博客列表 >7.【TP6学习笔记】数据库链式操作详解

7.【TP6学习笔记】数据库链式操作详解

 一纸荒凉* Armani
 一纸荒凉* Armani原创
2021年05月29日 15:19:151741浏览

ThinkPHP6 数据库链式操作

  • 数据库提供的链式操作方法,可以有效的提高数据存取的代码清晰度和开发效率,并且支持所有的CURD操作

  • 带*标识的表示支持多次调用

连贯操作作用支持的参数类型
where*用于AND查询字符串、数组和对象
table用于定义要操作的数据表名称字符串和数组
name用于定义要操作的数据表名称字符串
field*用于定义要查询的字段(支持字段排除)字符串和数组
order*用于对结果排序字符串和数组
limit用于限制查询结果数量字符串和数字
page用于查询分页(内部会转换成limit)字符串和数字

一、表达式查询

  • 表达式是SQL语句的条件

  • 表达式不分大小写

  • 表达式写在where里

表达式含义
=等于
<>不等于
>大于
>=大于等于
<小于
<=小于等于
[NOT] LIKE模糊查询
[NOT] BETWEEN(不在)区间查询
[NOT] IN(不在)IN 查询
[NOT] NULL查询字段是否(不)是NULL

where查询

  • where方法在链式操作方法里面是最常用的方法,可以完成包括普通查询、表达式查询、快捷查询、区间查询、组合查询在内的条件查询操作

# 等于(=)$select = Db::table('shop_goods')->where('id','=','6')->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','>=','5')->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','<=','5')->select();print_r($select->toArray());# 多where 大于3且小于8 (4 5 6 7)$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 在6到10之间的$select = Db::table('shop_goods')->where('id','between','6,10')->select();print_r($select->toArray());# NOT BETWEEN 除了6到10以外的$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('goods')->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,    'dicount' => 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(6,5)            ->select();print_r($select->toArray());
  • page方法主要用于分页查询

$select = Db::table('shop_goods')            ->field('title,price,id')            ->where('status',1)            ->order('price','DESC')            ->page(2,5)            ->select();print_r($select->toArray());

六、聚合查询

  • 聚合方法如果没有数据,默认都是0,聚合查询都可以配合其它查询条件

方法功能
count统计数量,参数是要统计的字段名(可选)
max获取最大值,参数是要统计的字段名(必须)
min获取最小值,参数是要统计的字段名(必须)
avg获取平均值,参数是要统计的字段名(必须)
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'] : 0    ]);    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">&#xe615;</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;    }    // 获取当前页数    $page = isset($param['page']) ? $param['page'] : 1;    // 统计总条数    $count = Db::table('shop_goods')->where($where)->count();    // 每页条数    $num = 6;    $list = Db::table('shop_goods')                ->where($where)                ->order('add_time DESC')                ->order('id DESC')                ->page($page,$num)                ->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/$num),        'page' => $page,        'status' => isset($param['status']) ? $param['status'] : 0    ]);    return View::fetch();}

view代码

<div class="layui-box layui-laypage layui-laypage-default">    <a href="{if $page<=1}javascript:;{else/}?page={$page-1}&status={$status}{/if}" class="layui-laypage-prev {if $page<=1}layui-disabled{/if}">上一页</a>    {for start="0" end="$count"}        {if $page == $i+1}            <span class="layui-laypage-curr">                <em class="layui-laypage-em"></em>                <em>{$i+1}</em>            </span>        {else/}            <a href="?page={$i+1}&status={$status}">{$i+1}</a>        {/if}    {/for}    <a href="{if $page>=$count}javascript:;{else/}?page={$page+1}&status={$status}{/if}" class="layui-laypage-next {if $page>=$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>';}// 生成分页的html代码可以传给视图print_r($select->render());echo '<hr>';print_r('总数:'.$select->total());echo '<hr>';View::assign([    'paginate' => $select,    'render'=> $select->render(),    'list' => $select->data()]);return View::fetch();

view代码

<!-- 视图中生成分页html代码 --><div>{$paginate|raw}</div><!-- 控制器传递过来的分页html代码 --><div>{$render}</div>

css代码  内置分页采用的是bootstrap分页组件,我们需要引入分页条样式

