本篇给出了基本的查询用法,更多的查询用法可以参考后续的章节。
## 查询单个数据
查询单个数据使用`find`方法:
~~~
// table方法必须指定完整的数据表名
Db::table('think_user')->where('id', 1)->find();
// 如果设置了数据表前缀(prefix)参数的话 也可以使用
Db::name('user')->where('id', 1)->find();
~~~
>[danger] 即使满足条件的数据有多个,`find`查询也只会返回一条数据。你可以使用`order`排序来决定返回某一条数据。
最终生成的SQL语句可能是(本手册中的示例如未说明均以MySql作为示例):
~~~
SELECT * FROM `think_user` WHERE `id` = 1 LIMIT 1
~~~
> `find `方法查询结果不存在,返回 `null`,否则返回结果数组
如果希望查询数据不存在的时候返回空数组,可以使用
~~~
// table方法必须指定完整的数据表名
Db::table('think_user')->where('id', 1)->findOrEmpty();
~~~
如果希望在没有找到数据后抛出异常可以使用
~~~
Db::table('think_user')->where('id', 1)->findOrFail();
~~~
如果没有查找到数据,则会抛出一个 think\db\exception\DataNotFoundException 异常。
## 查询数据集
查询多个数据(数据集)使用`select`方法:
~~~
$list = Db::table('think_user')->where('status', 1)->select();
foreach ($list as $user) {
echo $user['name'];
}
~~~
最终生成的SQL语句可能是:
~~~
SELECT * FROM `think_user` WHERE `status` = 1
~~~
`select` 方法查询结果是一个数据集对象(`think\Collection`),如果需要转换为(二维)数组可以使用
~~~
$list = Db::table('think_user')->where('status', 1)->select()->toArray();
foreach ($list as $user) {
echo $user['name'];
}
~~~
但通常这是没有必要的,因为数据集对象的操作和数组是几乎一致的。
如果希望在没有查找到数据后抛出异常可以使用
~~~
Db::table('think_user')->where('status',1)->selectOrFail();
~~~
如果没有查找到数据,同样也会抛出一个 think\db\exception\DataNotFoundException 异常。
如果设置了数据表前缀参数的话,可以使用
~~~
Db::name('user')->where('id', 1)->find();
Db::name('user')->where('status', 1)->select();
~~~
>[info] 如果你的数据表没有设置表前缀的话,那么`name`和`table`方法效果一致。
示例只是使用了简单的`where`方法,其实在`find`和`select`方法之前可以使用更多的链式操作(参考后面[链式操作](%E9%93%BE%E5%BC%8F%E6%93%8D%E4%BD%9C.md)章节)方法以完成更多的查询条件。
## 数据集
数据库的`select`查询结果默认返回数据集对象(`think\Collection`),提供了和数组无差别用法,并且另外封装了一些额外的方法。
~~~
// 获取数据集
$users = Db::name('user')->select();
// 遍历数据集
foreach($users as $user){
echo $user['name'];
echo $user['id'];
}
~~~
可以直接使用数组的方式操作数据集对象,例如:
~~~
// 获取数据集
$users = Db::name('user')->select();
// 直接操作第一个元素
$item = $users[0];
// 获取数据集记录数
$count = count($users);
// 遍历数据集
foreach($users as $user){
echo $user['name'];
echo $user['id'];
}
~~~
需要注意的是,如果要判断数据集是否为空,不能直接使用`empty`判断,而必须使用数据集对象的`isEmpty`方法判断,例如:
~~~
$users = Db::name('user')->select();
if($users->isEmpty()){
echo '数据集为空';
}
~~~
`think\Collection`类包含了下列主要方法:
|方法|描述|
|---|---|
|isEmpty|是否为空|
|toArray|转换为数组|
|all|所有数据|
|merge|合并其它数据|
|diff|比较数组,返回差集|
|flip|交换数据中的键和值|
|intersect|比较数组,返回交集|
|keys|返回数据中的所有键名|
|first|返回第一个元素|
|last|返回最后一个元素|
|pop|删除数据中的最后一个元素|
|shift|删除数据中的第一个元素|
|unshift|在数据开头插入一个元素|
|push|在结尾插入一个元素|
|reduce|通过使用用户自定义函数,以字符串返回数组|
|reverse|数据倒序重排|
|chunk|数据分隔为多个数据块|
|each|给数据的每个元素执行回调|
|filter|用回调函数过滤数据中的元素|
|column|返回数据中的指定列|
|sort|对数据排序|
|order|指定字段排序|
|shuffle|将数据打乱|
|slice|截取数据中的一部分|
|map|用回调函数处理数组中的元素|
|where|根据字段条件过滤数组中的元素|
|whereLike|Like查询过滤元素|
|whereNotLike|Not Like过滤元素|
|whereIn|IN查询过滤数组中的元素|
|whereNotIn|Not IN查询过滤数组中的元素|
|whereBetween|Between查询过滤数组中的元素|
|whereNotBetween|Not Between查询过滤数组中的元素|
## 值和列查询
查询某个字段的值可以用
~~~
// 返回某个字段的值
Db::table('think_user')->where('id', 1)->value('name');
~~~
> `value`方法查询结果不存在,返回 null
查询某一列的值可以用
~~~
// 返回数组
Db::table('think_user')->where('status',1)->column('name');
// 指定id字段的值作为索引
Db::table('think_user')->where('status',1)->column('name', 'id');
~~~
如果要返回完整数据,并且添加一个索引值的话,可以使用
~~~
// 指定id字段的值作为索引 返回所有数据
Db::table('think_user')->where('status',1)->column('*','id');
~~~
> `column `方法查询结果不存在,返回空数组
## 数据分批处理
如果你需要处理成千上百条数据库记录,可以考虑使用`chunk`方法,该方法一次获取结果集的一小块,然后填充每一小块数据到要处理的闭包,该方法在编写处理大量数据库记录的时候非常有用。
比如,我们可以全部用户表数据进行分批处理,每次处理 100 个用户记录:
~~~
Db::table('think_user')->chunk(100, function($users) {
foreach ($users as $user) {
// 对100条用户数据进行处理操作
}
});
~~~
你可以通过从闭包函数中返回`false`来中止对后续数据集的处理:
~~~
Db::table('think_user')->chunk(100, function($users) {
foreach ($users as $user) {
// 处理结果集...
if($user->status == 0){
return false;
}
}
});
~~~
也支持在`chunk`方法之前调用其它的查询方法,例如:
~~~
Db::table('think_user')
->where('score','>',80)
->chunk(100, function($users) {
foreach ($users as $user) {
//
}
});
~~~
`chunk`方法的处理默认是根据主键查询,支持指定字段,例如:
~~~
Db::table('think_user')->chunk(100, function($users) {
// 处理结果集...
return false;
},'create_time');
~~~
并且支持指定处理数据的顺序。
~~~
Db::table('think_user')->chunk(100, function($users) {
// 处理结果集...
return false;
},'create_time', 'desc');
~~~
>[danger] `chunk`方法一般用于命令行操作批处理数据库的数据,不适合WEB访问处理大量数据,很容易导致超时。
## 游标查询
如果你需要处理大量的数据,可以使用游标查询功能,该查询方式利用了PHP的生成器特性,可以大幅减少大量数据查询的内存开销问题。
~~~
$list = Db::name('user')->where('status', 1)->cursor();
foreach($list as $user){
echo $user['name'];
}
~~~
`cursor`方法返回的是一个生成器对象,`user`变量是数据表的一条数据(数组)。
- 简介
- 数据库配置
- 分布式数据库
- 查询构造器
- 查询数据
- 新增数据
- 更新数据
- 删除数据
- 链式操作
- Where
- Table
- Alias
- Field
- Strict
- Limit
- Page
- Order
- Group
- Having
- Join
- Union
- Distinct
- Lock
- Cache
- Comment
- FetchSql
- Force
- Partition
- Replace
- FailException
- Extra
- Duplicate
- Sequence
- Procedure
- View
- 聚合查询
- 分页查询
- 时间查询
- 高级查询
- 子查询
- 原生查询
- 事务操作
- 存储过程
- 查询事件
- JSON字段
- 模型
- 定义
- 新增
- 更新
- 删除
- 查询
- 查询范围
- 只读字段
- JSON字段
- 自动时间写入
- 获取器
- 修改器
- 搜索器
- 类型转换
- 模型输出
- 模型事件
- 虚拟模型
- 关联
- 一对一关联
- 一对多关联
- 远程一对多
- 远程一对一
- 多对多关联
- 多态一对多
- 多态一对一
- 关联预载入
- 关联统计
- 关联输出
- SQL监听
- 缓存机制
- 字段缓存
- 查询缓存
- 扩展
- 自定义查询类
- 自定义数据库驱动