Illuminate database是一個非常強大非常優秀的ORM類庫,也是一個非常實用的數據庫操作組件。使用它可以輕松對數據庫進行查詢、插入、更新、刪除等操作,支持MySQL,Postgres,SQL Server,SQLlite等。它還是Laravel框架的數據庫組件。
本文單獨將illuminate database拿出來,脫離框架,主要講講使用illuminate database查詢構造器進行數據庫操作。
安裝
使用 composer 安裝,直接在項目根目錄的命令行里,執行
composer require illuminate/database
建議PHP版本使用PHP^7.2。
建立配置
創建一個Capsule管理實例來配置數據庫連接參數。
<?php $capsule = new \Illuminate\Database\Capsule\Manager; // 創建鏈接 $capsule->addConnection([ 'driver' => 'mysql', 'host' => 'localhost', 'database' => 'demo', 'username' => 'root', 'password' => '', 'charset' => 'utf8mb4', 'port' => 3306, 'collation' => 'utf8mb4_general_ci', 'prefix' => 'web_', ]); // 設置全局靜態可訪問DB $capsule->setAsGlobal(); // 啟動Eloquent (如果只使用查詢構造器,這個可以注釋) $capsule->bootEloquent();
將配置文件保存為database.php。再新建文件index.php,代碼如下:
<?php date_default_timezone_set("PRC"); require 'vendor/autoload.php'; require 'database.php'; use Illuminate\Database\Capsule\Manager as DB;
自行准備好數據庫表,現在,可以直接在index.php后面寫數據庫操作語句了。
獲取結果集
從一張表中獲取一行/一列
如果我們只是想要從數據表中獲取一行數據,可以使用first
方法,該方法將會返回單個StdClass
對象:
$article = DB::table('article')->where('author', '月光光')->first(); echo $article->title;
如果我們不需要完整的一行,可以使用value
方法從結果中獲取單個值,該方法會直接返回指定列的值:
$title = DB::table('article')->where('author', '月光光')->value('title');
獲取數據列值列表
如果只要查詢表中的某一列值,可使用pluck
方法。
$titles = DB::table('article')->where('author', '月光光')->pluck('title'); foreach ($titles as $title) { echo $title; }
如果要獲取一個表中的其中幾個字段列的結果,可以使用select
和get
方法。
$list = DB::table('article')->select('id', 'title')->get(); $list = DB::table('article')->get(['id', 'title']);
兩條語句返回的結果是一樣的。要獲取結果,需要遍歷$list:
foreach ($list as $key => $val) { echo $val->id; echo $val->title; }
強制不重復
distinct
方法允許你強制查詢返回不重復的結果集
$list = DB::table('article')->distinct()->get();
Where查詢
簡單 Where 子句
使用查詢構建器上的where
方法可以添加where
子句到查詢中,調用where
最基本的方式需要傳遞三個參數,第一個參數是列名,第二個參數是任意一個數據庫系統支持的操作符,第三個參數是該列要比較的值。
如,查詢id值為100的記錄。
$row = DB::table('article')->where('id', '=', '100')->get();
當要查詢的列值和給定數組相等時,可以將等號省略。上面的語句可以這樣寫:
DB::table('article')->where('id', '100')->get();
除了等號,還有>=
,<=
,<>
,like
DB::table('article')->where('title', 'like', 'php%')->get();
Where數組
還可以傳遞條件數組到where
函數:
$list = DB::table('article')->where([ ['id', '>', '100'], ['source', '=', 'helloweba.com'] ])->get();
or 語句
我們可以通過方法鏈將多個where
約束鏈接到一起,也可以添加 or 子句到查詢,orWhere
方法和 where
方法接收參數一樣:
$list = DB::table('article') ->where('source', 'helloweba.com') ->orWhere('hits', '<', '1000') ->get(['id', 'title', 'hits']);
whereIn語句
whereIn
方法驗證給定列的值是否在給定數組中。whereNotIn
方法驗證給定列的值不在給定數組中。
$list = DB::table('article')->whereIn('id', [10,100,200])->get(['id', 'title']);
whereBeteen語句
whereBetween
方法驗證列值是否在給定值之間,whereNotBetween
方法驗證列值不在給定值之間。
$list = DB::table('article') ->whereBetween('hits', [1, 1000])->get(['id', 'title', 'hits']);
whereNull語句
whereNull
方法驗證給定列的值為NULL
,whereNotNull
方法驗證給定列的值不是 NULL
。
$list = DB::table('article') ->whereNull('updated_at') ->get();
whereDate語句
如果我們要查詢創建日期在2019-08-29的文章記錄,可以使用whereDate
。
$list = DB::table('article')->whereDate('created_at', '2019-08-29')->get(['id', 'title', 'created_at']);
whereMonth語句
如果我們要查詢創建月份在10月份的所有文章記錄,可以使用whereMonth
。
$list = DB::table('article')->whereMonth('created_at', '10')->get(['id', 'title', 'created_at']);
whereDay語句
如果要查詢創建日期在1號的所有文章,可以使用whereDay
。
$list = DB::table('article')->whereDay('created_at', '1')->get(['id', 'title', 'created_at']);
whereYear語句
如果要查詢創建年份是2016年的所有文章,可以使用whereYear
。
$list = DB::table('article')->whereYear('created_at', '2016')->get(['id', 'title', 'created_at']);
whereTime語句
如果要查詢創建時間在10:20的所有文章,可以使用whereTime
。
$list = DB::table('article')->whereTime('created_at', '10:20')->get(['id', 'title', 'created_at']);
whereColumn語句
如果要查詢文章表中創建時間和更新時間相等的所有文章,可以使用whereColumn
。
$list = DB::table('article')->whereColumn('created_at', '=', 'updated_at')->get(['id', 'title', 'created_at']);
聚合查詢
查詢構建器還提供了多個聚合方法,如總記錄數: count
, 最大值: max
, 最小值:min
,平均數:avg
和總和: sum
,我們可以在構造查詢之后調用這些方法。
$count = DB::table('article')->count(); //總記錄數 $max = DB::table('article')->max('hits'); //點擊量最大
判斷記錄是否存在
除了通過 count 方法來判斷匹配查詢條件的結果是否存在外,還可以使用exists
或doesntExist
方法:
$exists = DB::table('article')->where('author', '月光光')->exists();
返回的是true和false。
排序、分組與限定
orderBy
我們要對查詢的記錄進行順序asc
和倒序desc
排序,可以使用orderBy
。
$list = DB::table('article')->orderBy('id', 'desc')->get(['id', 'title']);
latest / oldest
我們可以使用latest
和oldest
對日期字段created_at
。
$list = DB::table('article')->latest()->first();
inRandomOrder
如果我們要從文章表中隨機排序,查詢一條隨機記錄,可以使用inRandomOrder
。
$list = DB::table('article')->inRandomOrder()->first();
groupBy / having
如果要對結果集進行分組,可以使用groupBy
方法和having
方法。
DB::table('article')->groupBy('cate')-having('id', '>', 100)->get();
skip / take
如果要對結果集進行跳過給定的數目結果,可以使用skip
和take
方法,該方法常用於數據分頁。
$list = DB::table('article')->skip(10)->take(5)->get(['id', 'title']);
以上語句等價於:
$list = DB::table('article')->offset(10)->limit(5)->get(['id', 'title']);
連接Join
查詢構建器還可以用於編寫join連接語句,常見的幾種連接類型有:join
、leftJoin
、rightJoin
等。
$list = DB::table('mark') ->join('user', 'mark.user_id', '=', 'user.id') ->join('article', 'mark.article_id', '=', 'article.id') ->get(['article.id','article.title','user.username','user.nickname']);
插入數據
查詢構建器還提供了insert
方法用於插入記錄到數據表。insert
方法接收數組形式的字段名和字段值進行插入操作
DB::table('article')->insert( ['title' => 'PDO操作數據庫', 'author' => '月光光'] );
支持批量插入:
DB::table('article')->insert( ['title' => 'PDO操作數據庫', 'author' => '月光光'], ['title' => 'PDO那些事', 'author' => '想吃魚的貓'], );
自增ID
使用insertGetId
方法來插入記錄並返回ID值,如果表中的id為自增長ID,則返回的即為自增ID。
$id = DB::table('article')->insertGetId( ['title' => 'PDO操作數據庫', 'author' => '月光光'], );
更新數據
使用update
方法可以更新對應的字段。
DB::table('article')->where('id', 1)->update('author', '月光光');
增減數字
我們可以使用increment
和decrement
方法增減某個列值,比如增加點擊量。
DB::table('article')->increment('hits'); //點擊量+1 DB::table('article')->increment('hits', 5); //點擊量+5 DB::table('article')->decrement('hits'); //點擊量-1 DB::table('article')->decrement('hits', 5); //點擊量-5
刪除數據
使用delete
方法可以從表中刪除記錄。
DB::table('article')->where('id', 10)->delete();
如果我們要清空一張表,將自增長id歸0,可以使用truncate
方法。
DB::table('article')->truncate();
打印sql日志
有時我們需要調試sql語句,查看最后一次執行的原生的sql語句,可以使用以下方法:
DB::connection()->enableQueryLog();
$list = DB::table('article')->skip(10)->take(5)->get(['id', 'title']); print_r(DB::getQueryLog());
2019-11-17補充:
事務
想要在一個數據庫事務中運行一連串操作,可以使用 DB 門面的transaction
方法,使用transaction
方法時不需要手動回滾或提交:如果事務閉包中拋出異常,事務將會自動回滾;如果閉包執行成功,事務將會自動提交:
DB::transaction(function () { DB::table('users')->update(['votes' => 1]); DB::table('posts')->delete(); });
當然我們也可以使用手動控制事務,從而對回滾和提交有更好的控制,可以使用 DB 門面的 beginTransaction
方法:
DB::beginTransaction();
可以通過rollBack
方法回滾事務:
DB::rollBack();
最后,我們可以通過commit
方法提交事務:
DB::commit();
小結
Illuminate database提供的查詢構造器可以輕松實現對數據庫的操作,能滿足我們日常開發需求,當然,在框架中使用的時候更多的使用ORM進行數據操作,后面我們會有文章介紹Illuminate database的ORM功能,徹底擺脫sql語句的束縛。