ThinkPHP5中,很多查詢都用到了閉包函數構造查詢器。
按照官方手冊中,對閉包作用的描述:數組方式和閉包方式的數據查詢的區別在於,數組方式只能定義查詢條件,閉包方式可以支持更多的連貫。
這句話,基本上說出了在查詢中,使用閉包的環境和方法。
下面我們最常用的get()和find()方法爲例,詳細介紹一下閉包查詢使用技巧。
準備工作:
我們操作的數據表模型是:staff(員工信息表),primary key 是 id
staff(id as 編號,name as 姓名,salary as 工資, dept as 部門);
一、get()方法
1、get()方法是模型類中定義一個方法,用於單條數據對象的輸出。
2、實例:
(A)查詢編號爲1005的員工信息;dump(Staff::get(1005));
分析以上代碼,get()參數爲條件,如果是主鍵可以直接寫,如果不是主鍵呢?我們可以用數組來構造查詢器來實現。
下面用數組構造查詢器,將上面的代碼重新改寫:dump(Staff::get(['id'=>['=',1005]]));
經過測試,運行結果是完全一樣的。
3、如果僅僅是相等判斷,數組優勢並不明顯,如果是更多的判斷條件,數組優勢就非常明顯了。
(A)實例:查詢工資大於等於3000元的開發部員工信息。
我們這裡用的是get(),所以僅返回符合條件的第一條記錄dump(Staff::get(['salary'=>['>=',3000],'dept'=>['=','開發部']])->getData());
對應生成的SQL語句是:SELECT * FROM `tp5_staff` WHERE `salary` >= 3000 AND `dept` = '開發部' LIMIT 1
當然我們想查看全部的信息,只需把get()換成all()方法,然後將getData()方法放在一個循環中調用每一個對象進行原始數據調用顯示即可。
可能大家發現了,隨著查詢條件變得複雜,我們的數組表達式變得非常的冗長,難以理解,並且書寫困難,容易出現錯誤,排錯也變得困難。
這時,閉包就上場了。
我們在學習PHP編程時,知道閉包函數,其本質是一個用變量來調用的函數,也就是匿名函數。
在這裡,我們把所有的查詢條件,不管有多複雜,全部打包到一個閉包函數中。
現在我們用閉包,將上面的代碼改寫:
(因爲我們用get()方法演示,無法演示出分組、排序等查詢效果,僅以限制字段顯示進行演示,其它連貫操作思想是一樣的)//查詢條件用閉包函數
$data=Staff::get(function($query){//模型靜態可以調用數據庫類的方法
$query = Staff::field(['name'=>'姓名','dept'=>'部門'])
->where(['id'=>['=',1005]]);
})->getData(); //獲取原始數據
// 以二維數組方式輸出
dump($data);
二、find()方法
find()方法是數據庫類提供給我們的一個獲取單條記錄的方法,使用起來與get()非常類似
我們知道:模型是與數據表關聯的,實例化以後,就會與指定的數據表綁定。
數據庫則不同,必須手工指定數據表,最多可以省略前綴。
廢話不多講,直接上代碼://查詢條件用閉包函數
$data=Db::table('tp5_staff')->find(function($query){ $query = Db::table('tp5_staff')->field(['name'=>'姓名','dept'=>'部門']) ->where(['id'=>['=',1005]]); }); dump($data);
這裡說明一個,如果閉包函數中指定了數據表,上級調用是可以不指定的。
這裡僅僅是爲了代碼清晰和可讀性考慮。
經過測試,其運行結果與上面是完全一樣的。
總結
閉包查詢是一個非常有意思的查詢技巧,我們完全可以將非常複雜的查詢要求,用這種方式,構造的查詢器,非常清晰自然!
希望對正在學習查詢構造器的您有所提示,特別是對閉包查詢感到困惑的同學,希望多多練習,將上述代碼親自運行一遍!