首页 » PHP » 正文

thinkphp5学习笔记(5)

本章查询内容均配置了数据表前缀 think_ ,因此统一使用 Db 类的 name 方法代替 table 方法进行举例说明。

查询表达式

最普通的查询就是判断某个字段是否等于某个值,例如,我们查询 think_data 数据表中 id 等于1的数
据,用法如下:

$result = Db::name('data')
->where('id', 1)
->find();
dump($result);

新手注意,如果没有使用 use 引入 Db 类的话 需要使用:

$result = \think\Db::name('data')
->where('id', 1)
->find();
dump($result);
find 方法用于查找满足条件第一个记录(即使你的查询条件有多个符合的数据),如果查询成功,返回的是一个一维数组,没有满足条件的话则默认返回 null (也支持设置是否抛出异常)。

生成的SQL语句是:
SELECT * FROM `think_data` WHERE `id` = 1
上述的查询其实等同于:

$result = Db::name('data')
->where('id', '=', 1)
->find();
dump($result);

使用表达式查询的时候,where方法的参数依次为:

where( 字段名,条件表达式,查询值 )

qq%e5%9b%be%e7%89%8720161207104106

下面就来查询 id 大于等于1的数据,使用如下代码:

$result = Db::name('data')
->where('id', '>=', 1)
->limit(10)
->select();
dump($result);

因为这里需要返回多条记录,因此这里我们使用了 select 方法,并且使用 limit 方法限制了返回的最多
记录数。

select 方法用于查询数据集,如果查询成功,返回的是一个二维数组,如果没有满足条件的话则返回空
数组(也支持设置是否需要抛出异常)。

生成的SQL语句是:
SELECT * FROM `think_data` WHERE `id` >= 1 LIMIT 10

如果使用EXP条件表达式的话,表示后面是原生的SQL语句表达式,例如上面的查询可以改成:

$result = Db::name('data')
->where('id', 'exp', '>= 1')
->limit(10)
->select();
dump($result);

生成的SQL语句和前面是一样的。

如果要查询id的范围,可以使用

$result = Db::name('data')
// id 是 1、2、3 其中的数字
->where('id', 'in', [1, 2, 3])
->select();
dump($result);

生成的SQL语句是:
SELECT * FROM `think_data` WHERE `id` IN (1,2,3)
或者

$result = Db::name('data')
// id 在 5到8之间的
->where('id', 'between', [5, 8])
->select();
dump($result);

生成的SQL语句是:
SELECT * FROM `think_data` WHERE `id` BETWEEN 5 AND 8

接下来,使用多个字段查询:

$result = Db::name('data')
// id 在 1到3之间的
->where('id', 'between', [1, 3])
// name 中包含think
->where('name', 'like', '%think%')
->select();
dump($result);

这样生成的查询语句为:
SELECT * FROM `think_data` WHERE `id` BETWEEN 1 AND 3 AND `name` LIKE ‘%think%’
如果要查询某个字段是否为 NULL ,可以使用:

$result = Db::name('data')
->where('name', 'null')
->select();
dump($result);

这样生成的查询语句为:
SELECT * FROM `think_data` WHERE `name` IS NULL

批量查询

我们可以使用一个方法完成多个查询条件,例如上面的查询可以改成:

$result = Db::name('data')
->where([
'id' => ['between', '1,3'],
'name' => ['like', '%think%'],
])->select();
dump($result);

这样生成的查询语句还是和之前一样:
SELECT * FROM `think_data` WHERE `id` BETWEEN ‘1’ AND ‘3’ AND `name` LIKE ‘%think%’
我们再来看一些复杂的用法,使用 OR 和 AND 混合条件查询,例如:

$result = Db::name('data')
// name 中包含think
->where('name', 'like', '%think%')
->where('id', ['in', [1, 2, 3]], ['between', '5,8'], 'or')
->select();
dump($result);

或者使用批量方式:

