數據庫
參見《Thinkphp5.1完全開發手冊》學習
Mirror王宇陽
數據庫連接
-
ThinkPHP采用內置抽象層對數據庫操作進行封裝處理;且基於PDO模式,可以適配各種數據庫。
-
數據庫連接的配置文件(config/database.php)設置數據庫的連接信息
class DataTest extends Controller// 數據庫連接 { // url => http://localhost/tp5.1/public/index.php/index/data_test public function index() { $data = Db::table('tp_access')->select(); $data = Db::name('access')->select(); return json($data); } }
查詢控制器(數據庫操作)
想要查看SQL的執行語句細節可以配置:config/app.php -> app_trace => true;
開啟后就可以在HTML頁面右下角打開SQL語句的具體執行過程
注意:json輸出的數據無法使用這一功能哦!
查詢數據
查詢單個數據使用find
方法:
// table方法必須指定完整的數據表名
Db::table('think_user')->where('id',1)->find();
最終生成的SQL語句可能是:
SELECT * FROM `think_user` WHERE `id` = 1 LIMIT 1
find 方法查詢結果不存在,返回 null,否則返回結果數組
V5.1.23+
版本開始,支持findOrEmpty
方法,當查詢不存在的時候返回空數組而不是Null。
// table方法必須指定完整的數據表名
Db::table('think_user')->where('id',1)->findOrEmpty();
如果沒有查找到數據,則會拋出一個think\db\exception\DataNotFoundException
異常。
try{ //捕獲異常
// table方法必須指定完整的數據表名
$data = Db::table('think_user')->where('id',1)->findOrEmpty();
} catch (DataNotFoundException $err) {
return '數據查詢發送異常!'
}
查詢多個數據(數據集)使用select
方法:
Db::table('think_user')->where('status',1)->select();
最終生成的SQL語句可能是:
SELECT * FROM `think_user` WHERE `status` = 1
select 方法查詢結果是一個二維數組,如果結果不存在,返回空數組
如果希望在沒有查找到數據后拋出異常可以使用
try{ //捕獲異常
$data = Db::table('think_user')->where('status',1)->selectOrFail();
} catch (DataNotFoundException $err) {
return '數據查詢發送異常!'
}
默認情況下,
find
和select
方法返回的都是數組,區別在於后者是二維數組。
系統提供了一個db
助手函數,可以更方便的查詢:
db('user')->where('id',1)->find();
db('user')->where('status',1)->select();
db
方法的第一個參數的作用和name
方法一樣,如果需要使用不同的數據庫連接,可以使用:
db('user','db_config1')->where('id', 1)->find();
查詢某個字段的值可以用 value(‘字段名’)
// 返回某個字段的值
Db::table('think_user')->where('id',1)->value('name');
value 方法查詢結果不存在,返回 null
查詢某一列的值可以用 colum('字段名/列名')
// 返回數組
Db::table('think_user')->where('status',1)->column('name');
// 指定id字段的值作為索引
Db::table('think_user')->where('status',1)->column('name','id');
如果要返回完整數據,並且添加一個索引值的話,可以使用
// 指定id字段的值作為索引 返回所有數據
Db::table('think_user')->where('status',1)->column('*','id');
column 方法查詢結果不存在,返回空數組
數據分批處理可以使用 chunk
我們可以全部用戶表數據進行分批處理,每次處理 100 個用戶記錄:
Db::table('think_user')->chunk(100, function($users) {
foreach ($users as $user) {
//
}
});
// 或者交給回調方法myUserIterator處理
Db::table('think_user')->chunk(100, 'myUserIterator');
你可以通過從閉包函數中返回false
來中止對后續數據集的處理:
Db::table('think_user')->chunk(100, function($users) {
foreach ($users as $user) {
// 處理結果集...
if($user->status==0){
return false;
}
}
});
也支持在chunk
方法之前調用其它的查詢方法,例如:
Db::table('think_user')
->where('score','>',80)
->chunk(100, function($users) {
foreach ($users as $user) {
//
}
});
chunk
方法的處理默認是根據主鍵查詢,支持指定字段,例如:
Db::table('think_user')->chunk(100, function($users) {
// 處理結果集...
return false;
},'create_time');
並且支持指定處理數據的順序。
Db::table('think_user')->chunk(100, function($users) {
// 處理結果集...
return false;
},'create_time', 'desc');
chunk
方法一般用於命令行操作批處理數據庫的數據,不適合WEB訪問處理大量數據,很容易導致超時。
大批量數據處理
如果你需要處理大量的數據,可以使用新版提供的游標查詢功能,該查詢方式利用了PHP的生成器特性,可以大幅減少大量數據查詢的內存占用問題。
$cursor = Db::table('user')->where('status', 1)->cursor();
foreach($cursor as $user){
echo $user['name'];
}
cursor
方法返回的是一個生成器對象,user
變量是數據表的一條數據(數組)。
JSON類型數據查詢(mysql
)
// 查詢JSON類型字段 (info字段為json類型)
Db::table('think_user')
->where('info->email','thinkphp@qq.com')
->find();
鏈式查詢簡單認識
-
查詢規則
-
通過指向符號
->
多次連續的調用方法Db::table('think_user') ->where('status',1) ->order('create_time') ->limit(10) ->select();
-
多次i的調用使用返回的都是數據庫對象,可以多次的鏈式查詢數據對象的方法
-
最后的數據庫對象可以使用 find()、select() 等結果方法,返回數據結果
-
find()、select()、value()、column() 是結果查詢方法,並不是鏈式查詢方法
-
-
鏈式查詢方法:
系統支持的鏈式操作方法包含:
連貫操作 作用 支持的參數類型 where* 用於AND查詢 字符串、數組和對象 whereOr* 用於OR查詢 字符串、數組和對象 wheretime* 用於時間日期的快捷查詢 字符串 table 用於定義要操作的數據表名稱 字符串和數組 alias 用於給當前數據表定義別名 字符串 field* 用於定義要查詢的字段(支持字段排除) 字符串和數組 order* 用於對結果排序 字符串和數組 limit 用於限制查詢結果數量 字符串和數字 page 用於查詢分頁(內部會轉換成limit) 字符串和數字 group 用於對查詢的group支持 字符串 having 用於對查詢的having支持 字符串 join* 用於對查詢的join支持 字符串和數組 union* 用於對查詢的union支持 字符串、數組和對象 view* 用於視圖查詢 字符串、數組 distinct 用於查詢的distinct支持 布爾值 lock 用於數據庫的鎖機制 布爾值 cache 用於查詢緩存 支持多個參數 relation* 用於關聯查詢 字符串 with* 用於關聯預載入 字符串、數組 bind* 用於數據綁定操作 數組或多個參數 comment 用於SQL注釋 字符串 force 用於數據集的強制索引 字符串 master 用於設置主服務器讀取數據 布爾值 strict 用於設置是否嚴格檢測字段名是否存在 布爾值 sequence 用於設置Pgsql的自增序列名 字符串 failException 用於設置沒有查詢到數據是否拋出異常 布爾值 partition 用於設置分表信息 數組 字符串 所有的連貫操作都返回當前的模型實例對象(this),其中帶*標識的表示支持多次調用。
-
更多查詢
多次查詢並不需要每次都創建一個實例;可以保存實例對象進行反復調用:
$user = Db::name('user'); $data = $user->select();
public function getModelData() { $book = Db::table('tp_book'); // 創建tp_book的實例並保持$book $data = $book->select(); return json($data); $data1 = $book->where('id',1)->column('title'); //使用被保持的實例 return json($data1); // 結果返回 莎士比亞 $data2 = $book->column('title'); // 被保存的實例會保留上一個查詢結果(對象) return json($data3); // 結果返回 與 $data2 一致 }
實例會保存上一個查詢對象結果,但使用
removerOption()
方法可以清理上一個保留的值$data3 = $book->removeOption('where')->column('title'); return json($data3); // 結果返回 沒有where條件限制了
增刪改操作
新增數據
ThinkPHP5.1使用insert()
、insertGetId()
方法向數據表添加一條數據
使用 Db
類的 insert
方法向數據庫提交數據
$data = ['foo' => 'bar', 'bar' => 'foo'];
// 筆者在insert()的時候,發現中文內容添加后會在數據庫中顯示空白
Db::name('user')->insert($data);
insert
方法添加數據成功返回添加成功的條數,通常情況返回 1
// 新增數據到數據表中
public function insert()
{
$book = Db::table('tp_book');
// 匹配添加數據
$data = [ // 可為空Null的、自動增補的可以忽略不添加
'user_id' => '66',
'title' => 'Mirror'
];
$book->insert($data);
$select = $book->select();
return json($select);
}
或者使用data
方法配合insert
使用。
$data = ['foo' => 'bar', 'bar' => 'foo'];
Db::name('user')
->data($data)
->insert();
如果你的數據表里面沒有
foo
或者bar
字段,那么就會拋出異常。
如果不希望拋出異常,可以使用下面的方法:
$data = ['foo' => 'bar', 'bar' => 'foo'];
Db::name('user')->strict(false)->insert($data);
不存在的字段的值將會直接拋棄。
如果是mysql數據庫,支持replace
寫入,例如:
$data = ['foo' => 'bar', 'bar' => 'foo'];
Db::name('user')->insert($data, true);
添加數據后如果需要返回新增數據的自增主鍵,可以使用insertGetId
方法新增數據並返回主鍵值:
$userId = Db::name('user')->insertGetId($data);
insertGetId
方法添加數據成功返回添加數據的自增主鍵
添加多條數據直接向 Db 類的 insertAll
方法傳入需要添加的數據即可
public function insertAll()//批量添加到數據表
{
$dataAll = [
[
'user_id' => '66',
'title' => '《白帽子講Web安全》'
],
[
'user_id' => '88',
'title' => '《喬布斯傳》'
],
[
'user_id' => '99',
'title' => '《白夜行》'
],
];
$kk = Db::table('tp_book')->insertAll($dataAll);
return $kk;
}
insertAll 方法添加數據成功返回添加成功的條數
如果批量插入的數據比較多,可以指定分批插入,使用limit
方法指定每次插入的數量限制。
$data = [
['foo' => 'bar', 'bar' => 'foo'],
['foo' => 'bar1', 'bar' => 'foo1'],
['foo' => 'bar2', 'bar' => 'foo2']
...
];
// 分批寫入 每次最多100條數據
Db::name('user')->data($data)->limit(100)->insertAll();
修改數據
// 修改數據
public function update()
{
$date = [
'title' => '《解憂雜貨鋪》'
];
$kk = Db::table('tp_book')->where('user_id','99')->update($date);
return $kk;
}
update 方法返回影響數據的條數,沒修改任何數據返回 0
如果數據中包含主鍵,可以直接使用:
Db::name('user')
->update(['name' => 'thinkphp','id'=>1]);
如果要更新的數據需要使用SQL
函數或者其它字段,可以使用下面的方式:
Db::name('user')
->where('id',1)
->inc('read_time') //對字段增值
->dec('score',3) //對字段減值
->exp('name','UPPER(name)') // 在字段中使用mysql函數
->update();
可以使用setInc/setDec
方法自增或自減一個字段的值( 如不加第二個參數,默認步長為1)。
// score 字段加 1
Db::table('think_user')
->where('id', 1)
->setInc('score');
// score 字段加 5
Db::table('think_user')
->where('id', 1)
->setInc('score', 5);
// score 字段減 1
Db::table('think_user')
->where('id', 1)
->setDec('score');
// score 字段減 5
Db::table('think_user')
->where('id', 1)
->setDec('score', 5);
setInc/setDec
支持延時更新,如果需要延時更新則傳入第三個參數,下例中延時10秒更新。
Db::name('user')->where('id', 1)->setInc('score', 1, 10);
V5.1.7+
版本以后,支持使用raw
方法進行數據更新,適合在數組更新的情況。
Db::name('user')
->where('id', 1)
->update([
'name' => Db::raw('UPPER(name)'),
'score' => Db::raw('score-3'),
'read_time' => Db::raw('read_time+1')
]);
字段值更新 setField('原字段名','新字段名')
Db::name('user')
->where('id',1)
->setField('name', 'thinkphp');
刪除數據
// 根據主鍵刪除
Db::table('think_user')->delete(1);
Db::table('think_user')->delete([1,2,3]);
// 條件刪除
Db::table('think_user')->where('id',1)->delete();
Db::table('think_user')->where('id','<',10)->delete();
// 無條件刪除所有數據
Db::name('user')->delete(true);
查詢表達式
比較查詢
Db::name('book')->where('id',80)->find(); //簡寫
Db::name('book')->where('id','=',80)->find(); //完整;且與第一條同意義
5.1
還支持新的查詢方法
whereField('表達式','查詢條件');
whereOrField('表達式','查詢條件');
Field
使用字段的駝峰命名方式。
-
where() 格式
where( 字段名 , 表達式 , 查詢條件);
表達式包含以下:
表達式 含義 快捷查詢方法 = 等於 <> 不等於 > 大於 >= 大於等於 < 小於 <= 小於等於 [NOT] LIKE 模糊查詢 whereLike/whereNotLike
[NOT] BETWEEN (不在)區間查詢 whereBetween/whereNotBetween
[NOT] IN (不在)IN 查詢 whereIn/whereNotIn
[NOT] NULL 查詢字段是否(不)是NULL whereNull/whereNotNull
[NOT] EXISTS EXISTS查詢 whereExists/whereNotExists
[NOT] REGEXP 正則(不)匹配查詢 (僅支持Mysql) [NOT] BETWEEM TIME 時間區間比較 whereBetweenTime > TIME 大於某個時間 whereTime
< TIME 小於某個時間 whereTime
>= TIME 大於等於某個時間 whereTime
<= TIME 小於等於某個時間 whereTime
EXP 表達式查詢,支持SQL語法 whereExp
區間查詢(建議使用快捷)
-
link 表達式進行模糊查詢
$data = Db::table('tp_book')->where('title','like','%白%')->column('title'); return json($data);
支持使用數組
// 查詢 title中包含 白和M開頭的書籍 $data = Db::table('tp_book') ->where('title','like',['%白%','M%'],'OR') ->column('title'); return json($data);
為了更加方便,應該直接使用
whereLike
方法Db::name('user')->whereLike('name','thinkphp%')->select(); Db::name('user')->whereNotLike('name','thinkphp%')->select();
-
between 指定區間范圍查找
查詢條件支持字符串或者數組,例如:
Db::name('user')->where('id','between','1,8')->select();
和下面的等效:
Db::name('user')->where('id','between',[1,8])->select();
最快捷的查詢方法是:
Db::name('user')->whereBetween('id','1,8')->select(); Db::name('user')->whereNotBetween('id','1,8')->select();
-
in 指定索引查找
// in、not in 指定所有查找 $data = Db::table('tp_book')->where('id','in','1,2,23')->column('title'); $data = Db::table('tp_book')->where('id','in','[1,2,23]')->column('title'); $data = Db::table('tp_book')->whereIn('id','1,2,34')->column('title'); $data = Db::table('tp_book')->whereNotIn('id','1,2,3,4,44')->column('title'); return json($data);
-
Null 查詢字段是否(不)是
Null
// null、not null 查詢指定字段是否可以為Null/Not Null $data = Db::table('tp_access')->where('details','null')->column('user_id'); $data = Db::table('tp_access')->where('details','notnull')->column('user_id'); $data = Db::table('tp_access')->whereNull('details')->column('user_id'); $data = Db::table('tp_access')->whereNotNull('details')->column('user_id'); return json($data);
EXP:其它查詢
支持更復雜的查詢情況 例如:
Db::name('user')->where('id','in','1,3,8')->select();
可以改成:
Db::name('user')->where('id','exp',' IN (1,3,8) ')->select();
exp
查詢的條件不會被當成字符串,所以后面的查詢條件可以使用任何SQL支持的語法,包括使用函數和字段名稱。
$data = Db::table('tp_access')->where('id','exp','in (1,2,3,4)')->column('user_id');// 快捷 ↓
$data = Db::table('tp_access')->whereExp('id','in (1,2,3,4)')->column('user_id');
// 等效於 ==> SELECT `user_id` FROM `tp_access` WHERE ( `id` in (1,2,3,4) )
$data = Db::table('tp_book')->whereExp('id','>=20 and user_id =88 ')->column('title');
$data = Db::table('tp_book')->whereExp('','id >=20 and user_id =88 ')->column('title');
// 等效於 ==> SELECT `title` FROM `tp_book` WHERE ( `id` >=20 and user_id =88 )
print_r($data);
時間查詢
-
傳統查詢 where()
where
方法支持時間比較,例如:// 采用比較符號比較時間 $data = Db::table('tp_one')->where('create_time','< time','2016-10-10 00:00:00')->select(); // ==> SELECT * FROM `tp_one` WHERE `create_time` < '2016-10-10 00:00:00' // 在第二參數明確 time 的時候,第三個參數會自動按照完整的time格式填充(年-月-日 時:分:秒) // 時間區間查詢 where('create_time', 'between time', ['2015-1-1', '2016-1-1']);
第三個參數可以傳入任何有效的時間表達式,會自動識別你的時間字段類型,支持的時間類型包括
timestamps
、datetime
、date
和int
區間查詢
whereTime()
/wherebetween()
/wherebetweenTime()
:// 采用whereTime()區間查詢時間 (whereTime()和between time 結果是一樣的,推薦后者) $data = Db::table('tp_one') ->where('create_time','between time',['2018-01-01','2019-01-01']) ->select(); $data = Db::table('tp_one') ->whereTime('create_time',['2018-01-01','2019-01-01']) ->select(); // ==> SELECT * FROM `tp_one` WHERE `create_time` BETWEEN '2018-01-01 00:00:00' AND '2019-01-01 00:00:00' // wherebetween() 也支持如上的區間Time查詢 $data = Db::table('tp_one') ->whereBetween('create_time',['2018-01-01','2019-01-01']) ->select(); // wherebetweenTime() 也是一個支持時間起始查詢函數 $data = Db::table('tp_one') ->whereBetweenTime('create_time','2018-01-01','2019-01-01') ->select(); // 如果第三個參數為空則代表查詢當天(一天)
whereTime()
還支持時間便捷固定查詢:關鍵字 (whereTime()的第三個參數值) 說明 today 今天 yesterday 昨天 week 本周 last week 上周 month 本月 last month 上月 year 本年 last year 去年 同時還支持指定的時間數據查詢;例如兩小時內就是:
-2 hour
whereBetweenTimeField()
多時間(字)段查詢V5.1.17+
版本開始,可以支持對兩個時間字段的區間比較// 查詢有效期內的活動 Db::name('event') ->whereBetweenTimeField('start_time','end_time') ->select();
上面的查詢相當於
// 查詢有效期內的活動 Db::name('event') ->whereTime('start_time', '<=', time()) ->whereTime('end_time', '>=', time()) ->select();
聚合查詢
在應用中我們經常會用到一些統計數據,例如當前所有(或者滿足某些條件)的用戶數、所有用戶的最大積分、用戶的平均成績等等,ThinkPHP為這些統計操作提供了一系列的內置方法,包括:
方法 | 說明 |
---|---|
count | 統計數量,參數是要統計的字段名(可選) |
max | 獲取最大值,參數是要統計的字段名(必須) |
min | 獲取最小值,參數是要統計的字段名(必須) |
avg | 獲取平均值,參數是要統計的字段名(必須) |
sum | 獲取總分,參數是要統計的字段名(必須) |
聚合方法如果沒有數據,默認都是0,聚合查詢都可以配合其它查詢條件
V5.1.5+
版本開始,聚合查詢可以支持JSON
字段類型(MySQL5.7+開始支持JSON)
count()
統計數量: 可以根據表的行數或根據字段的行數
$data = Db::table('tp_book')->count();
// ==> SELECT COUNT(*) AS tp_count FROM `tp_book`
$data = Db::table('tp_book')->count('id');
// ==> SELECT COUNT(`id`) AS tp_count FROM `tp_book`
max()/min()
獲取最值:可以根據字段名獲取字段列中最值;如果字段中的不是數值,函數會自動強制轉換,可以通過定義第二參數為“false”來取消強制轉換的行為
// max()/min() 最值函數
$data = Db::table('tp_book')
->max('user_id');
// ==> SELECT MAX(`user_id`) AS tp_max FROM `tp_book`
$data = Db::table('tp_book')
->max('title');
$data = Db::table('tp_book')
->max('title',false); // 和↑條同作用,但是這條將不強制轉換,按照編碼進行
// ==> SELECT MAX(`title`) AS tp_max FROM `tp_book`
avg()
平均值計算
$data = Db::table('tp_book')->avg('user_id');
// ==> SELECT AVG(`user_id`) AS tp_avg FROM `tp_book`
sum()
求和計算
$data = Db::table('tp_book')->sum('user_id');
// ==> SELECT SUM(`user_id`) AS tp_sum FROM `tp_book`
子查詢
-
使用
fetchSql()
方法,不執行SQL語句而是返回SQL語句,默認True$subQuery = Db::table('think_user') ->field('id,name') ->where('id', '>', 10) ->fetchSql(true) ->select();
生成的subQuery結果為:
SELECT `id`,`name` FROM `think_user` WHERE `id` > 10
-
使用
buidSql()
方法,返回SQL語句且不需要執行select()同時添加兩側括號$subQuery = Db::table('think_user') ->field('id,name') ->where('id', '>', 10) ->buildSql();
生成的subQuery結果為:
( SELECT `id`,`name` FROM `think_user` WHERE `id` > 10 )
在SQL語句中我們需要用到子查詢的功能,就是利用SQL1語句的查詢結果給SQL2語句使用
原生SQL語句:(具備子查詢)
SELECT * FROM `tp_one` WHERE id in (SELECT uid FROM tp_two where gender = '男');
構造ThinkPHP的子查詢代碼:
$sql_1 = Db::table('tp_two')
->field('uid')
// field()方法主要作用是標識要返回或者操作的字段,可以用於查詢和寫入操作。
->where('gender','男')
->buildSql();
$sql = Db::table('tp_one')
->whereIn('id',$sql_1)
->select();
// ==> SELECT * FROM `tp_one` WHERE `id` = ( SELECT `uid` FROM `tp_two` WHERE `gender` = '男' )
// 這里使用WhereIn出現的問題就是原本應該是 IN 卻變成了 = 符號
$sql_exp = Db::table('tp_one')
->whereExp('id','IN'.$sql_1)
->select();
// ==> SELECT * FROM `tp_one` WHERE ( `id` IN( SELECT `uid` FROM `tp_two` WHERE `gender` = '男' ) )
// 由於whereIn無法正確的使用,於是采用whereExp()方法構造IN並使用連接符連接$sql_1
使用閉包構造子查詢
IN/NOT IN
和EXISTS/NOT EXISTS
之類的查詢可以直接使用閉包作為子查詢,例如:
Db::table('think_user')
->where('id', 'IN', function ($query) {
$query->table('think_profile')->where('status', 1)->field('id');
})
->select();
原生查詢
query()/讀操作
query
方法用於執行SQL
查詢操作,如果數據非法或者查詢錯誤則返回false,否則返回查詢結果數據集(同select
方法)。
使用示例:
Db::query("select * from think_user where status=1");
execute()/寫操作
execute
用於更新和寫入數據的sql操作,如果數據非法或者查詢錯誤則返回false
,否則返回影響的記錄數。
使用示例:
Db::execute("update think_user set name='thinkphp' where status=1");
鏈式查詢-建議參考手冊
where
-
表達式查詢:即之前的那些普通的多個表達式組合的查詢方式
例如:where比較查詢、whereIn、whereLike……
-
關聯數組查詢:等值AND和IN函數條件
// Where數組關聯查詢可以等值AND和IN函數條件 $data = Db::table('tp_one')->where([ 'math' => 88, 'chinese' => 88, ])->select(); // ==> SELECT * FROM `tp_one` WHERE `math` = 88 AND `chinese` = 88 $data = Db::table('tp_one')->where([ 'math' => 88, 'chinese' => [88,99,11],//等效於IN (88,99,11) ])->select(); // ==> SELECT * FROM `tp_one` WHERE `math` = 88 AND `chinese` IN (88,99,11)
-
索引數組查詢:批量設置查詢條件
// Where索引數組查詢 $data = Db::table('tp_one')->where([ ['math','<=','88'], ['chinese','>','90'], ])->select(); // ==> SELECT * FROM `tp_one` WHERE `math` <= 88 AND `chinese` > 90
如果需要事先組裝數組查詢條件,可以使用:
$map[] = ['name','like','think']; $map[] = ['status','=',1];
數組的各種查詢方式其實可以多樣應用
-
字符串傳遞
使用字符串條件直接查詢和操作,例如:
Db::table('think_user')->where('type=1 AND status=1')->select();
最后生成的SQL語句是
SELECT * FROM think_user WHERE type=1 AND status=1
這里的where多樣運用需要開發者按照自己的喜好和實際的開發需求決定如何使用;如果無法運用就直接使用原生!
table
table
方法主要用於指定操作的數據表。
Db::table('think_user')->where('status>1')->select(); // 指定數據表
Db::table('db_name.think_user')->where('status>1')->select(); //指定數據庫和表
如果需要對多表進行操作,可以這樣使用:
Db::field('user.name,role.title')
->table('think_user user,think_role role')
->limit(10)->select();
為了盡量避免和mysql的關鍵字沖突,可以建議使用數組方式定義,例如:
Db::field('user.name,role.title')
->table(['think_user'=>'user','think_role'=>'role'])
->limit(10)->select();
使用數組方式定義的優勢是可以避免因為表名和關鍵字沖突而出錯的情況。
alias
alias
用於設置當前數據表的別名,便於使用其他的連貫操作;例如join方法等。
示例:
Db::table('think_user')
->alias('a')
->join('think_dept b ','b.user_id= a.id')
->select();
最終生成的SQL語句類似於:
SELECT * FROM think_user a INNER JOIN think_dept b ON b.user_id= a.id
field
field
方法主要作用是標識要返回或者操作的字段,可以用於查詢和寫入操作。
-
指定字段:field()可以在查詢數據、添加數據中都可以運用到,但是在添加中不得違背SQL的規范
$data = Db::table('tp_book') ->where('user_id','>','50') ->field('title') ->select(); // ==> SELECT `title` FROM `tp_book` WHERE `user_id` > 50
-
使用SQL函數
$data = Db::table('tp_one') ->field('SUM(math)') ->select(); // ==> SELECT SUM(math) FROM `tp_one`
-
field方法的參數可以支持數組,例如:
Db::table('think_user')->field(['id','title','content'])->select();
-
字段排除:排除某一個或多個字段,需要在field()的第二參數設置為True默認Falst
// 排除某一個或多個字段,需要在field()的第二參數設置為True 不支持跨表和join操作。 $data = Db::table('tp_book')->field('user_id',true)->select(); // ==> SELECT `id`,`title` FROM `tp_book` $data = Db::table('tp_book')->field('id,user_id',true)->select(); // ==> SELECT `title` FROM `tp_book`
strict
strict
方法用於設置是否嚴格檢查字段名,用法如下:(建議true)
// 關閉字段嚴格檢查
Db::name('user')
->strict(false)
->insert($data);
注意,系統默認值是由數據庫配置參數fields_strict
決定,因此修改數據庫配置參數可以進行全局的嚴格檢查配置,如下:
// 關閉嚴格檢查字段是否存在
'fields_strict' => false,
如果開啟字段嚴格檢查的話,在更新和寫入數據庫的時候,一旦存在非數據表字段的值,則會拋出異常。
limit
limit()
用於限制輸入輸出的數據條數,也可以指定輸出的行數范圍
// limit() 可以指定輸出的條數、行數范圍、輸入的條數限制
$data = Db::table('tp_book')->field('title')->limit(3)->select(); //限制條數
// ==> SELECT `title` FROM `tp_book` LIMIT 3
$data = Db::table('tp_book')->field('title')->limit(3,3)->select(); // 實現分頁
// ==> SELECT `title` FROM `tp_book` LIMIT 3,3 //limit(起始行,條數)
limit
方法也可以用於寫操作,例如更新滿足要求的3條數據:
Db::table('think_user')
->where('score',100)
->limit(3)
->update(['level'=>'A']);
page
page()
方法主要用於分頁查詢。
// page() 分頁查詢
$data = Db::table('tp_book')->field('title')->page(1,3)->select();
// => SELECT `title` FROM `tp_book` LIMIT 0,3
$data = Db::table('tp_book')->field('title')->page(2,3)->select();
// => SELECT `title` FROM `tp_book` LIMIT 3,3
page()直接是規定第一頁第二頁即可,page()方法自動實現LIMIT的分頁補充……而當LIMIT和page同時出現的話,page接受的一個參數代表頁數,而limit的參數代表輸出的每頁條數。(具體見手冊)
order
order()
方法用於對操作的結果排序或者優先級限制。(參考手冊)
Db::table('think_user')
->where('status', 1)
->order('id', 'desc')
->limit(5)
->select();
SELECT * FROM `think_user` WHERE `status` = 1 ORDER BY `id` desc LIMIT 5
如果沒有指定
desc
或者asc
排序規則的話,默認為asc
。
支持使用數組對多個字段的排序,例如:
Db::table('think_user')
->where('status', 1)
->order(['order','id'=>'desc'])
->limit(5)
->select();
最終的查詢SQL可能是
SELECT * FROM `think_user` WHERE `status` = 1 ORDER BY `order`,`id` desc LIMIT 5
對於更新數據或者刪除數據的時候可以用於優先級限制
Db::table('think_user')
->where('status', 1)
->order('id', 'desc')
->limit(5)
->delete();
生成的SQL
DELETE FROM `think_user` WHERE `status` = 1 ORDER BY `id` desc LIMIT 5
在V5.1.7+
版本開始,如果你需要在order
方法中使用mysql函數的話,必須使用下面的方式:
Db::table('think_user')
->where('status', 1)
->orderRaw("field(name,'thinkphp','onethink','kancloud')")
->limit(5)
->select();
group
GROUP
方法通常用於結合合計函數,根據一個或多個列對結果集進行分組 。(參考手冊)
group
方法只有一個參數,並且只能使用字符串。
例如,我們都查詢結果按照用戶id進行分組統計:
Db::table('think_user')
->field('user_id,username,max(score)')
->group('user_id')
->select();
生成的SQL語句是:
SELECT user_id,username,max(score) FROM think_score GROUP BY user_id
也支持對多個字段進行分組,例如:
Db::table('think_user')
->field('user_id,test_time,username,max(score)')
->group('user_id,test_time')
->select();
生成的SQL語句是:
SELECT user_id,test_time,username,max(score) FROM think_user GROUP BY user_id,test_time
having
HAVING
方法用於配合group方法完成從分組的結果中篩選(通常是聚合條件)數據。
having
方法只有一個參數,並且只能使用字符串,例如:
Db::table('think_user')
->field('username,max(score)')
->group('user_id')
->having('count(test_time)>3')
->select();
生成的SQL語句是:
SELECT username,max(score) FROM think_score GROUP BY user_id HAVING count(test_time)>3