ThinkPHP6.0 數據庫鏈式操作
數據庫提供的鏈式操作方法,可以有效的提高數據存取的代碼清晰度和開發(fā)效率,并且支持所有的CURD操作。
ThinkPHP6 數據庫鏈式操作
數據庫提供的鏈式操作方法,可以有效的提高數據存取的代碼清晰度和開發(fā)效率,并且支持所有的
CURD
操作帶*標識的表示支持多次調用
連貫操作 | 作用 | 支持的參數類型 |
where* | 用于AND查詢 | 字符串、數組和對象 |
table | 用于定義要操作的數據表名稱 | 字符串和數組 |
name | 用于定義要操作的數據表名稱 | 字符串 |
field* | 用于定義要查詢的字段(支持字段排除) | 字符串和數組 |
order* | 用于對結果排序 | 字符串和數組 |
limit | 用于限制查詢結果數量 | 字符串和數字 |
page | 用于查詢分頁(內部會轉換成limit) | 字符串和數字 |
一、表達式查詢
表達式是SQL語句的條件
表達式不分大小寫
表達式寫在where里
表達式 | 含義 | 查詢方法 |
= | 等于 | |
<> | 不等于 | |
> | 大于 | |
>= | 大于等于 | |
< | 小于 | |
<= | 小于等于 | |
[NOT] LIKE | 模糊查詢 | whereLike/whereNotLike |
[NOT] BETWEEN | (不在)區(qū)間查詢 | whereBetween/whereNotBetween |
[NOT] IN | (不在)IN 查詢 | whereIn/whereNotIn |
[NOT] NULL | 查詢字段是否(不)是NULL | whereNull/whereNotNull |
where
查詢
where方法在鏈式操作方法里面是最常用的方法,可以完成包括普通查詢、表達式查詢、快捷查詢、區(qū)間查詢、組合查詢在內的條件查詢操作
# 等于(=)
$select = Db::table('shop_goods')->where('id','=','1')->select();
print_r($select->toArray());
# 不等于(<>)
$select = Db::table('shop_goods')->where('id','<>','2')->select();
print_r($select->toArray());
# 大于(>)
$select = Db::table('shop_goods')->where('id','>','3')->select();
print_r($select->toArray());
# 大于等于(>=)
$select = Db::table('shop_goods')->where('id','>=','4')->select();
print_r($select->toArray());
# 小于(<)
$select = Db::table('shop_goods')->where('id','<','5')->select();
print_r($select->toArray());
# 小于等于(<=)
$select = Db::table('shop_goods')->where('id','<=','6')->select();
print_r($select->toArray());
# 多where
$select = Db::table('shop_goods')
->where('id','>','3')
->where('id','<','8')
->select();
print_r($select->toArray());
# LIKE
$select = Db::table('shop_goods')->where('title','like','%連衣裙%')->select();
print_r($select->toArray());
# NOT LIKE
$select = Db::table('shop_goods')->where('title','not like','%連衣裙%')->select();
print_r($select->toArray());
# BETWEEN
$select = Db::table('shop_goods')->where('id','between','6,10')->select();
print_r($select->toArray());
# NOT BETWEEN
$select = Db::table('shop_goods')->where('id','not between',[6,10])->select();
print_r($select->toArray());
# IN
$select = Db::table('shop_goods')->where('id','in','4,7,10')->select();
print_r($select->toArray());
# NOT IN
$select = Db::table('shop_goods')->where('id','not in',[4,7,10])->select();
print_r($select->toArray());
二、數據表
1、table 和 name
# 必須完整數據庫名
$select = Db::table('shop_goods')->where('id','10')->select();
print_r($select->toArray());
# 數據庫未設置前綴
$select = Db::name('shop_goods')->where('id','11')->select();
print_r($select->toArray());
# 數據庫設置前綴,無前綴訪問
$select = Db::name('list')->where('id','12')->select();
print_r($select->toArray());
2、數據庫前綴
數據庫配置 database.php
return [
'connections' => [
'mysql' => [
// 數據庫表前綴
'prefix' => Env::get('database.prefix', 'shop_'),
]
]
];
三、返回值
1、field
field 方法主要作用是標識要返回或者操作的字段,可以用于查詢和寫入操作
所有的查詢方法都可以使用field方法
# 字符串
$select = Db::table('shop_goods')
->field('title,price,discount as d')
->where('status',1)
->select();
print_r($select->toArray());
# 數組
$select = Db::table('shop_goods')
->field([
'title',
'price',
'discount'=>'d'
])
->where('status',1)
->select();
print_r($select->toArray());
# 添加,只能添加這幾個字段
# 多field
$data = [
'title' => '新商品',
'price' => 50,
'discount' => 8,
'add_time' => 1576080000
];
$insert = Db::table('shop_goods')
->field('title')
->field('price')
->field('discount')
->field('add_time')
->insert($data);
print_r($insert);
# 查詢全部字段,速度較快
$select = Db::table('shop_goods')
->field(true)
// ->field('*')
->where('status',1)
->select();
print_r($select->toArray());
2、withoutField
withoutField 方法作用 排除數據表中的字段
Db::table('shop_goods')->withoutField('id')->select();
3、fieldRaw
fieldRaw 方法直接使用mysql函數
Db::table('shop_goods')->fieldRaw('id,sum(price)')->select();
四、排序
1、order
方法用于對操作的結果排序或者優(yōu)先級限制
默認正序
asc 正序
desc 倒序
$select = Db::table('shop_goods')
->field('title,price,id')
->where('status',1)
->order('price','DESC')
->order('id','DESC')
->select();
print_r($select->toArray());
2、orderRaw
方法中使用mysql函數
$select = Db::table('shop_goods')
->field('title,price,id')
->where('status',1)
->orderRaw("field(title,'price','discount','stock')")
->select();
print_r($select->toArray());
五、分頁
limit
方法主要用于指定查詢和操作的數量
$select = Db::table('shop_goods')
->field('title,price,id')
->where('status',1)
->order('price','DESC')
->limit(3)
->select();
print_r($select->toArray());
$select = Db::table('shop_goods')
->field('title,price,id')
->where('status',1)
->order('price','DESC')
->limit(0,5)
->select();
print_r($select->toArray());
page
方法主要用于分頁查詢
$select = Db::table('shop_goods')
->field('title,price,id')
->where('status',1)
->order('price','DESC')
->page(1,5)
->select();
print_r($select->toArray());
六、聚合查詢
聚合方法如果沒有數據,默認都是0,聚合查詢都可以配合其它查詢條件
方法 | 功能 |
count | 統(tǒng)計數量,參數是要統(tǒng)計的字段名(可選) |
max | 獲取最大值,參數是要統(tǒng)計的字段名(必須) |
min | 獲取最小值,參數是要統(tǒng)計的字段名(必須) |
avg | 獲取平均值,參數是要統(tǒng)計的字段名(必須) |
sum | 獲取總數,參數是要統(tǒng)計的字段名(必須) |
// 統(tǒng)計數量,參數是要統(tǒng)計的字段名(可選)
$select = Db::table('shop_goods')->count();
print_r($select);
// 獲取最大值,參數是要統(tǒng)計的字段名(必須)
$select = Db::table('shop_goods')->max('id');
print_r($select);
// 獲取最小值,參數是要統(tǒng)計的字段名(必須)
$select = Db::table('shop_goods')->min('id');
print_r($select);
// 獲取平均值,參數是要統(tǒng)計的字段名(必須)
$select = Db::table('shop_goods')->avg('id');
print_r($select);
// 獲取總數,參數是要統(tǒng)計的字段名(必須)
$select = Db::table('shop_goods')->sum('id');
print_r($select);
七、搜索、排序示例
controller代碼
public function index(){
$title = '商城';
$login = '歐陽克';
# 左側菜單
$menu = Db::table('shop_menu')->where('fid',0)->select();
$left = $menu->toArray();
foreach($left as &$left_v){
$left_v['lists'] = Db::table('shop_menu')->where('fid',$left_v['id'])->select();
}
# 右側列表
$param = Request::param();
if(isset($param['status']) && $param['status'] == 1){
$where['status'] = 1;
}else if(isset($param['status']) && $param['status'] == 2){
$where['status'] = 2;
}else{
$where = true;
}
$list = Db::table('shop_goods')
->where($where)
->order('add_time DESC')
->order('id DESC')
->select();
$right = $list->toArray();
foreach($right as &$right_v){
$right_v['cat'] = Db::table('shop_cat')->where('id',$right_v['cat'])->value('name');
}
View::assign([
'title' => $title,
'login' => $login,
'left' => $left,
'right' => $right,
'status' => isset($param['status']) ? $param['status'] : null
]);
return View::fetch();
}
view代碼
<form class="layui-form" method="post">
<div class="layui-form-item" style="margin-top:10px;">
<div class="layui-input-inline">
<select name="status">
<option value="0" {if $status==0}selected{/if}>全部</option>
<option value="1" {if $status==1}selected{/if}>開啟</option>
<option value="2" {if $status==2}selected{/if}>關閉</option>
</select>
</div>
<button class="layui-btn layui-btn-primary"><i class="layui-icon"></i>搜索</button>
</div>
</form>
八、分頁示例
controller代碼
public function index(){
$title = '商城';
$login = '歐陽克';
# 左側菜單
$menu = Db::table('shop_menu')->where('fid',0)->select();
$left = $menu->toArray();
foreach($left as &$left_v){
$left_v['lists'] = Db::table('shop_menu')->where('fid',$left_v['id'])->select();
}
# 右側列表
$param = Request::param();
if(isset($param['status']) && $param['status'] == 1){
$where['status'] = 1;
}else if(isset($param['status']) && $param['status'] == 2){
$where['status'] = 2;
}else{
$where = true;
}
$p = isset($param['p']) ? $param['p'] : 1;
// 統(tǒng)計總數
$count = Db::table('shop_goods')->where($where)->count();
$list = Db::table('shop_goods')
->where($where)
->order('add_time DESC')
->order('id DESC')
->page($p,10)
->select();
$right = $list->toArray();
foreach($right as &$right_v){
$right_v['cat'] = Db::table('shop_cat')->where('id',$right_v['cat'])->value('name');
}
View::assign([
'title' => $title,
'login' => $login,
'left' => $left,
'right' => $right,
'count' => ceil($count/10),
'p' => $p,
'status' => isset($param['status']) ? $param['status'] : 0
]);
return View::fetch();
}
view代碼
<div class="layui-box layui-laypage layui-laypage-default">
<a href="/index.php/Index/index?p={$p-1}&status={$status}" class="layui-laypage-prev {if $p<=1}layui-disabled{/if}">上一頁</a>
{for start="0" end="$count"}
{if $p == $i+1}
<span class="layui-laypage-curr">
<em class="layui-laypage-em"></em>
<em>{$i+1}</em>
</span>
{else/}
<a href="/index.php/Index/index?p={$i+1}&status={$status}">{$i+1}</a>
{/if}
{/for}
<a href="/index.php/Index/index?p={$p+1}&status={$status}" class="layui-laypage-next {if $p>=$count}layui-disabled{/if}">下一頁</a>
</div>
九、模版分頁
paginate
內置了分頁實現,要給數據添加分頁輸出功能變得非常簡單render
獲取翻頁html代碼total
獲取總數量
controller代碼
$select = Db::table('shop_goods')->paginate(10);
print_r($select);echo '<hr>';
foreach($select as $v){
print_r($v);echo '<hr>';
}
print_r($select->render());echo '<hr>';
print_r('總數:'.$select->total());echo '<hr>';
View::assign([
'select' => $select
]);
return View::fetch();
view代碼
<div>{$select|raw}</div>
css代碼
.pagination {
display: inline-block;
padding-left: 0;
margin: 20px 0;
border-radius: 4px;
}
.pagination > li {
display: inline;
}
.pagination > li > a,
.pagination > li > span {
position: relative;
float: left;
padding: 6px 12px;
margin-left: -1px;
line-height: 1.42857143;
color: #337ab7;
text-decoration: none;
background-color: #fff;
border: 1px solid #ddd;
}
.pagination > li:first-child > a,
.pagination > li:first-child > span {
margin-left: 0;
border-top-left-radius: 4px;
border-bottom-left-radius: 4px;
}
.pagination > li:last-child > a,
.pagination > li:last-child > span {
border-top-right-radius: 4px;
border-bottom-right-radius: 4px;
}
.pagination > li > a:hover,
.pagination > li > span:hover,
.pagination > li > a:focus,
.pagination > li > span:focus {
z-index: 2;
color: #23527c;
background-color: #eee;
border-color: #ddd;
}
.pagination > .active > a,
.pagination > .active > span,
.pagination > .active > a:hover,
.pagination > .active > span:hover,
.pagination > .active > a:focus,
.pagination > .active > span:focus {
z-index: 3;
color: #fff;
cursor: default;
background-color: #337ab7;
border-color: #337ab7;
}
.pagination > .disabled > span,
.pagination > .disabled > span:hover,
.pagination > .disabled > span:focus,
.pagination > .disabled > a,
.pagination > .disabled > a:hover,
.pagination > .disabled > a:focus {
color: #777;
cursor: not-allowed;
background-color: #fff;
border-color: #ddd;
}
十、模版分頁示例
參數 | 描述 |
list_rows | 每頁數量 |
page | 當前頁 |
path | url路徑 |
query | url額外參數 |
fragment | url錨點 |
var_page | 分頁變量 |
controller代碼
public function index(){
$title = '商城';
$login = '歐陽克';
# 左側菜單
$menu = Db::table('shop_menu')->where('fid',0)->select();
$left = $menu->toArray();
foreach($left as &$left_v){
$left_v['lists'] = Db::table('shop_menu')->where('fid',$left_v['id'])->select();
}
# 右側列表
$param = Request::param();
if(isset($param['status']) && $param['status'] == 1){
$where['status'] = 1;
}else if(isset($param['status']) && $param['status'] == 2){
$where['status'] = 2;
}else{
$where = true;
}
$p = isset($param['p']) ? $param['p'] : 1;
# thinkphp 自帶分頁
$list = Db::table('shop_goods')
->where($where)
->order('add_time DESC')
->order('id DESC')
->paginate([
'list_rows'=> 10,
'query' => Request::param()
]);
$right = $list->toArray();
foreach($right as &$right_v){
$right_v['cat'] = Db::table('shop_cat')->where('id',$right_v['cat'])->value('name');
}
View::assign([
'title' => $title,
'login' => $login,
'left' => $left,
'right' => $right,
'list' => $list,
'status' => isset($param['status']) ? $param['status'] : 0
]);
return View::fetch();
}
view代碼
<div>{$paginate|raw}</div>
十一、SQL 調試
getLastSql
輸出上次執(zhí)行的sql語句getLastSql
方法只能獲取最后執(zhí)行的 SQL 記錄
$select = Db::table('shop_goods')->select(); echo Db::getLastSql();
fetchSql
方法直接返回當前的 SQL 而不執(zhí)行
$select = Db::table('shop_goods')->fetchSql()->select(); echo $select;
十二、動態(tài)配置數據庫
config目錄database.php文件
return [
'connections' => [
'ouyangke' => [
// 數據庫類型
'type' => Env::get('database.type', 'mysql'),
// 服務器地址
'hostname' => Env::get('database.hostname', '127.0.0.1'),
// 數據庫名
'database' => 'ouyangke',
// 用戶名
'username' => Env::get('database.username', 'root'),
// 密碼
'password' => Env::get('database.password', 'root'),
// 端口
'hostport' => Env::get('database.hostport', '3306'),
// 數據庫連接參數
'params' => [],
// 數據庫編碼默認采用utf8
'charset' => Env::get('database.charset', 'utf8'),
// 數據庫表前綴
'prefix' => Env::get('database.prefix', 'shop_'),
// 數據庫部署方式:0 集中式(單一服務器),1 分布式(主從服務器)
'deploy' => 0,
// 數據庫讀寫是否分離 主從式有效
'rw_separate' => false,
// 讀寫分離后 主服務器數量
'master_num' => 1,
// 指定從服務器序號
'slave_no' => '',
// 是否嚴格檢查字段是否存在
'fields_strict' => true,
// 是否需要斷線重連
'break_reconnect' => false,
// 監(jiān)聽SQL
'trigger_sql' => true,
// 開啟字段緩存
'fields_cache' => false,
// 字段緩存路徑
'schema_cache_path' => app()->getRuntimePath() . 'schema' . DIRECTORY_SEPARATOR,
]
]
];
ouyangke數據庫中的shop_user表
CREATE TABLE `shop_user` (
`uid` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '用戶ID',
`account` varchar(50) NOT NULL COMMENT '賬戶',
`password` char(32) NOT NULL COMMENT '密碼',
`name` varchar(50) NOT NULL COMMENT '姓名',
`status` tinyint(1) unsigned NOT NULL DEFAULT '1' COMMENT '狀態(tài) 1開啟 2關閉',
`add_time` int(10) unsigned NOT NULL COMMENT '添加時間',
PRIMARY KEY (`uid`)
) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COMMENT='后臺管理員';
connect
方法動態(tài)配置數據庫連接信息
Db::connect('ouyangke')->table('shop_user')->select();
connect
方法必須在查詢的最開始調用,而且必須緊跟著調用查詢方法,否則可能會導致部分查詢失效或者依然使用默認的數據庫連接
十三、WHRER 鏈式操作(不常用)
和查詢表達式功能一樣,ThinkPHP 提供以下快捷查詢方法
連貫操作 | 作用 | 支持的參數類型 |
whereOr* | 用于OR查詢 | 字符串、數組和對象 |
whereLike* | 模糊查詢 | 字符串 |
whereNotLike* | 模糊查詢 | 字符串 |
whereBetween* | 區(qū)間查詢 | 字符串 |
whereNotBetween* | 不在區(qū)間查詢 | 字符串 |
whereIn* | IN查詢 | 字符串 |
whereNotIn* | 不在IN查詢 | 字符串 |
whereNull* | 查詢字段是否是NULL | 字符串 |
whereNotNull* | 查詢字段是否不是NULL | 字符串 |
whereExists* | EXISTS查詢 | 字符串 |
whereNotExists* | 不在EXISTS查詢 | 字符串 |
whereBetweenTime* | 時間區(qū)間比較 | 字符串 |
whereTime* | 用于時間日期的快捷查詢 | 字符串 |
whereExp* | 表達式查詢,支持SQL語法 | 字符串 |
whereFindInSet* | FIND_IN_SET查詢 | 字符串 |
whereRaw* | 用于字符串條件直接查詢和操作 | 字符串 |
十四、其他鏈式操作(不常用)
連貫操作 | 作用 | 支持的參數類型 |
alias | 用于給當前數據表定義別名 | 字符串 |
strict | 用于設置是否嚴格檢測字段名是否存在 | 布爾值 |
group | 用于對查詢的group支持 | 字符串 |
having | 用于對查詢的having支持 | 字符串 |
join* | 用于對查詢的join支持 | 字符串和數組 |
union* | 用于對查詢的union支持 | 字符串、數組和對象 |
distinct | 用于查詢的distinct支持 | 布爾值 |
lock | 用于數據庫的鎖機制 | 布爾值 |
cache | 用于查詢緩存 | 支持多個參數 |
comment | 用于SQL注釋 | 字符串 |
force | 用于數據集的強制索引 | 字符串 |
partition | 用于設置分區(qū)信息 | 數組 字符串 |
failException | 用于設置沒有查詢到數據是否拋出異常 | 布爾值 |
sequence | 用于設置自增序列名 | 字符串 |
replace | 用于設置使用REPLACE方式寫入 | 布爾值 |
extra | 用于設置額外查詢規(guī)則 | 字符串 |
duplicate | 用于設置DUPLCATE信息 | 數組 字符串 |
procedure | 用于設置當前查詢是否為存儲過程查詢 | 布爾值 |
master | 用于設置主服務器讀取數據 | 布爾值 |
view* | 用于視圖查詢 | 字符串、數組 |
十五、事務操作
InnoDB
引擎支持事務處理,MyISAM
不支持事務處理
// 啟動事務 Db::startTrans(); $data = ['cat'=>'1','title'=>'日系小浪漫與溫暖羊毛針織拼接網紗百褶中長收腰連衣裙','price'=>'1598.35','add_time'=>1576080000]; $insert = Db::table('shop_goods')->insert($data); if(empty($insert)){ // 回滾事務 Db::rollback(); }else{ // 提交事務 Db::commit(); }
transaction
方法操作數據庫事務,當閉包中的代碼發(fā)生異常會自動回滾
Db::transaction(function () { $data = ['cat'=>'1','title'=>'日系小浪漫與溫暖羊毛針織拼接網紗百褶中長收腰連衣裙','price'=>'1598.35','add_time'=>1576080000]; $insert = Db::table('shop_goods')->insert($data); });
十六、數據集
數據庫通過select查詢,得到的數據集對象
返回的數據集對象是
think\Collection
,提供了和數組無差別用法,并且另外封裝了一些額外的方法
編號 | 方法 | 描述 |
1 | isEmpty | 是否為空 |
2 | toArray | 轉換為數組 |
3 | all | 所有數據 |
4 | merge | 合并其它數據 |
5 | diff | 比較數組,返回差集 |
6 | flip | 交換數據中的鍵和值 |
7 | intersect | 比較數組,返回交集 |
8 | keys | 返回數據中的所有鍵名 |
9 | pop | 刪除數據中的最后一個元素 |
10 | shift | 刪除數據中的第一個元素 |
11 | unshift | 在數據開頭插入一個元素 |
12 | push | 在結尾插入一個元素 |
13 | reduce | 通過使用用戶自定義函數,以字符串返回數組 |
14 | reverse | 數據倒序重排 |
15 | chunk | 數據分隔為多個數據塊 |
16 | each | 給數據的每個元素執(zhí)行回調 |
17 | filter | 用回調函數過濾數據中的元素 |
18 | column | 返回數據中的指定列 |
19 | sort | 對數據排序 |
20 | order | 指定字段排序 |
21 | shuffle | 將數據打亂 |
22 | slice | 截取數據中的一部分 |
23 | map | 用回調函數處理數組中的元素 |
24 | where | 根據字段條件過濾數組中的元素 |
25 | whereLike | Like查詢過濾元素 |
26 | whereNotLike | Not Like過濾元素 |
27 | whereIn | IN查詢過濾數組中的元素 |
28 | whereNotIn | Not IN查詢過濾數組中的元素 |
29 | whereBetween | Between查詢過濾數組中的元素 |
30 | whereNotBetween | Not Between查詢過濾數組中的元素 |
$select = Db::table('shop_goods') ->field('title,price,id') ->where('status',1) ->order('price','DESC') ->select(); if($select->isEmpty()){ echo '未查詢到數據'; }else{ print_r($select->toArray()); }
備:在模型中進行數據集查詢,全部返回數據集對象,但使用的是think\model\Collection類
(繼承think\Collection),但用法是一致的。