$result = Db::name('data')
->where([
'id' => [['in', [1, 2, 3]], ['between', '5,8'], 'or'],
'name' => ['like', '%think%'],
])->limit(10)->select();
dump($result);

生成的SQL语句为:
SELECT * FROM `think_data` WHERE ( `id` IN (1,2,3) or `id` BETWEEN ‘5’ AND ‘8’ ) AND `n
ame` LIKE ‘%think%’ LIMIT 10

快捷查询

如果你有多个字段需要使用相同的查询条件,可以使用快捷查询。例如,我们要查询id和status都大于0的数
据,可以使用:

$result = Db::name('data')
->where('id&status', '>', 0)
->limit(10)
->select();
dump($result);

生成的SQL语句为:
SELECT * FROM `think_data` WHERE ( `id` > 0 AND `status` > 0 ) LIMIT 10
也可以使用or方式查询,例如:

$result = Db::name('data')
->where('id|status', '>', 0)
->limit(10)
->select();
dump($result);

生成的SQL语句为:
SELECT * FROM `think_data` WHERE ( `id` > 0 OR `status` > 0 ) LIMIT 10

视图查询

如果需要快捷查询多个表的数据,可以使用视图查询,相当于在数据库创建了一个视图,但仅仅支持查询操作,例如:

$result = Db::view('user','id,name,status')
->view('profile',['name'=>'truename','phone','email'],'profile.user_id=user.id')
->where('status',1)
->order('id desc')
->select();
dump($result);

生成的SQL语句为:
SELECT user.id,user.name,user.status,profile.name AS truename,profile.phone,profile.ema
il FROM think_user user INNER JOIN think_profile profile ON profile.user_id=user.id WHE
RE user.status = 1 order by user.id desc

闭包查询

find 和 select 方法可以直接使用闭包查询:

$result = Db::name('data')->select(function ($query) {
$query->where('name', 'like', '%think%')
->where('id', 'in', '1,2,3')
->limit(10);
});
dump($result);

生成的SQL语句是:
SELECT * FROM `think_data` WHERE `name` LIKE ‘%think%’ AND `id` IN (‘1′,’2′,’3’) LIMIT
10

使用Query对象
也可以事先封装Query对象,并传入select方法,例如:

$query = new \think\db\Query;
$query->name('city')->where('name', 'like', '%think%')
->where('id', 'in', '1,2,3')
->limit(10);
$result = Db::select($query);
dump($result);

使用 Query 对象的话, select 方法之前调用的任何的链式操作都是无效。

获取数值
如果仅仅是需要获取某行表的某个值,可以使用 value 方法:

// 获取id为8的data数据的name字段值
$name = Db::name('data')
->where('id', 8)
->value('name');
dump($name);

name的结果为: thinkphp

获取列数据

也支持获取某个列的数据,使用 column 方法,例如:

// 获取data表的name列
$list = Db::name('data')
->where('status', 1)
->column('name');
dump($list);
<pre>
返回的结果类似下面:
<pre lang="php">
array (size=5)
0 => string 'thinkphp'
1 => string 'onethink'
2 => string 'topthink'
3 => string 'kancloud'

如果希望返回以id为索引的name列数据,可以改成:

// 获取data表的name列 并且以id为索引
$list = Db::name('data')
->where('status', 1)
->column('name', 'id');
dump($list);

返回的结果类似下面:

array (size=5)
1 => string 'thinkphp'
2 => string 'onethink'
3 => string 'topthink'
4 => string 'kancloud'

如果需要返回以主键为索引的数据集,可以使用:

// 获取data表的name列 并且以id为索引
$list = Db::name('data')
->where('status', 1)
->column('*', 'id');
dump($list);

返回:

array (size=5)
1 => array (size=3)
'id' => int 1
'name' => string 'thinkphp'
'status'=> int 1
2 => array (size=3)
'id' => int 1
'name' => string 'onethink'
'status'=> int 1
3 => array (size=3)
'id' => int 1
'name' => string 'topthink'
'status'=> int 1
4 => array (size=3)
'id' => int 1
'name' => string 'kancloud'
'status'=> int 1

