1. 程式人生 > 程式設計 >tp5.1 框架資料庫高階查詢技巧例項總結

tp5.1 框架資料庫高階查詢技巧例項總結

本文例項講述了tp5.1 框架資料庫高階查詢技巧。分享給大家供大家參考,具體如下:

快捷查詢

快捷查詢方式是一種多欄位相同查詢條件的簡化寫法,可以進一步簡化查詢條件的寫法,在多個欄位之間用|分割表示OR查詢,用&分割表示AND查詢,可以實現下面的查詢,例如:

Db::table('think_user')
 ->where('name|title','like','thinkphp%')
 ->where('create_time&update_time','>',0)
 ->find();

生成的查詢SQL是:

SELECT * FROM 
 `think_user` 
WHERE ( 
 `name` LIKE 'thinkphp%' OR `title` LIKE 'thinkphp%' ) 
AND ( 
 `create_time` > 0 AND `update_time` > 0 ) 
LIMIT 1

快捷查詢支援所有的查詢表示式。

區間查詢

區間查詢是一種同一欄位多個查詢條件的簡化寫法,例如:

Db::table('think_user')
 ->where('name',['like','%thinkphp%'],'%kancloud%'],'or')
 ->where('id',['>',0],['<>',10],'and')
 ->find();

生成的SQL語句為:

SELECT * FROM 
 `think_user` 
WHERE ( 
 `name` LIKE '%thinkphp%' OR `name` LIKE '%kancloud%' ) 
AND ( 
 `id` > 0 AND `id` <> 10 )
LIMIT 1

區間查詢的查詢條件必須使用陣列定義方式,支援所有的查詢表示式。

下面的查詢方式是錯誤的:

Db::table('think_user')
 ->where('name','thinkphp%'],'%thinkphp'])
 ->where('id',5,'or')
 ->find();

區間查詢其實可以用下面的方式替代,更容易理解,因為查詢構造器支援對同一個欄位多次呼叫查詢條件,例如:

Db::table('think_user')
 ->where('name','%think%')
 ->where('name','%php%')
 ->where('id','in',[1,80,50])
 ->where('id',10)
 ->find();

批量(欄位)查詢

可以進行多個條件的批量條件查詢定義,例如:

Db::table('think_user')
 ->where([
 ['name',['title','%thinkphp'],['id',['status','=',1],])
 ->select();

生成的SQL語句為:

SELECT * FROM 
 `think_user` 
WHERE 
 `name` LIKE 'thinkphp%' 
AND 
 `title` LIKE '%thinkphp' 
AND 
 `id` > 0 
AND 
 `status` = '1'

注意,V5.1.7+版本陣列方式如果使用exp查詢的話,一定要用raw方法。

Db::table('think_user')
 ->where([
 ['name','exp',Db::raw('>score')],])
 ->select();

陣列查詢方式,確保你的查詢陣列不能被使用者提交資料控制,使用者提交的表單資料應該是作為查詢陣列的一個元素傳入,如下:

Db::table('think_user')
 ->where([
 ['name',$name . '%'],'%' . $title],$id],$status],])
 ->select();

注意,相同的欄位的多次查詢條件可能會合並,如果希望某一個where方法裡面的條件單獨處理,可以使用下面的方式,避免被其它條件影響。

