簡介
Laravel 讓開發者與多種資料庫的互動變得非常簡單,主要是利用 查詢語句構造器 和 Eloquent ORM 幫您產生與業務邏輯對應的原生 SQL 語句,避免了開發者手動書寫 SQL 語句帶來的煩惱。現支援的資料庫如下:
- MySQL
- Postgres
- SQLite
- SQL Server
配置
資料庫配置檔案是 config/database.php
。你可以根據實際情況,修改或新增你的資料庫資訊,指定預設使用的資料庫連線(database connections)。
配置 SQLite
配置 SQLite 需要先建立一個資料庫,使用 touch database/database.sqlite
建立,然後再配置你的環境變數——使用絕對路徑指向這個新建立的資料庫。
DB_CONNECTION=sqlite
DB_DATABASE=/absolute/path/to/database.sqlite
配置 SQL Server
Laravel 在配置檔案 config/database.php
中,已經為您預設了 SQL Server 的連線資訊,只需要按照實際情況修改即可:
'sqlsrv' => [
'driver' => 'sqlsrv',
'host' => env('DB_HOST', 'localhost'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8',
'prefix' => '',
],
讀 & 寫連線
有時,您希望專案使用兩種資料庫——一種負責讀,也就是用來執行 select
語句;另一種負責寫,用來執行 insert
、update
和 delete
語句。Laravel 使之變得輕而易舉,無論您是使用原生查詢、查詢語句構造器還是Eloquent ORM,都會始終使用正確的連線。
具體讀 & 寫連線的配置方式,看下面的例子可知:
'mysql' => [
'read' => [
'host' => '192.168.1.1',
],
'write' => [
'host' => '196.168.1.2'
],
'driver' => 'mysql',
'database' => 'database',
'username' => 'root',
'password' => '',
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
],
我們為配置資訊新增了兩個鍵:read
和 write
。兩個鍵裡又包含 host
鍵。在 mysql
中,其餘的配置資訊是讀 & 寫連線共用的配置資訊。
在上面例子裡,192.168.1.1
這臺主機用來「讀」, 196.168.1.2
這臺主機用來「寫」。而其餘像使用者名稱、密碼、資料庫編碼等都是兩個連線共用的配置。
使用多資料庫連線
DB
門面提供了 connection
方法,用來獲得某個連線。用它就可以實現使用多資料庫連線的需求。給 connection
傳遞是一個「連線名」,這個連線名必然是要在 config/database.php
裡配置的。
$users = DB::connection('foo')->select(...);
您可以用連線例項的 getPdo
方法獲得底層 PDO
例項。
$pdo = DB::connection()->getPdo();
執行原生 SQL 查詢
使用 DB
門面可以完成每種型別的查詢:select
、update
、insert
、delete
和 statement
。
執行 select
查詢
使用 DB
門面的 select
方法可執行查詢:
<?php
namespace App\Http\Controllers;
use Illuminate\Support\Facades\DB;
use App\Http\Controllers\Controller;
class UserController extends Controller
{
/**
* Show a list of all of the application's users.
*
* @return Response
*/
public function index()
{
$users = DB::select('select * from users where active = ?', [1]);
return view('user.index', ['users' => $users]);
}
}
select
方法的第一個引數就是原生的 SQL 語句,第二個引數是繫結到語句的引數。繫結的引數通常是 where
子句約束條件,這可保護程式免受 SQL 注入危害。
select
方法返回一個結果陣列,每個陣列成員都是一個 PHP StdClass
物件:
foreach ($users as $user) {
echo $user->name;
}
使用命名引數
你可以選擇使用命名引數的形式代替 ?
佔位符:
$results = DB::select('select * from users where id = :id', ['id' => 1]);
執行 insert
語句
使用 DB
門面的 insert
方法插入資料。形如 select
方法,DB:insert
的第一個引數是原生 SQL 語句,第二個引數是繫結引數:
DB::insert('insert into users (id, name) values (?, ?)', [1, 'Dayle']);
執行 update
語句
update
方法用來更新資料庫中已存在的記錄,返回的結果是更新的記錄數目。
$affected = DB::update('update users set votes = 100 where name = ?', ['John']);
執行 delete
語句
update
方法用來從資料庫中刪除記錄,類似 update
方法,返回的結果是刪除的記錄數目。
執行一般語句
「一般語句」指沒有返回結果的 SQL 語句。對於這類操作,可以使用 DB
門面上的 statement
方法。
DB::statement('drop table users');
監聽查詢事件
如果你要查閱 Laravel 底層執行的 SQL 語句,可以使用 listen
方法,這個方法會在程式執行 SQL 語句時呼叫。這對 debug 程式和記錄 SQL 語句非常有用。你可以在服務提供者 AppServiceProvider
中註冊、監聽查詢事件。
<?php
namespace App\Providers;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
DB::listen(function ($query) {
// $query->sql
// $query->bindings
// $query->time
});
}
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
//
}
}
資料庫事務
你可以用 DB
門面的 transaction
方法在一個事務裡執行一系列操作。如果事務閉包裡丟擲異常,那麼事務就會自動回滾。如果閉包執行成功,那麼事務就會自動提交。使用 transaction
方法就無需手動回滾或者提交事務了:
DB::transaction(function () {
DB::table('users')->update(['votes' => 1]);
DB::table('posts')->delete();
});
解決死鎖
transaction
方法還要第二個引數可供指定——當死鎖發生時,事務最大的嘗試次數。一旦超過這個指定次數,就會丟擲異常:
DB::transaction(function () {
DB::table('users')->update(['votes' => 1]);
DB::table('posts')->delete();
}, 5);
手動使用事務
如果你要完全手動控制事務的回滾和提交,就要用 BD
門面的 beginTransaction
方法了:
DB::beginTransaction();
使用 rollBack
方法回滾事務:
DB::rollBack();
最後,使用 commit
方法提交事務:
DB::commit();