数据库的时间查询
传统方式
- 可以使用
>,<,>=,<=来筛选匹配时间的数据; 
Db::name('user')->where('create_time', '>', '2018-1-1')->select();
- 可以使用
between关键字来设置时间的区间; 
Db::name('user')->where('create_time', 'between', ['2018-1-1','2019-12-31'])->select();
Db::name('user')->where('create_time', 'not between', ['2018-1-1','2019-12-31'])->select();
快捷方式
- 时间查询的快捷方法为
whereTime(),直接使用>,<,>=,<=; 
Db::name('user')->whereTime('create_time', '>', '2018-1-1')->select();
- 快捷方式也可以使用
between和not between; 
Db::name('user')->whereBetween('create_time', ['2018-1-1','2019-12-31'])->select();
- 还有一种快捷方式为:
whereBetweenTime()和whereNotBetweenTime(); 
Db::name('user')->whereBetweenTime('create_time', '2018-1-1','2019-12-31')->select();
- 默认的大于
>,可以省略; 
Db::name('user')->whereTime('create_time', '2018-1-1')->select();
固定查询
- 使用
whereYear查询今年的数据,去年的数据和某一年的数据 
Db::name('user')->whereYear('create_time')->select();
Db::name('user')->whereYear('create_time', 'last year')->select();
Db::name('user')->whereYear('create_time', '2016')->select();
- 使用
whereMonth查询当月的数据,上月的数据和某一个月的数据; 
Db::name('user')->whereMonth('create_time')->select();
Db::name('user')->whereMonth('create_time', 'last month')->select();
Db::name('user')->whereMonth('create_time', '2016-6')->select();
- 使用
whereDay查询今天的数据,昨天的数据和某一个天的数据; 
Db::name('user')->whereDay('create_time')->select();
Db::name('user')->whereDay('create_time', 'last day')->select();
Db::name('user')->whereDay('create_time', '2016-6-27')->select();
其它查询
- 查询指定时间的数据,比如两小时内的;
 
Db::name('user')->whereTime('create_time', '-2 hours')->select();
- 查询两个时间字段时间有效期的数据,比如会员开始到结束的期间;
 
Db::name('user')->whereBetweenTimeField('start_time','end_time')->select();
聚合.原生.子查询
聚合查询
- 使用
count方法,可以求出所查询数据的数量; 
Db::name('user')->count();
count()可设置指定id,比如有空值Null的uid,不会计算数量;
Db::name('user')->count('uid');
- 使用
max方法,求出所查询数据字段的最大值; 
Db::name('user')->max('price');
- 如果
max方法,求出的值不是数值,则通过第二参数强制转换; 
Db::name('user')->max('price', false);
- 使用
min方法,求出所查询数据字段的最小值,也可以强制转换; 
Db::name('user')->min('price');
- 使用
avg方法,求出所查询数据字段的平均值; 
Db::name('user')->avg('price');
- 使用
sum方法,求出所查询数据字段的总和; 
Db::name('user')->sum('price');
子查询
- 使用
fetchSql方法,可以设置不执行SQL,而返回SQL语句,默认true; 
Db::name('user')->fetchSql(true)->select();

- 使用
buildSql方法,也是返回SQL语句,不需要再执行select(),且有括号; 
Db::name('user')->buildSql(true);

- 结合以上方法,我们实现一个子查询;
 
$subQuery = Db::name('two')->field('uid')->where('gender','男')->buildSql(true);
$result = Db::name('one')->where('id','exp','IN '.$subQuery)->select();

- 使用闭包的方式执行子查询;
 
$result = Db::name('one')->where('id', 'in', function ($query) {
    $query->name('two')->where('gender', '男')->field('uid');
})->select();
原生查询
- 使用
query方法,进行原生SQL查询,适用于读取操作,SQL错误返回false; 
Db::query('select * from tp_user');
- 使用
execute方法,进行原生SQL更新写入等,SQL错误返回false; 
Db::execute('update tp_user set username="孙悟空" where id=29');
链式查询方法
where
- 表达式查询,就是
where()方法的基础查询方式; 
Db::name('user')->where('id', '>', 70)->select();
- 关联数组查询,通过键值对来数组键值对匹配的查询方式;
 
$user = Db::name('user')->where([
'gender' => '男',
'price' => 100 ,
//'price' => [60,70,80],
])->select();
- 索引数组查询,通过数组里的数组拼装方式来查询;
 
$user = Db::name('user')->where([
['gender', '=', '男'],
['price', '=', '100']
])->select();
- 将复杂的数组组装后,通过变量传递,将增加可读性;
 
