快速入門


設定

#讀& 寫連接
  • 使用多個資料庫連線
    • 執行原生的SQL 查詢
    • ##監聽查詢事件
  • 資料庫事務
    #

    簡介

    Laravel 能使用原生 SQL、流暢的查詢建構器 和 Eloquent ORM 在各種資料庫後台與資料庫進行非常簡單的互動。目前Laravel 支援四種資料庫:

    • MySQL
    • PostgreSQL
    • SQLite
    • SQL Server

    ##設定資料庫的設定檔放置在

    config/database.php
    檔案中,你可以在此定義所有的資料庫連接,並指定預設使用的連接。此文件內提供了大部分 Laravel 能支援的資料庫設定範例。

    預設情況下,Laravel  的範例 環境配置 使用了 Laravel Homestead(這是一種小型虛擬機,能讓你很方便地在本地進行 Laravel 的開發)。你可以根據本地資料庫的需要修改這個配置。

    SQLite 設定

    使用類似touch database/database.sqlite 之類指令建立一個新的SQLite 資料庫之後,可以使用資料庫的絕對路徑配置環境變數來指向這個新建立的資料庫:

    DB_CONNECTION=sqliteDB_DATABASE=/absolute/path/to/database.sqlite
    如果要開啟SQLite 連線的外鍵約束,您應該將foreign_key_constraints 新增到 config / database.php 設定檔中:
    'sqlite' => [   
     // ...    
     'foreign_key_constraints' => true,
     ],
    #已讀寫分離有時候你希望SELECT 語句使用一個資料庫連接,而INSERT,UPDATE,和DELETE 語句使用另一個資料庫連線。在Laravel 中,無論你是使用原生查詢,查詢建構器,或是Eloquent ORM,都能輕鬆的實作

    為了弄清楚讀寫分離是如何設定的,我們先來看個例子:

    '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'    => '',
      ],
    注意在以上的例子中,配置數組中增加了三個鍵,分別是readwritestickyread

    write
    的鍵都包含一個鍵為
    host### 的陣列。而 ###read### 和 ###write### 的其他資料庫都在鍵為 ###mysql### 的陣列中。 ######如果你想重寫主數組中的配置,只需要修改 ###read### 和 ###write### 陣列即可。所以,在這個範例中:  ###192.168.1.1### 將會以「讀取」 連結主機,而 ###192.168.1.2### 將會以「寫」連結主機。這兩個連線會共用 ###mysql### 陣列的各項配置,如資料庫的憑證(使用者名稱 / 密碼),前綴,字元編碼等。 ##########

    sticky 選項

    sticky 是一個可選值,它可用於立即讀取在目前請求週期內已寫入資料庫的記錄。若 sticky 選項已啟用,且目前請求週期內執行過 “寫入” 操作,那麼任何 “讀取” 操作都會使用 “寫入” 連接。這樣可確保同一個請求週期內寫入的資料可以立即讀取到,從而避免主從延遲導致資料不一致的問題。不過是否啟用它,取決於應用程式的需求。

    使用多個資料庫連線

    當使用多個資料庫連線時,你可以透過DB Facade 的connection 方法存取每一個連線。傳遞給connection 方法的參數name 應該是config/database.php 設定檔中connections 陣列中的一個值:

    $users = DB::connection('foo')->select(...);

    你也可以使用一個連線實例上的getPdo 方法存取底層的PDO 實例:

    $pdo = DB::connection()->getPdo();

    ##執行原生SQL查詢

    一旦配置好資料庫連線後,便可以使用

    DB facade 執行查詢。 DB facade 為每種類型的查詢提供了方法: selectupdateinsertdeletestatement

    執行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 方法將始終傳回數組,數組中的每個結果都是一個= StdClass 對象,可以像下面這樣存取結果值:

    foreach ($users as $user) { 
       echo $user->name;
     }

    使用命名綁定

    除了使用

    ? 表示參數綁定外,你也可以使用命名綁定來執行一個查詢:

    $results = DB::select('select * from users where id = :id', ['id' => 1]);

    執行插入語句

    可以使用

    DB Facade 的insert 方法來執行insert 語句。與select 一樣,該方法將原生SQL 查詢作為其第一個參數,並將綁定資料作為第二個參數:

    DB::insert('insert into users (id, name) values (?, ?)', [1, 'Dayle']);

    執行更新語句

    update 方法用於更新資料庫中現有的記錄。此方法傳回受該語句影響的行數:

    $affected = DB::update('update users set votes = 100 where name = ?', ['John']);

    #

    執行刪除語句

    delete 方法用於從資料庫中刪除記錄。與update 一樣,傳回受該語句影響的行數:

    $deleted = DB::delete('delete from users');

    執行普通語句

    有些資料庫語句不會有任何回傳值。對於這些語句,你可以使用DB Facade 的statement 方法來執行:

    DB::statement('drop table users');

    ##監聽查詢事件

    如果你想要監控程式執行的每一個SQL 查詢,你可以使用

    listen 方法。這個方法對於記錄查詢或調試非常有用。你可以在服務提供器中註冊你的查詢監聽器:

    <?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 的事務方法同樣適用於查詢構造器和Eloquent ORM.
    本篇首發在LearnKu.com
    網站上。
    ###