.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当前页
pathurl路径
queryurl额外参数
fragmenturl锚点
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;    }    $page = isset($param['page']) ? $param['page'] : 1;    # thinkphp 自带分页    $list = Db::table('shop_goods')            ->where($where)            ->order('add_time DESC')            ->order('id DESC')            ->paginate([                'list_rows'=> 6,                'query' => Request::param()            ]);    $right = $list->toArray();    foreach($right['data'] 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['data'],        // 注意:paginate查询出的对象中data才是我们的数据        'paginate' => $list,        // 这里需要将data中数据抽离给前端渲染列表,是因为我们将结果对象转换为了数组,默认是不需要这样的,直接将paginate查询结果传递过去即可,和之前的select一样操作        'status' => isset($param['status']) ? $param['status'] : 0    ]);    return View::fetch();}

view代码

// $paginate中数据为paginate()查询出的,|raw<div>{$paginate|raw}</div>

十一、SQL 调试

  • getLastSql输出上次执行的sql语句

  • getLastSql方法只能获取最后执行的 SQL 记录

$select = Db::table('shop_goods')->select();// 查询结果对象print_r($select);echo Db::getLastSql();// SELECT * FROM `shop_goods` 为上一次执行的SQL语句
  • fetchSql方法直接返回当前的 SQL 而不执行

$select = Db::table('shop_goods')->field('*')->order('id desc')->fetchSql()->select();echo $select;// SELECT * FROM `shop_goods` ORDER BY `id` DESC 查询语句不会被执行,而是直接输出

十二、动态配置数据库

  • config目录database.php文件

use think\facade\Env;return [    'connections' => [        'zhang' => [            // 数据库类型            'type'              => Env::get('database.type', 'mysql'),            // 服务器地址            'hostname'          => Env::get('database.hostname', '127.0.0.1'),            // 数据库名            'database'          => 'mydb',            // 用户名            '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,        ]    ]];
  • mydb数据库中的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('zhang')->table('shop_user')->select();

connect方法必须在查询的最开始调用,而且必须紧跟着调用查询方法,否则可能会导致部分查询失效或者依然使用默认的数据库连接

十三、WHRER 链式操作(不常用)

  • 和查询表达式功能一样,ThinkPHP 提供以下快捷查询方法

连贯操作作用支持的参数类型
whereOr*用于OR查询字符串、数组和对象
whereLike*模糊查询字符串
whereNotLike*模糊查询字符串
whereBetween*区间查询字符串
whereNotBetween*不在区间查询字符串
whereIn*IN查询字符串
whereNotIn*不在IN查询字符串
whereNull*查询字段是否是NULL字符串
whereNotNull*查询字段是否不是NULL字符串
whereExists*EXISTS查询字符串
whereNotExists*不在EXISTS查询字符串
whereBetweenTime*时间区间比较字符串
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用于设置分区信息数组 字符串
failException用于设置没有查询到数据是否抛出异常布尔值
sequence用于设置自增序列名字符串
replace用于设置使用REPLACE方式写入布尔值
extra用于设置额外查询规则字符串
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方法操作数据库事务,当闭包中的代码发生异常会自动回滚

Db::transaction(function () {    $data = ['cat'=>'1','title'=>'日系小浪漫与温暖羊毛针织拼接网纱百褶中长收腰连衣裙','price'=>'1598.35','add_time'=>1576080000];    $insert = Db::table('shop_goods')->insert($data);});

十六、数据集

  • 数据库通过select查询,得到的数据集对象

  • 返回的数据集对象是think\Collection,提供了和数组无差别用法,并且另外封装了一些额外的方法

编号方法描述
1isEmpty是否为空
2toArray转换为数组
3all所有数据
4merge合并其它数据
5diff比较数组,返回差集
6flip交换数据中的键和值
7intersect比较数组,返回交集
8keys返回数据中的所有键名
9pop删除数据中的最后一个元素
10shift删除数据中的第一个元素
11unshift在数据开头插入一个元素
12push在结尾插入一个元素
13reduce通过使用用户自定义函数,以字符串返回数组
14reverse数据倒序重排
15chunk数据分隔为多个数据块
16each给数据的每个元素执行回调
17filter用回调函数过滤数据中的元素
18column返回数据中的指定列
19sort对数据排序
20order指定字段排序
21shuffle将数据打乱
22slice截取数据中的一部分
23map用回调函数处理数组中的元素
24where根据字段条件过滤数组中的元素
25whereLikeLike查询过滤元素
26whereNotLikeNot Like过滤元素
27whereInIN查询过滤数组中的元素
28whereNotInNot IN查询过滤数组中的元素
29whereBetweenBetween查询过滤数组中的元素
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),但用法是一致的。

声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议