$map = [
 ['name',];
Db::table('think_user')
 ->where([ $map ])
 ->where('status',1)
 ->select();

生成的SQL語句為:

SELECT * FROM 
 `think_user` 
WHERE ( 
 `name` LIKE 'thinkphp%' 
AND 
 `title` LIKE '%thinkphp' 
AND 
 `id` > 0 ) 
AND 
 `status` = '1'

如果使用下面的多個條件組合

$map1 = [
 ['name',];
 
$map2 = [
 ['name','kancloud%'],'%kancloud'],]; 
 
Db::table('think_user')
 ->whereOr([ $map1,$map2 ])
 ->select();

生成的SQL語句為:

SELECT * FROM 
 `think_user` 
WHERE ( 
 `name` LIKE 'thinkphp%' 
AND 
 `title` LIKE '%thinkphp' ) 
OR ( 
 `name` LIKE 'kancloud%' 
AND 
 `title` LIKE '%kancloud' )

善用多維陣列查詢,可以很方便的拼裝出各種複雜的SQL語句

陣列物件查詢(V5.1.21+)

對於習慣或者重度依賴陣列查詢條件的使用者來說,可以選擇陣列物件查詢,該物件完成了普通陣列方式查詢和系統的查詢表示式之間的橋接,但相較於系統推薦的查詢表示式方式而言,需要注意變數的安全性,避免產生SQL注入的情況

使用方法如下:

use think\db\Where;
 
$map = [
 'name' => ['like','title' => ['like','%think%'],'id' => ['>','status' => 1,];
 
$where  = new Where;
$where['id'] = ['in',2,3]];
$where['title'] = ['like','%php%'];
 
Db::table('think_user')
 ->where(new Where($map))
 ->whereOr($where->enclose())
 ->select();

enclose方法表示該查詢條件兩邊會加上括號包起來。

使用陣列物件查詢的情況請一定要注意做好資料型別檢查,儘量避免讓使用者決定你的資料。

生成的SQL是:

SELECT * FROM 
 `think_user` 
WHERE 
 `name` LIKE 'thinkphp%' 
AND 
 `title` LIKE '%think%' 
AND 
 `id` > 10 
AND 
 `status` =1 
OR ( 
 `id` IN (1,3) 
AND 
 `title` LIKE '%php%' )

閉包查詢

$name = 'thinkphp';
$id = 10;
Db::table('think_user')->where(function ($query) use($name,$id) {
 $query->where('name',$name)
 ->whereOr('id',$id);
})->select();

生成的SQL語句為:

SELECT * FROM `think_user` WHERE ( `name` = 'thinkphp' OR `id` > 10 )

可見每個閉包條件兩邊也會自動加上括號,但需要注意,使用閉包查詢的時候不能使用cache(true)資料快取,而應該使用指定key的方式例如cache('key')

混合查詢

可以結合前面提到的所有方式進行混合查詢,例如:

Db::table('think_user')
 ->where('name','%thinkphp'])
 ->where(function ($query) {
 $query->where('id',['<',100],'or');
 })
 ->select();

生成的SQL語句是:

SELECT * FROM 
 `think_user` 
WHERE ( 
 `name` LIKE 'thinkphp%' 
AND 
 `name` LIKE '%thinkphp' ) 
AND ( 
 `id` < 10 or `id` > 100 )

字串條件查詢

對於一些實在複雜的查詢,也可以直接使用原生SQL語句進行查詢,例如:

Db::table('think_user')
 ->where('id > 0 AND name LIKE "thinkphp%"')
 ->select();

為了安全起見,我們可以對字串查詢條件使用引數繫結,例如:

Db::table('think_user')
 ->where('id > :id AND name LIKE :name ',['id' => 0,'name' => 'thinkphp%'])
 ->select();

V5.1.8+版本開始,如果你要使用字串條件查詢,推薦使用whereRaw方法。

Db::table('think_user')
 ->whereRaw('id > :id AND name LIKE :name ','name' => 'thinkphp%'])
 ->select();

使用Query物件查詢(V5.1.5+)

V5.1.5+版本開始,可以通過呼叫一次where方法傳入Query物件來進行查詢。

$query = new \think\db\Query;
$query->where('id',0)
	->where('name','%thinkphp');
 
Db::table('think_user')
 ->where($query)
 ->select();

Query物件的where方法僅能呼叫一次,如果query物件裡面使用了非查詢條件的鏈式方法,則不會傳入當前查詢。

$query = new \think\db\Query;
$query->where('id','%thinkphp')
 ->order('id','desc') // 不會傳入後面的查詢
 ->field('name,id'); // 不會傳入後面的查詢
 
Db::table('think_user')
 ->where($query)
 ->where('title','thinkphp%') // 有效
 ->select();

快捷方法

系統封裝了一系列快捷方法,用於簡化查詢,包括:

