* * * * *
[TOC]
## 簡介
Laravel 對主流數據庫系統連接和查詢都提供了很好的支持,尤其是流暢的?[查詢語句構造器](https://laravel-china.org/docs/laravel/5.4/queries)?, Laravel 支持四種類型的數據庫:
* MySQL
* Postgres
* SQLite
* SQL Server
### 配置信息
Laravel 應用程序的數據庫配置文件放置在?`config/database.php`?文件中。在這個配置文件內你可以定義所有的數據庫連接,以及指定默認使用哪個連接。在此文件內提供了所有支持的數據庫系統示例。
默認情況下,Laravel 的?[環境配置](https://laravel-china.org/docs/laravel/5.4/installation#environment-configuration)?示例會使用?[Laravel Homestead](https://laravel-china.org/docs/laravel/5.4/homestead),對于 Laravel 開發來說這是一個相當便利的本地虛擬機。當然你也可以根據需求來隨時修改本機端的數據庫設置。
#### SQLite 配置
請使用?`touch database/database.sqlite`?命令創建一個 SQLite 文件, 您可以通過使用數據庫的絕對路徑來輕松地配置您的環境變量來指向這個新創建的數據庫:
~~~
DB_CONNECTION=sqlite
DB_DATABASE=/absolute/path/to/database.sqlite
~~~
#### SQL Server 配置
Laravel 支持 SQL Server 數據庫,你需要在?`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' => '',
],
~~~
### 數據庫讀寫分離
有時候你希望把一個數據庫作為只讀數據庫,而另一個數據庫則負責寫入、更新以及刪除。Laravel 會讓你輕而易舉的實現,并適用于原始查找、查詢語句構造器或是 Eloquent ORM。
通過下面這個例子,我們來學習如何配置數據庫讀寫連接的分離:
~~~
'mysql' => [
'read' => [
'host' => '192.168.1.1',
],
'write' => [
'host' => '196.168.1.2'
],
'driver' => 'mysql',
'database' => 'database',
'username' => 'root',
'password' => '',
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
],
~~~
注意,有兩個鍵加入了這個配置文件數組內:?`read`?和?`write`?。 它們兩個都是一個數組且只包含了一個鍵:?`host`?。 而?`read`?和?`write`?連接的其他配置都包含在?`mysql`?數組中。
所以,如果需要在主要的數組內重寫值,只需在?`read`?and?`write`?數組內放置設置參數即可。在這個例子中,?`192.168.1.1`?將會只提供數據讀取數據的功能,而?`192.168.1.2`?提供數據庫寫入。數據庫的憑證、前綴、編碼設置,以及所有其它的選項都被存放在?`mysql`?數組內,這兩個連接將會共用這些選項。
### 使用多數據庫連接
當使用多個數據連接時,你可以使用?`DB`?facade 的?`connection`?方法。在?`config/database.php`?中定義好的數據庫連接?`name`?作為?`connection`?的參數進行傳遞。
~~~
$users = DB::connection('foo')->select(...);
~~~
你也可以在連接的實例中使用?`getPdo`?方法訪問原始的底層 PDO 實例:
~~~
$pdo = DB::connection()->getPdo();
~~~
## 運行原生 SQL 語句
配置好數據庫連接以后,你可以使用?`DB`?facade 來執行查詢。?`DB`?facade 提供了?`select`?、?`update`?、?`insert`?、?`delete`?和?`statement`?的查詢方法。
#### 運行 Select
運行一個基礎的查詢語句,你可以使用?`DB`?facade 的?`select`?方法:
~~~
<?php
namespace App\Http\Controllers;
use Illuminate\Support\Facades\DB;
use App\Http\Controllers\Controller;
class UserController extends Controller
{
/**
* 在應用用戶中查詢出已激活的用戶列表。
*
* @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
運行?`Insert`?語句,你可以是使用?`DB`?facade 的?`insert`?方法 。 像?`select`?一樣, 該方法將原生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
`delete`?方法用于刪除已經存在于數據庫的記錄。如同?`update`?一樣,刪除的行數將會被返回。
~~~
$deleted = DB::delete('delete from users');
~~~
#### 運行一般聲明
有些數據庫沒有返回值, 對于這種類型的操作,可以使用?`DB`?facade 的?`statement`?方法。
~~~
DB::statement('drop table users');
~~~
### 監聽查詢事件
如果你希望能夠監控到程序執行的每一條 SQL 語句,那么你可以使用?`listen`?方法。 該方法對查詢日志和調試非常有用,你可以在?[服務容器](https://laravel-china.org/docs/laravel/5.4/providers)?中注冊該方法:
~~~
<?php
namespace App\Providers;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* 啟動應用服務。
*
* @return void
*/
public function boot()
{
DB::listen(function ($query) {
// $query->sql
// $query->bindings
// $query->time
});
}
/**
* 注冊服務提供者。
*
* @return void
*/
public function register()
{
//
}
}
~~~
## 數據庫事務
想要在一個數據庫事務中運行一連串操作,可以使用?`DB`?facade 的?`transaction`?方法。如果在事務的?`Closure`中拋出了異常,那么事務會自動的執行回滾操作。如果?`Closure`?成功的執行,那么事務就會自動的進行提交操作。你不需要在使用?`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);
~~~
#### 手動操作事務
如果你想要手動開始一個事務的回滾和提交操作,你可以使用?`DB`?facade 的?`beginTransaction`?方法。
~~~
DB::beginTransaction();
~~~
你也可以通過?`rollBack`?方法來回滾事務:
~~~
DB::rollBack();
~~~
最后,可以通過?`commit`?方法來提交這個事務:
~~~
DB::commit();
~~~
> {tip} 使用?`DB`?facade 的事務方法也適用于?[查詢語句構造器](https://laravel-china.org/docs/laravel/5.4/queries)?和?[Eloquent ORM](https://laravel-china.org/docs/laravel/5.4/eloquent)?。
- 前言
- 翻譯說明
- 發行說明
- 升級說明
- 貢獻導引
- 入門指南
- 安裝
- 配置信息
- 文件夾結構
- 請求周期
- 開發環境部署
- Homestead
- Valet
- 核心概念
- 服務容器
- 服務提供者
- Facades
- Contracts
- HTTP層
- 路由
- 中間件
- CSRF 保護
- 控制器
- 請求
- 響應
- 視圖
- Session
- 表單驗證
- 前端
- Blade 模板
- 本地化
- 前端指南
- 編輯資源 Mix
- 安全
- 用戶認證
- Passport OAuth 認證
- 用戶授權
- 加密解密
- 哈希
- 重置密碼
- 綜合話題
- Artisan 命令行
- 廣播系統
- 緩存系統
- 集合
- 錯誤與日志
- 事件系統
- 文件存儲
- 輔助函數
- 郵件發送
- 消息通知
- 擴展包開發
- 隊列
- 任務調度
- 數據庫
- 快速入門
- 查詢構造器
- 分頁
- 數據庫遷移
- 數據填充
- Redis
- Eloquent ORM
- 快速入門
- 模型關聯
- Eloquent 集合
- 修改器
- 序列化
- 測試
- 快速入門
- HTTP 測試
- 瀏覽器測試 Dusk
- 數據庫測試
- 測試模擬器
- 官方擴展包
- Cashier 交易工具包
- Envoy 部署工具
- Scout 全文搜索
- Socialite 社會化登錄