快速入門
快速入門
數(shù)據(jù)庫:入門
簡介
Laravel 能使用原生 SQL、流暢的查詢構(gòu)造器 和 Eloquent ORM 在各種數(shù)據(jù)庫后臺與數(shù)據(jù)庫進(jìn)行非常簡單的交互。當(dāng)前 Laravel 支持四種數(shù)據(jù)庫:
- MySQL
- PostgreSQL
- SQLite
- SQL Server
配置
數(shù)據(jù)庫的配置文件放置在 config/database.php
文件中,你可以在此定義所有的數(shù)據(jù)庫連接,并指定默認(rèn)使用的連接。此文件內(nèi)提供了大部分 Laravel 能支持的數(shù)據(jù)庫配置示例。
默認(rèn)情況下,Laravel 的示例 環(huán)境配置 使用了 Laravel Homestead(這是一種小型虛擬機(jī),能讓你很方便地在本地進(jìn)行 Laravel 的開發(fā))。你可以根據(jù)本地數(shù)據(jù)庫的需要修改這個配置。
SQLite 配置
使用類似 touch database/database.sqlite
之類命令創(chuàng)建一個新的 SQLite 數(shù)據(jù)庫之后,可以使用數(shù)據(jù)庫的絕對路徑配置環(huán)境變量來指向這個新創(chuàng)建的數(shù)據(jù)庫:
DB_CONNECTION=sqliteDB_DATABASE=/absolute/path/to/database.sqlite
如果要開啟 SQLite 連接的外鍵約束,您應(yīng)該將 foreign_key_constraints
添加到 config / database.php
配置文件中:
'sqlite' => [ // ... 'foreign_key_constraints' => true, ],
讀寫分離
有時候你希望 SELECT 語句使用一個數(shù)據(jù)庫連接,而 INSERT,UPDATE,和 DELETE 語句使用另一個數(shù)據(jù)庫連接。在 Laravel 中,無論你是使用原生查詢,查詢構(gòu)造器,或者是 Eloquent ORM,都能輕松的實現(xiàn)
為了弄明白讀寫分離是如何配置的,我們先來看個例子:
'mysql' => [ 'read' => [ 'host' => ['192.168.1.1'], ], 'write' => [ 'host' => ['196.168.1.2'], ], 'sticky' => true, 'driver' => 'mysql', 'database' => 'database', 'username' => 'root', 'password' => '', 'charset' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci', 'prefix' => '', ],
注意在以上的例子中,配置數(shù)組中增加了三個鍵,分別是 read
, write
和 sticky
。 read
和 write
的鍵都包含一個鍵為 host
的數(shù)組。而 read
和 write
的其他數(shù)據(jù)庫都在鍵為 mysql
的數(shù)組中。
如果你想重寫主數(shù)組中的配置,只需要修改 read
和 write
數(shù)組即可。所以,這個例子中: 192.168.1.1
將作為 「讀」 連接主機(jī),而 192.168.1.2
將作為 「寫」 連接主機(jī)。這兩個連接會共享 mysql
數(shù)組的各項配置,如數(shù)據(jù)庫的憑據(jù)(用戶名 / 密碼),前綴,字符編碼等。
sticky
選項
sticky
是一個 可選值,它可用于立即讀取在當(dāng)前請求周期內(nèi)已寫入數(shù)據(jù)庫的記錄。若 sticky
選項被啟用,并且當(dāng)前請求周期內(nèi)執(zhí)行過 「寫」 操作,那么任何 「讀」 操作都將使用 「寫」 連接。這樣可確保同一個請求周期內(nèi)寫入的數(shù)據(jù)可以被立即讀取到,從而避免主從延遲導(dǎo)致數(shù)據(jù)不一致的問題。不過是否啟用它,取決于應(yīng)用程序的需求。
使用多個數(shù)據(jù)庫連接
當(dāng)使用多個數(shù)據(jù)庫連接時,你可以通過 DB
Facade 的 connection
方法訪問每一個連接。傳遞給 connection
方法的參數(shù) name
應(yīng)該是 config/database.php
配置文件中 connections 數(shù)組中的一個值:
$users = DB::connection('foo')->select(...);
你也可以使用一個連接實例上的 getPdo
方法訪問底層的 PDO 實例:
$pdo = DB::connection()->getPdo();
運行原生 SQL 查詢
一旦配置好數(shù)據(jù)庫連接后,便可以使用 DB
facade 運行查詢。 DB
facade 為每種類型的查詢提供了方法: select
,update
,insert
,delete
和 statement
。
運行 Select 查詢
你可以使用 DB
Facade 的 select
方法來運行基礎(chǔ)的查詢語句:
<?php namespace App\Http\Controllers; use Illuminate\Support\Facades\DB; use App\Http\Controllers\Controller; class UserController extends Controller{ /** * 顯示應(yīng)用程序中所有用戶的列表 * * @return Response */ public function index() { $users = DB::select('select * from users where active = ?', [1]); return view('user.index', ['users' => $users]); } }
傳遞給 select
方法的第一個參數(shù)就是一個原生的 SQL 查詢,而第二個參數(shù)則是需要綁定到查詢中的參數(shù)值。通常,這些值用于約束 where
語句。參數(shù)綁定用于防止 SQL 注入。
select
方法將始終返回一個數(shù)組,數(shù)組中的每個結(jié)果都是一個 = StdClass
對象,可以像下面這樣訪問結(jié)果值:
foreach ($users as $user) { echo $user->name; }
使用命名綁定
除了使用 ?
表示參數(shù)綁定外,你也可以使用命名綁定來執(zhí)行一個查詢:
$results = DB::select('select * from users where id = :id', ['id' => 1]);
運行插入語句
可以使用 DB
Facade 的 insert
方法來執(zhí)行 insert
語句。與 select
一樣,該方法將原生 SQL 查詢作為其第一個參數(shù),并將綁定數(shù)據(jù)作為第二個參數(shù):
DB::insert('insert into users (id, name) values (?, ?)', [1, 'Dayle']);
運行更新語句
update
方法用于更新數(shù)據(jù)庫中現(xiàn)有的記錄。該方法返回受該語句影響的行數(shù):
$affected = DB::update('update users set votes = 100 where name = ?', ['John']);
運行刪除語句
delete
方法用于從數(shù)據(jù)庫中刪除記錄。與 update
一樣,返回受該語句影響的行數(shù):
$deleted = DB::delete('delete from users');
運行普通語句
有些數(shù)據(jù)庫語句不會有任何返回值。對于這些語句,你可以使用 DB
Facade 的 statement
方法來運行:
DB::statement('drop table users');
監(jiān)聽查詢事件
如果你想監(jiān)控程序執(zhí)行的每一個 SQL 查詢,你可以使用 listen
方法。這個方法對于記錄查詢或調(diào)試非常有用。你可以在 服務(wù)提供器 中注冊你的查詢監(jiān)聽器:
<?php namespace App\Providers; use Illuminate\Support\Facades\DB; use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider{ /** * 啟動應(yīng)用服務(wù) * * @return void */ public function boot() { DB::listen(function ($query) { // $query->sql // $query->bindings // $query->time }); } /** * 注冊服務(wù)提供器 * * @return void */ public function register() { // } }
數(shù)據(jù)庫事務(wù)
你可以使用 DB
facade 的 transaction
方法在數(shù)據(jù)庫事務(wù)中運行一組操作。如果事務(wù)的閉包 Closure
中出現(xiàn)一個異常,事務(wù)將會回滾。如果事務(wù)閉包 Closure
執(zhí)行成功,事務(wù)將自動提交。一旦你使用了 transaction
, 就不再需要擔(dān)心手動回滾或提交的問題:
DB::transaction(function () { DB::table('users')->update(['votes' => 1]); DB::table('posts')->delete(); });
處理死鎖
transaction
方法接受一個可選的第二個參數(shù) ,該參數(shù)用來表示事務(wù)發(fā)生死鎖時重復(fù)執(zhí)行的次數(shù)。一旦定義的次數(shù)嘗試完畢,就會拋出一個異常:
DB::transaction(function () { DB::table('users')->update(['votes' => 1]); DB::table('posts')->delete(); }, 5);
手動使用事務(wù)
如果你想要手動開始一個事務(wù),并且對回滾和提交能夠完全控制,那么你可以使用 DB
Facade 的 beginTransaction
方法:
DB::beginTransaction();
你可以使用 rollBack
方法回滾事務(wù):
DB::rollBack();
最后,你可以使用 commit
方法提交事務(wù):
DB::commit();
{tip}
DB
facade 的事務(wù)方法同樣適用于 查詢構(gòu)造器 和 Eloquent ORM.