$map[] = ['gender', '=', '男'];
$map[] = ['price', 'in', [60, 70, 80]];
$user = Db::name('user')->where($map)->select();
- 字符串形式传递,简单粗暴的查询方式,
whereRaw()支持复杂字符串格式; 
Db::name('user')->whereRaw('gender="男" AND price IN (60, 70, 80)')->select();
- 如果SQL查询采用了预处理模式,比如
id=:id,也能够支持; 
Db::name('user')->whereRaw('id=:id', ['id'=>19])->select();
field
- 使用
field方法,可以指定要查询的字段; 
Db::name('user')->field('id, username, email')->select();
Db::name('user')->field(['id', 'username', 'email'])->select();
- 使用
field方法,给指定的字段设置别名; 
Db::name('user')->field('id,username as name')->select();
Db::name('user')->field(['id', 'username'=>'name'])->select();
- 在
fieldRaw方法里,可以直接给字段设置MySQL函数; 
Db::name('user')->fieldRaw('id,SUM(price)')->select();
- 使用
field(true)的布尔参数,可以显式的查询获取所有字段,而不是*; 
Db::name('user')->field(true)->select();

- 使用
withoutField方法中字段排除,可以屏蔽掉想要不显示的字段; 
Db::name('user')->withoutField('details')->select();
- 使用
field方法在新增时,验证字段的合法性; 
Db::name('user')->field('username, email, details')->insert($data);
alias
- 使用
alias方法,给数据库起一个别名; 
Db::name('user')->alias('a')->select();

limit
- 使用
limit()方法,限制获取输出数据的个数; 
Db::name('user')->limit(5)->select();
- 分页模式,即传递两个参数,比如从第3条开始显示5条
limit(2,5); 
Db::name('user')->limit(2, 5)->select();
- 实现分页,需要严格计算每页显示的条数,然后从第几条开始;
 
//第一页
Db::name('user')->limit(0, 5)->select();
//第二页
Db::name('user')->limit(5, 5)->select();

page
page()分页方法,优化了limit()方法,无须计算分页条数;
//第一页
Db::name('user')->page(1, 5)->select();
//第二页
Db::name('user')->page(2, 5)->select();

order
- 使用
order()方法,可以指定排序方式,没有指定第二参数,默认asc; 
Db::name('user')->order('id', 'desc')->select();
- 支持数组的方式,对多个字段进行排序;
 
Db::name('user')->order(['create_time'=>'desc', 'price'=>'asc'])->select();
- 使用
orderRaw()方法,支持排序的时候指定MySQL函数; 
Db::name('user')->orderRaw('FIELD(username,"樱桃小丸子") DESC')->select();

group
- 使用
group()方法,给性别不同的人进行price字段的总和统计; 
Db::name('user')->fieldRaw('gender, SUM(price)')->group('gender')->select();

- 也可以进行多字段分组统计;
 
Db::name('user')->fieldRaw('gender, SUM(price)')->group('gender,password')->select();

having
- 使用
group()分组之后,再使用having()进行筛选; 
$result = Db::name('user')
->fieldRaw('gender, SUM(price)')
->group('gender')
->having('SUM(price)>600')
->select();

数据库的高级查询
高级查询
- 使用
|(OR)或&(AND)来实现where条件的高级查询,where支持多个连缀; 
$result = Db::name('user')
->where('username|email', 'like', '%xiao%')
->where('price&uid', '>', 0)
->select();

- 关联数组方式,可以在
where进行多个字段进行查询; 
$result = Db::name('user')->where([
['id', '>', 0],
['status', '=', 1],
['price', '>=', 80],
['email', 'like', '%163%']
])->select();

- 根据之前的课程中,条件字符串复杂组装,比如使用
exp了,就使用raw()方法; 
$result = Db::name('user')->where([
['status', '=', 1],
['price', 'exp', Db::raw('>80')]
])->select();

- 如果有多个
where,并且where条件是分离的$map,而$map本身有多个条件; - 那么
$map条件如果需要先执行出结果,再和后续条件判断,也就是加上括号; - 那么,需要对这个
$map变量,再加上一个中括号处理优先级; 
$map = [
['status', '=', 1],
['price', 'exp', Db::raw('>80')]
];
$result = Db::name('user')
->where([$map])
->where('status', '=', '%163.com%')->select();

- 如果,条件中有多次出现一个字段,并且需要 OR 来左右筛选,可以用 whereOr;
 
$map1 = [
['username', 'like', '%小%'],
['email', 'like', '%163%']
];
$map2 = [
['username', 'like', '%孙%'],
['email', 'like', '%.com%']
];
$result = Db::name('user')->whereOr([$map1, $map2])->select();

- 闭包查询可以连缀,会自动加上括号,更清晰,如果是 OR,请用 whereOR();
 