方法 作用
whereOr 欄位OR查詢
whereXor 欄位XOR查詢
whereNull 查詢欄位是否為Null
whereNotNull 查詢欄位是否不為Null
whereIn 欄位IN查詢
whereNotIn 欄位NOT IN查詢
whereBetween 欄位BETWEEN查詢
whereNotBetween 欄位NOT BETWEEN查詢
whereLike 欄位LIKE查詢
whereNotLike 欄位NOT LIKE查詢
whereExists EXISTS條件查詢
whereNotExists NOT EXISTS條件查詢
whereExp 表示式查詢
whereColumn 比較兩個欄位

下面舉例說明下兩個欄位比較的查詢條件whereColumn方法的用法。

查詢update_time大於create_time的使用者資料

Db::table('think_user')
 ->whereColumn('update_time','create_time')
 ->select();

生成的SQL語句是:

SELECT * FROM `think_user` WHERE ( `update_time` > `create_time` ) 

查詢namenickname相同的使用者資料

Db::table('think_user')
 ->whereColumn('name','nickname')
 ->select();

生成的SQL語句是:

SELECT * FROM `think_user` WHERE ( `name` = `nickname` )

相同欄位條件也可以簡化為

Db::table('think_user')
 ->whereColumn('name','nickname')
 ->select();

高階查詢

快捷查詢

快捷查詢方式是一種多欄位相同查詢條件的簡化寫法,可以進一步簡化查詢條件的寫法,在多個欄位之間用|分割表示OR查詢,用&分割表示AND查詢,可以實現下面的查詢,例如:

Db::table('think_user')
 ->where('name|title',0)
 ->find();

生成的查詢SQL是:

SELECT * FROM `think_user` 
WHERE ( `name` LIKE 'thinkphp%' OR `title` LIKE 'thinkphp%' ) 
AND ( `create_time` > 0 AND `update_time` > 0 ) 
LIMIT 1

快捷查詢支援所有的查詢表示式。

區間查詢

區間查詢是一種同一欄位多個查詢條件的簡化寫法,例如:

Db::table('think_user')
 ->where('name','and')
 ->find();

生成的SQL語句為:

SELECT * FROM `think_user` 
WHERE ( `name` LIKE '%thinkphp%' OR `name` LIKE '%kancloud%' ) 
AND ( `id` > 0 AND `id` <> 10 ) 
LIMIT 1

區間查詢的查詢條件必須使用陣列定義方式,支援所有的查詢表示式。

下面的查詢方式是錯誤的:

Db::table('think_user')
 ->where('name',])
 ->select();

生成的SQL語句為:

SELECT * FROM `think_user` 
WHERE `name` LIKE 'thinkphp%' 
AND `title` LIKE '%thinkphp' 
AND `id` > 0 
AND `status` = '1'

注意,V5.1.7+版本陣列方式如果使用exp查詢的話,一定要用raw方法。

Db::table('think_user')
 ->where([
 ['name',1)
 ->select();

生成的SQL語句為:

SELECT * FROM `think_user` 
WHERE ( `name` LIKE 'thinkphp%' AND `title` LIKE '%thinkphp' AND `id` > 0 ) 
AND `status` = '1'

如果使用下面的多個條件組合

$map1 = [
 ['name',$map2 ])
 ->select();

生成的SQL語句為:

SELECT * FROM `think_user` 
WHERE ( `name` LIKE 'thinkphp%' AND `title` LIKE '%thinkphp' ) 
OR ( `name` LIKE 'kancloud%' AND `title` LIKE '%kancloud' )

善用多維陣列查詢,可以很方便的拼裝出各種複雜的SQL語句

陣列物件查詢(V5.1.21+)

對於習慣或者重度依賴陣列查詢條件的使用者來說,可以選擇陣列物件查詢,該物件完成了普通陣列方式查詢和系統的查詢表示式之間的橋接,但相較於系統推薦的查詢表示式方方式而言,需要注意變數的安全性,避免產生SQL注入的情況

使用方法如下:

use think\db\Where;
 
$map = [
 'name' => ['like','%php%'];
 
Db::table('think_user')
 ->where(new Where($map))
 ->whereOr($where->enclose())
 ->select();

enclose方法表示該查詢條件兩邊會加上括號包起來。

使用陣列物件查詢的情況請一定要注意做好資料型別檢查,儘量避免讓使用者決定你的資料。

生成的SQL是:

SELECT * FROM `think_user` 
WHERE `name` LIKE 'thinkphp%' 
AND `title` LIKE '%think%' 
AND `id` > 10 
AND `status` =1 
OR ( `id` IN (1,3) AND `title` LIKE '%php%' )

閉包查詢

$name = 'thinkphp';
$id = 10;
Db::table('think_user')->where(function ($query) use($name,$id);
})->select();

生成的SQL語句為:

SELECT * FROM `think_user` WHERE ( `name` = 'thinkphp' OR `id` > 10 )

可見每個閉包條件兩邊也會自動加上括號,但需要注意,使用閉包查詢的時候不能使用cache(true)資料快取,而應該使用指定key的方式例如cache('key')

混合查詢

可以結合前面提到的所有方式進行混合查詢,例如:

Db::table('think_user')
 ->where('name','or');
 })
 ->select();