聚合查询

thinkphp为聚合查询提供了更便捷的方法,如下:

// 统计data表的数据
$count = Db::name('data')
->where('status', 1)
->count();
dump($count);
// 统计user表的最高分
$max = Db::name('user')
->where('status', 1)
->max('score');
dump($max);

qq%e5%9b%be%e7%89%8720161207104106

字符串查询

在必要的时候,仍然可以使用原生的字符串查询,但建议是配合参数绑定一起使用,可以避免注入问题,例
如:

$result = Db::name('data')
->where('id > :id AND name IS NOT NULL', ['id' => 10])
->select();
dump($result);

可以直接在 where 方法中使用字符串查询条件,并支持第二个参数传入参数绑定,上面这个查询生成的SQL
语句是:SELECT * FROM `think_data` WHERE ( id > ’10’ AND name IS NOT NULL )

时间(日期)查询

首先需要在 think_data 数据表新增 create_time 字段,用于日期查询的字段类型推荐使用datetime 类型。

ThinkPHP5.0 的查询语言强化了对时间日期查询的支持,例如:

// 查询创建时间大于2016-1-1的数据
$result = Db::name('data')
->whereTime('create_time', '>', '2016-1-1')
->select();
dump($result);
// 查询本周添加的数据
$result = Db::name('data')
->whereTime('create_time', '>', 'this week')
->select();
dump($result);
// 查询最近两天添加的数据
$result = Db::name('data')
->whereTime('create_time', '>', '-2 days')
->select();
dump($result);
// 查询创建时间在2016-1-1~2016-7-1的数据
$result = Db::name('data')
->whereTime('create_time', 'between', ['2016-1-1', '2016-7-1'])
->select();
dump($result);

日期查询对 create_time 字段类型没有要求,可以是 int/string/timestamp/datetime/date 中的
任何一种,系统会自动识别进行处理。
还可以使用下面的人性化日期查询方式,例如:

// 获取今天的数据
$result = Db::name('data')
->whereTime('create_time', 'today')
->select();
dump($result);
// 获取昨天的数据
$result = Db::name('data')
->whereTime('create_time', 'yesterday')
->select();
dump($result);
// 获取本周的数据
$result = Db::name('data')
->whereTime('create_time', 'week')
->select();
dump($result);
// 获取上周的数据
$result = Db::name('data')
->whereTime('create_time', 'last week')
->select();
dump($result);

分块查询

分块查询是为查询大量数据的需要而设计的,假如 think_data 表已经有超过1万条记录,但是一次性取那
么大的数据会导致内存开销非常之大,但确实又有这个需要(例如查询所有的数据并导出到 excel ),采用
分块查询可以缓解这个问题。
使用分块查询,可以把1万条记录分成 100 次处理,每次处理 100 条记录,代码示例如下:

Db::name('data')
->where('status', '>', 0)
->chunk(100, function ($list) {
// 处理100条记录
foreach($list as $data){
}
});

第二个参数可以是有效的 callback 类型,包括使用闭包函数。
系统会按照主键顺序查询,每次查询 100 条,如果你不希望使用主键进行查询,或者没有主键的话,则需要
指定查询的排序字段(但必须是唯一的),例如:

Db::name('user')
->where('status', '>', 0)
->chunk(100, function ($list) {
// 处理100条记录
foreach($list as $data){
}
}, 'uid');

然后交给 callback 进行数据处理,处理完毕后继续查询下一个 100 条记录,如果你需要在中途中断后续
的查询,只需要在 callback 方法调用中返回 false 即可,例如:

Db::name('data')
->where('status','>',0)
->chunk(100,function($list){
foreach($list as $data){
// 返回false则中断后续查询
return false;
}
});
博主的文章或程序如果给您带来了价值,感谢您打赏一二
微信扫码支付 支付宝扫码支付

发表评论