$result = Db::name('user')->where(function ($query) {
$query->where('id', '>', 10);
})->whereOr(function ($query) {
$query->where('username', 'like', '%小%');
})->select();

- 对于比较复杂或你不知道如何拼装 SQL 条件,那么就直接使用 whereRaw()即可;
 
$result = Db::name('user')
->whereRaw('(username LIKE "%小%" AND email LIKE "%163%") OR (price > 80)')
->select();

- whereRaw()方式也支持参数绑定操作,具体如下;
 
$result = Db::name('user')
->whereRaw('(username LIKE :username AND email LIKE :email)
OR (price > :price)',
['username'=>'%小%', 'email'=>'%163%', 'price'=>80])
->select();

数据库的快捷查询
快捷查询
- 系统封装了很多
where方法的快捷方式,之前学习了一些,全部如下: 

whereColumn()方法,比较两个字段的值,符合的就筛选出来;
$result = Db::name('user')
->whereColumn('update_time', '>=', 'create_time')
->select();
//相等可以简化,只需要两边的字段
// whereColumn('update_time', 'create_time')

- 系统还针对字段查询提供了几个方便查询的快捷方式;
 whereFieldName()方法,查询某个字段的值,注意FileName是字段名;
Db::name('user')->whereEmail('xiaoxin@163.com')->find();
Db::name('user')->whereUsername('蜡笔小新')->find();
//如果字段是 create_time,则 whereCreateTime,驼峰式写法;

getByFieldName()方法,查询某个字段的值,注意只能查询一条,不需要find();
Db::name('user')->getByEmail('xiaoxin@163.com');

getFieldByFieldName()方法,通过查询得到某个指定字段的单一值;
Db::name('user')->getFieldByEmail('xiaoxin@163.com', 'username');

其它补充
- when()可以通过条件判断,执行闭包里的分支查询;
 
$result = Db::name('user')->when(false, function ($query) {
$query->where('id', '>', 0);
}, function ($query) {
$query->where('username', 'like', '%小%');
})->select();

数据库的事务和获取器
事务处理
- 数据库的表引擎需要是
InnoDB才可以使用,如果不是调整即可; - 事务处理,需要执行多个SQL查询,数据是关联恒定的;
 - 如果成功一条查询,改变了数据,而后一条失败,则前面的数据回滚;
 - 比如:蜡笔小新给路飞3快钱,自己-3,对方+3,这时需要事务处理;
 - 系统提供了两种事务处理的方式,第一种是自动处理,出错自动回滚;
 
Db::transaction(function () {
    Db::name('user')->where('id', 19)->save(['price'=>Db::raw('price - 3')]);
    Db::name('user1')->where('id', 20)->save(['price'=>Db::raw('price + 3')]);
});
- 手动处理,基本和原生处理类似,可以自行输出错误信息;
 
//启动事务
Db::startTrans();
try {
    Db::name('user')->where('id', 19)->save(['price'=>Db::raw('price - 3')]);
    Db::name('user1')->where('id', 20)->save(['price'=>Db::raw('price + 3')]);
    //提交事务
    Db::commit();
} catch (\Exception $e) {
    echo '执行 SQL 失败!';
    //回滚
    Db::rollback();
}
获取器
- 获取器的意思就是:将数据的字段进行转换处理再进行操作;
 - 比如在获取数据列表的时候,将获取到的邮箱字段全部大写;
 
$user = Db::name('user')->withAttr('email', function ($value, $data) {
    return strtoupper($value);
})->select();
echo json($user);

数据库的数据集和代码提示
代码提示
- 一般来说,代码提示是通过注释来告知编辑器自动补全方法等;
 - 对比一下,5.1的类库,发现6.x的类库没有写注释;
 - 就拿Db类来说,只要把5.1的注释覆盖到6.x即可实现代码提示;
 - 当然,是否精确,需要一一对比这些方法和参数,但绝大多数是相同的;
 - 找到 Db 类,看它的注释:@see指向的是谁,是DbManager类;
 - 然后将5.1的Db类注释,复制给DbManager类即可,以后其它的雷同操作;
 
数据集
- 所谓数据集,是当查询后的结果集,它是
think\Collection类型和数组一样; - 虽然操作和数组类似,但它额外提供了一些方法,方法如下:
 


- 注意:这里的方法关键字某些和数据库查询类似,但它是数据集操作的方法;
 - 由于方法较多,我们尝试几个理解一下即可,有需要可以回头查阅;
 

- 每种的典型,都拎出来说明了一下;
 - 其它的方法,可以通过追逐方法查阅注释和参数来参考使用
 
 
           最后一次更新于2020-07-23 15:05         
 
        
Alipay
Wechat
           
           
   
  
0 条评论