生成的SQL語句是:

SELECT * FROM `think_user` 
WHERE ( `name` LIKE 'thinkphp%' AND `name` LIKE '%thinkphp' ) 
AND ( `id` < 10 or `id` > 100 )

字串條件查詢

對於一些實在複雜的查詢,也可以直接使用原生SQL語句進行查詢,例如:

Db::table('think_user')
 ->where('id > 0 AND name LIKE "thinkphp%"')
 ->select();

為了安全起見,我們可以對字串查詢條件使用引數繫結,例如:

Db::table('think_user')
 ->where('id > :id AND name LIKE :name ','nickname')
 ->select();

V5.1.11+版本開始,支援陣列方式比較多個欄位

Db::name('user')->whereColumn([
	['title','name'],['update_time','>=','create_time'],])->select();

生成的SQL語句是:

SELECT * FROM `think_user` 
WHERE ( `name` = `nickname` AND `update_time` > `create_time` ) 

動態查詢

查詢構造器還提供了兩個動態查詢機制,用於簡化查詢條件,包括getBygetFieldBy

動態查詢 描述
whereFieldName 查詢某個欄位的值
whereOrFieldName 查詢某個欄位的值
getByFieldName 根據某個欄位查詢
getFieldByFieldName 根據某個欄位獲取某個值

其中FieldName表示資料表的實際欄位名稱的駝峰法表示,假設資料表user中有emailnick_name欄位,我們可以這樣來查詢。

// 根據郵箱(email)查詢使用者資訊
$user = Db::table('user')
	->whereEmail('[email protected]')
 ->find();
 
// 根據暱稱(nick_name)查詢使用者
$email = Db::table('user')
 ->whereNickName('like','%流年%')
 ->select();
 
// 根據郵箱查詢使用者資訊
$user = Db::table('user')
 ->getByEmail('[email protected]');
 
// 根據暱稱(nick_name)查詢使用者資訊
$user = Db::table('user')
 ->field('id,name,nick_name,email')
 ->getByNickName('流年');
 
// 根據郵箱查詢使用者的暱稱
$nickname = Db::table('user')
 ->getFieldByEmail('[email protected]','nick_name');
 
// 根據暱稱(nick_name)查詢使用者郵箱
$email = Db::table('user')
 ->getFieldByNickName('流年','email');

getBygetFieldBy方法只會查詢一條記錄,可以和其它的鏈式方法搭配使用

條件查詢

5.1的查詢構造器支援條件查詢,例如:

Db::name('user')->when($condition,function ($query) {
 // 滿足條件後執行
 $query->where('score',80)->limit(10);
})->select();

並且支援不滿足條件的分支查詢

Db::name('user')->when($condition,80)->limit(10);
},function ($query) {
 // 不滿足條件執行
 $query->where('score',60);
});

更多關於thinkPHP相關內容感興趣的讀者可檢視本站專題:《ThinkPHP入門教程》、《thinkPHP模板操作技巧總結》、《ThinkPHP常用方法總結》、《codeigniter入門教程》、《CI(CodeIgniter)框架進階教程》、《Zend FrameWork框架入門教程》及《PHP模板技術總結》。

希望本文所述對大家基於ThinkPHP框架的PHP程式設計有所幫助。