ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
# ThinkPHP6.0 数据库链式操作 数据库提供的链式操作方法,可以有效的提高数据存取的代码清晰度和开发效率,并且支持所有的CURD操作。 * * * ## ThinkPHP6 数据库链式操作 * 数据库提供的链式操作方法,可以有效的提高数据存取的代码清晰度和开发效率,并且支持所有的`CURD`操作 * 带\*标识的表示支持多次调用 连贯操作&nbsp;作用&nbsp;支持的参数类型where*用于AND查询字符串、数组和对象table&nbsp;用于定义要操作的数据表名称字符串和数组name&nbsp;用于定义要操作的数据表名称字符串field*用于定义要查询的字段(支持字段排除)字符串和数组order*用于对结果排序字符串和数组limit&nbsp;用于限制查询结果数量字符串和数字page&nbsp;用于查询分页(内部会转换成limit)字符串和数字 ## 一、表达式查询 * 表达式是SQL语句的条件 * 表达式不分大小写 * 表达式写在where里 表达式含义查询方法=等于&lt;&gt;不等于&gt;大于&gt;=大于等于&lt;小于&lt;=小于等于[NOT] LIKE模糊查询whereLike/whereNotLike[NOT] BETWEEN(不在)区间查询whereBetween/whereNotBetween[NOT] IN(不在)IN 查询&nbsp;whereIn/whereNotIn[NOT] NULL查询字段是否(不)是NULLwhereNull/whereNotNull `where`查询 * where方法在链式操作方法里面是最常用的方法,可以完成包括普通查询、表达式查询、快捷查询、区间查询、组合查询在内的条件查询操作 > \# 等于(=) > > $select = Db::table('shop\_goods')->where('id','=','1')->select(); > > print\_r($select->toArray()); > > > > \# 不等于(<>) > > $select = Db::table('shop\_goods')->where('id','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','select(); > > print\_r($select->toArray()); > > > > \# 小于等于(<=) > > $select = Db::table('shop\_goods')->where('id','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`方法用于对操作的结果排序或者优先级限制 * 默认正序 * 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&nbsp;统计数量,参数是要统计的字段名(可选)max&nbsp;获取最大值,参数是要统计的字段名(必须)min&nbsp;获取最小值,参数是要统计的字段名(必须)avg&nbsp;获取平均值,参数是要统计的字段名(必须)sum获取总数,参数是要统计的字段名(必须) > // 统计数量,参数是要统计的字段名(可选) > > $select = Db::table('shop\_goods')->count(); > > print\_r($select); > > > > // 获取最大值,参数是要统计的字段名(必须) > > $select = Db::table('shop\_goods')->max('id'); > > print\_r($select); > > > > // 获取最小值,参数是要统计的字段名(必须) > > $select = Db::table('shop\_goods')->min('id'); > > print\_r($select); > > > > // 获取平均值,参数是要统计的字段名(必须) > > $select = Db::table('shop\_goods')->avg('id'); > > print\_r($select); > > > > // 获取总数,参数是要统计的字段名(必须) > > $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代码 > > >     > >         > >             > >                 全部 > >                 开启 > >                 关闭 > >             > >         > >         &#xe615;搜索 > >     > > ## 八、分页示例 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; > >     // 统计总数 > >     $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代码 > > >     上一页 > >     {for start="0" end="$count"} > >         {if $p == $i+1} > >             > >                 > >                 {$i+1} > >             > >         {else/} > >             {$i+1} > >         {/if} > >     {/for} > >     =$count}layui-disabled{/if}">下一页 > > ## 九、模版分页 * `paginate`内置了分页实现,要给数据添加分页输出功能变得非常简单 * `render`获取翻页html代码 * `total`获取总数量 controller代码 > $select = Db::table('shop\_goods')->paginate(10); > > print\_r($select);echo ''; > > foreach($select as $v){ > >     print\_r($v);echo ''; > > } > > print\_r($select->render());echo ''; > > print\_r('总数:'.$select->total());echo ''; > > View::assign(\[ > >     'select' => $select > > \]); > > return View::fetch(); view代码 > {$select|raw} 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&nbsp;每页数量page&nbsp;当前页pathurl路径query&nbsp;url额外参数fragment&nbsp;url锚点var_page&nbsp;分页变量 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代码 > {$paginate|raw} ## 十一、SQL 调试 * `getLastSql`输出上次执行的sql语句 * `getLastSql`方法只能获取最后执行的 SQL 记录 ~~~ $select = Db::table('shop_goods')->select(); echo Db::getLastSql(); ~~~ * `fetchSql`方法直接返回当前的 SQL 而不执行 ~~~ $select = Db::table('shop_goods')->fetchSql()->select(); echo $select; ~~~ ## 十二、动态配置数据库 * 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, > >             // 监听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 '状态 1开启 2关闭', > >     `add\_time` int(10) unsigned NOT NULL COMMENT '添加时间', > >     PRIMARY KEY (`uid`) > > ) ENGINE=MyISAM AUTO\_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COMMENT='后台管理员'; * `connect`方法动态配置数据库连接信息 > Db::connect('ouyangke')->table('shop\_user')->select(); `connect`方法必须在查询的最开始调用,而且必须紧跟着调用查询方法,否则可能会导致部分查询失效或者依然使用默认的数据库连接 ## 十三、WHRER 链式操作(不常用) * 和查询表达式功能一样,ThinkPHP 提供以下快捷查询方法 连贯操作作用支持的参数类型whereOr*用于OR查询字符串、数组和对象whereLike*模糊查询字符串whereNotLike*模糊查询字符串whereBetween*区间查询字符串whereNotBetween*不在区间查询&nbsp;字符串whereIn*IN查询字符串whereNotIn*不在IN查询字符串whereNull*查询字段是否是NULL字符串whereNotNull*查询字段是否不是NULL字符串whereExists*EXISTS查询字符串whereNotExists*&nbsp;不在EXISTS查询字符串whereBetweenTime*时间区间比较字符串whereTime*用于时间日期的快捷查询字符串whereExp*&nbsp;表达式查询,支持SQL语法字符串whereFindInSet*FIND_IN_SET查询字符串whereRaw*用于字符串条件直接查询和操作字符串 ## 十四、其他链式操作(不常用) 连贯操作作用&nbsp;支持的参数类型alias&nbsp;用于给当前数据表定义别名&nbsp;字符串strict&nbsp;用于设置是否严格检测字段名是否存在&nbsp;布尔值group&nbsp;用于对查询的group支持字符串having&nbsp;用于对查询的having支持字符串join*用于对查询的join支持字符串和数组union*用于对查询的union支持字符串、数组和对象distinct&nbsp;用于查询的distinct支持布尔值lock&nbsp;用于数据库的锁机制布尔值cache&nbsp;用于查询缓存支持多个参数comment&nbsp;用于SQL注释字符串force&nbsp;用于数据集的强制索引字符串partition&nbsp;用于设置分区信息数组 字符串failException&nbsp;用于设置没有查询到数据是否抛出异常布尔值sequence&nbsp;用于设置自增序列名字符串replace&nbsp;用于设置使用REPLACE方式写入布尔值extra&nbsp;用于设置额外查询规则字符串duplicate&nbsp;用于设置DUPLCATE信息数组 字符串procedure&nbsp;用于设置当前查询是否为存储过程查询布尔值master&nbsp;用于设置主服务器读取数据布尔值view*用于视图查询&nbsp;字符串、数组 ## 十五、事务操作 * `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`方法操作数据库事务,当闭包中的代码发生异常会自动回滚 ~~~ Db::transaction(function () {     $data = ['cat'=>'1','title'=>'日系小浪漫与温暖羊毛针织拼接网纱百褶中长收腰连衣裙','price'=>'1598.35','add_time'=>1576080000];     $insert = Db::table('shop_goods')->insert($data); }); ~~~ ## 十六、数据集 * 数据库通过select查询,得到的数据集对象 * 返回的数据集对象是`think\Collection`,提供了和数组无差别用法,并且另外封装了一些额外的方法 编号方法描述1&nbsp;isEmpty是否为空2&nbsp;toArray&nbsp;转换为数组3&nbsp;all&nbsp;所有数据4&nbsp;merge&nbsp;合并其它数据5&nbsp;diff&nbsp;比较数组,返回差集6&nbsp;flip&nbsp;交换数据中的键和值7&nbsp;intersect&nbsp;比较数组,返回交集8&nbsp;keys&nbsp;返回数据中的所有键名9&nbsp;pop&nbsp;删除数据中的最后一个元素10&nbsp;shift&nbsp;删除数据中的第一个元素11&nbsp;unshift&nbsp;在数据开头插入一个元素12&nbsp;push&nbsp;在结尾插入一个元素13&nbsp;reduce&nbsp;通过使用用户自定义函数,以字符串返回数组14&nbsp;reverse&nbsp;数据倒序重排15&nbsp;chunk&nbsp;数据分隔为多个数据块16&nbsp;each&nbsp;给数据的每个元素执行回调17&nbsp;filter&nbsp;用回调函数过滤数据中的元素18&nbsp;column&nbsp;返回数据中的指定列19sort对数据排序20&nbsp;order&nbsp;指定字段排序21&nbsp;shuffle&nbsp;将数据打乱22&nbsp;slice&nbsp;截取数据中的一部分23&nbsp;map用回调函数处理数组中的元素24&nbsp;where&nbsp;根据字段条件过滤数组中的元素25&nbsp;whereLikeLike查询过滤元素26&nbsp;whereNotLike&nbsp;Not Like过滤元素27&nbsp;whereIn&nbsp;IN查询过滤数组中的元素28&nbsp;whereNotIn&nbsp;Not IN查询过滤数组中的元素29whereBetween&nbsp;Between查询过滤数组中的元素30whereNotBetweenNot 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),但用法是一致的。