thinkphp笔记-数据库查询
普通查询
比如有这么一个数据表
id | username | password | |
---|---|---|---|
19 | 蜡笔小新 | 123 | xxx |
20 | 路飞 | 321 | xxx |
21 | 黑崎一护 | 1234 | xxx |
25 | 孙悟饭 | 6543 | xxx |
单数据查询
Db::table()中table 必须指定完整数据表(包括前缀)。
use think\facade\Db;
// 找到tp_user数据表中,id=27的数据
$user = Db::table('tp_user')->where('id', 27)->find();
如果希望只查询一条数据,可以使用find()方法,需指定where 条件;支持链式查询可以一直往后写。
find()方法如果没有查询到任何值,则返回null;
Db::getLastSql()方法,可以得到最近一条SQL 查询的原生语句;
$user = Db::table('tp_user')->where('id', 27)->find();
return Db::getLastSql();
// SELECT * FROM `tp_user` WHERE `id` = 27 LIMIT 1
使用findOrFail()方法同样可以查询一条数据,在没有数据时抛出一个异常;
$user=Db::table('tp_user')->where('id',524)->findOrFail();
使用findOrEmpty()方法也可以查询一条数据,但在没有数据时返回一个空数组;
$user=Db::table('tp_user')->where('id',524)->findOrEmpty();
数据集查询
想要获取多列数据,可以使用select()方法;
$user = Db::table('tp_user')->select();
多列数据在查询不到任何数据时返回空数组:
$user = Db::table('tp_user')->where('status', 5)->select();
使用selectOrFail()在查询不到数据的时候,会抛出异常(注意没有selectOrEmpty方法!!默认的就是没有返回空数组!)
$user = Db::table('tp_user')->where('status', 5)->selectOrFail();
在select()方法后再使用toArray()方法,可以将数据集对象转化为数组;
$user = Db::table('tp_user')->select();
dump($user);
// 此时得到是一个数据集对象
$user = Db::table('tp_user')->select()->toArray();
dump($user);
// 此时将对象转化为二维数组了
当在数据库配置文件中设置了前缀,那么我们可以使用name()方法忽略前缀;
$user = Db::name('user')->select()->toArray();
总结,使用Db::table('必须完整的表名');Db::name('如果config/database和.env中设置了前缀,那么可以只输入去掉前缀的部分'),表全名:tp_user,这里就可以仅仅使用Db::name('user')
其他查询
通过value()方法,可以查询指定字段的值(单个),没有数据返回null;
$user = Db::table('tp_user')->where('id', 27)->value('username');
->value(‘数据表的字段名称’)
通过colunm()方法,可以查询指定列的值(多个),没有数据返回空数组(即把username字段中所有值都输出出来);
$user = Db::name('user')->column('username');
输出的是一个数组:
[
"蜡笔小新",
"路飞",
"黑崎一护",
"小明",
"孙悟饭",
"孙悟天",
"樱桃小丸子",
"孙悟空",
"李白",
"辉夜",
"李黑"
]
可以指定id 作为列值的索引;
$user = Db::name('user')->column('username', 'id');
最终输出一个:
{
19: "蜡笔小新",
20: "路飞",
21: "黑崎一护",
24: "小明",
25: "孙悟饭",
26: "孙悟天",
27: "樱桃小丸子",
29: "孙悟空",
76: "李白",
79: "辉夜",
301: "李黑"
}
大量数据查询-chunk
如果处理的数据量巨大,成百上千那种,一次性读取有可能会导致内存开销过大,为了避免内存处理太多数据出错,可以使用chunk()方法分批处理数据,即每次处理几百条(100~200),处理完了我再去处理个几百条,而不是一次性处理几千条、上万条。比如,每次只处理100 条,处理完毕后,再读取100 条继续处理;
// 每次读3条,用一个匿名函数处理,参数$users就是所有的数据,然后用循环遍历
Db::name('user')->chunk(3, function($users) {
foreach($users as $user) {
dump($user);
}
echo 1;
});
可以使用tp调试模式自带的性能检测窗口,查看这种处理方式占用的内存等信息,与一口气读取进行一个比较。
大量数据查询-游标查询
可以利用游标查询功能,可以大幅度减少海量数据的内存开销,它利用了PHP 生成器特性(5.5之后才有)。每次查询只读一行,然后再读取时,自动定位到下一行继续读取;
生成器介绍:https://www.php.net/manual/zh/language.generators.overview.php
使用场景:https://www.cnblogs.com/johnson108178/p/8007585.html
// 先创建一个游标对象,然后再遍历,
$cursor = Db::name('user')->cursor();
foreach($cursor as $user) {
dump($user);
}
链式查询
通过指向符号“->”多次连续调用方法称为:链式查询;
当Db::name('user')时,返回查询对象(Query),即可连缀数据库对应的方法,而每次执行一个数据库查询方法时,比如where(),还将返回查询对象(Query),只要还是数据库对象,那么就可以一直使用指向符号进行链式查询;
最终用find()、select()等方法返回数组(Array)或数据集对象(Colletion);
而find()和select()是结果查询方法(放在最后),并不是链式查询方法;
$user = Db::name('user')->where('id', 27)->order('id', 'desc')->find(); // 返回数组对象
$user = Db::name('user')->where('id', 27)->order('id', 'desc')->select(); // 返回数据集对象
使用dump($user)就可以打印出来,查看对象的类型。find输出得到是array,select()得到的是think\Collection
链式查询官方APIhttps://www.kancloud.cn/manual/thinkphp6_0/1037538
如果多次使用数据库查询,那么每次静态创建都会生成一个实例,造成浪费,我们可以把对象实例保存下来,再进行反复调用即可;
$userQuery = Db::name('user');
$dataFind = $userQuery->where('id', 27)->find();
$dataSelect = $userQuery->select();
但是,当同一个对象实例第二次查询后,会保留第一次查询的值;比如,
$data1 = $userQuery->order('id', 'desc')->select();
// 按理说$data1的查询语句应该是:SELECT * FROM `tp_user` ORDER BY `id` DESC
$data2 = $userQuery->select();
// $data2的查询语句是SELECT * FROM `tp_user`
return Db::getLastSql();
但是最终得到的查询语句确实:SELECT * FROM `tp_user` ORDER BY `id` DESC
这明显不对,所以我们需要使用removeOption()方法,可以清理掉上一次查询保留的值,清理哪个就给其传入什么参数,比如removeOption('where')
$userQuery = Db::name('user');
$data1 = $userQuery->where('id', '<', '40')->order('id', 'desc')->select();
$data2 = $userQuery->removeOption('order')->select();
return Db::getLastSql();
// SELECT * FROM `tp_user` WHERE `id` < 40
$userQuery = Db::name('user');
$data1 = $userQuery->where('id', '<', '40')->order('id', 'desc')->select();
$data2 = $userQuery->removeOption('where')->select();
return Db::getLastSql();
// SELECT * FROM `tp_user` ORDER BY `id` DESC
$userQuery = Db::name('user');
$data1 = $userQuery->where('id', '<', '40')->order('id', 'desc')->select();
$data2 = $userQuery->removeOption()->select();
return Db::getLastSql();
// SELECT * FROM `tp_user`
如果要清除所有查询条件,那么不需要传入任何参数,直接就是全清除所有查询条件,所以再多个查询时候,直接无脑清除一下即可。
另外where方法参数:where('字段名','查询表达式','查询条件'),默认查询表达式是“=”
Db::table('user')->where('id','=',1)->select();
与下面等效
Db::table('user')->where('id',1)->select();
更详细参考:https://www.cnblogs.com/sam-zh/p/15196390.html