- 开发无止境 -
Data: 2015-06-15 05:08:13Form: JournalClick: 24
1.查询数据库的方式三种
数据库查询(Db类) Db::name()->where()->select()
实例化模型查询(建立模型model ) $userModel = new userModel(); $userModel->where()->select()
使用查询构造器(调用数据库链式操作和查询方法) UserModel::where()->select()
俩种查询方式返回的数据格式也不一样。一种是数组,一种是数据集对象(think\Collection),和数组无差别用法,并且额外分装了些方法。
数据库的查询结果默认返回数据集对象
模型中进行的数据集查询,全部返回数据集对象
查询的方式主要是 查询多条->select() 和 查询单条 ->find()
模型查询 | 数据库查询 | |
->select() | 数据集(对象 think\Collection的数组) | 数据集 (对象 think\Collection的数组) |
->find() | 数据( 对象 think\Collection) | 数组 |
判断为空:数据集必须用$result->isEmpty().来操作。不能用empty($result);
数据集转化为数据:$result->toArray()
这里要值得注意的是:只有模型查询下的find(), 在查不到返回结果时,返回的是NULL。这个时候使用$result-> toArray()和$result-> isEmpty(),是会报错的。没有这个方法。
解决办法:
方法一、使用findOrEmpty()为空的时候返回的会是空模型,可以继续使用toArray() 和 isEmpty() 方法
$result = $userModel->where()->findOrEmpty() ;
方法二、用->find(),再用empty 判断
2.数据操作:链式操作
方法 | 作用 | 实例 |
where | 查询条件 | ->where() |
table | 方法主要用于指定操作的数据表。(包含表前缀) | ->table('taobao_user') |
name | 方法主要用于指定操作的数据表(不用写表前缀,查询时会自动使用database.php中配置好的表前缀) | ->name('user') |
alias | 设置当前表的别名 | UserModel::alias(‘u’) |
field | 查询字段 | ->field('*') |
limit | 限制查询数量 | ->limit(10) // ->limit(0,10)// 第一页 |
page | 查询第几页(我一般少用) | ->page(1,10) // 第一页 |
order | 排序 | // 单个字段 ->order('create_time','desc') // 多个字段,默认asc ->order(['create_time','user_id'=>'desc]) |
排序字段需要函数 | ->orderRaw() | |
group | 分组 | ->group('user_id') ->group('user_id,test_time') |
having | group by 的条件 :group by user_id having count(id)>2 | ->having('count(id)>3'); |
join | 表连接(默认inner join) join ( mixed join [, mixed $condition = null [, string $type = 'INNER']] ) type:关联类型。可以为:`INNER`、`LEFT`、`RIGHT`、`FULL`,不区分大小写,默认为`INNER`。 | ->join('user u','u.id = login.user_id and u.state >1') |
leftJoin | 左连接(左表为主) | ->leftJoin('user u','u.id = login.user_id and u.state >1') |
rightJoin | 右连接(右表为主) | ->leftJoin('user u','u.id = login.user_id and u.state >1') |
join / leftJoin / rightJoin 需要连接的表也可以是个子查询 | ->leftJoin([$sql=>'u'],'u.id = login.user_id and u.state >1') | |
union | 合并多个SELECT 语句的结果集。 (查询结果的的字段名称,应该一直) | Db::field('name') ->table('think_user_0') ->union('SELECT name FROM think_user_1') ->union('SELECT name FROM think_user_2') ->select(); |
distinct | 去重 这个不经常用链式函数去写,直接field('distinct id, name') | |
lock | 锁机制,在select 语句中加上 for update | ->lock(true) |
fetchSql | 返回查询的语句 | ->fetchSql(true) |
partition | 分区 这个在tp框架中,个人比较少用。都是数据库表直接分区,比较多用hash分区, 和 值大小分区。select 直接查询没有手动切换哪个分区去查 |
where 查询
数组条件:
2.1. 关联数组
2.2. 索引数组
2.1 关联数组
和3.2 框架常用的条件查询基本一致,但是tp6的关联数组,只能实现and操作和=操作(起码我用的时候,不知道 != in not in like 这些的条件怎么在关联数组中使用)
$where = [ 'user_id'=>1, 'phone'=>'15600000001', 'is_delete'=>1 ];
$result = Db::name('user_card')->where($where)->select();
2.2 索引数组
索引数组的方式批量设置查询条件,可以使用 <> / in / not in/ like/ between 条件
$where = [ ['id','=', 253], ['is_delete','>=', 1], ['phone','like', '%186%'], ['sex','<>', '女'], ['create_time','between',['2020-05-12','2022-01-11']], ]; $result = Db::name('user_card')->where($where)->whereNotNull('birthday')->select();
null 和not null 不能放在where索引数组总查询,会变成比较字符串,解决方法,用链式函数 ->whereNotNull('birthday') 或者 whereNull(birthday)
$where = [ ['birthday','=','not null'] ]; $result = Db::name('user_card')->where($where)->select();
sql:SELECT * FROM `un2co_user_card` WHERE `birthday` = 'not null'
字符串条件:
直接使用字符串条件直接查询和操作
Db::table('think_user')->whereRaw('type=1 AND status=1')->select();
Thinkphp6 的 where 查询条件 and 和 or 的 操作
tp3.2 来说 or 或者and 的操作可以在一个数组中用_logic 来解决
例一:
$where = ['id'=>1,'name'=>'小表','_logic'=>'or']
例二:
$where1 = ['id'=>1, 'name'=>'小白']; $where2 = ['id'=>2, 'name'=>'小黑']; $where = [$where1, $where2,'_logic'='or']
但是tp6的不行。tp6的and 和 or 可以实现的方法比较多
已知:->where(A)->where(B) 俩个条件关系是 A and B
1.多字段相同的查询条件, 可以使用 |(or) &(and)
Db::table('think_user') ->where('name|title','like','thinkphp%') ->where('create_time&update_time','>',0) ->find();
sql:
SELECT * FROM `think_user` WHERE ( `name` LIKE 'thinkphp%' OR `title` LIKE 'thinkphp%' ) AND ( `create_time` > 0 AND `update_time` > 0 ) LIMIT 1
2.不同字段不同条件,包含 and 和or 的建议使用闭包查询。因为数组条件查询的达不到想要的效果(我是用不出来)。例如
SELECT * FROM `un2co_user_card` WHERE (nickname = '白小白' or phone = '18606995547') and is_delete = 1;
现有的方法,为啥不行。主要是索引数组和关联数组,条件之间都是and关系
where(C)->whereOR([A, B])->where(d) | A、B条件之间是或的关系,且和c是And关系,和d是or关系 where A or B |
where([A, B]) | where A and B. 看起来能用,但是A条件里面,无法实现or的逻辑。各个条件之间全是and逻辑。 $where = [ ['id','=', 253], ['is_delete','>=', 1], ['phone','like', '%186%'], ['sex','<>', '女'], ['create_time','between',['2020-05-12','2022-01-11']], |
只能用闭包查询
$where = [['nickname','=', '白小白'], ['phone','=','18606995547']]; $result = Db::name('user_card') ->where(['is_delete'=>1]) ->where(function($query) use ($where){$query->whereOr($where);}) ->select();
sql:
SELECT * FROM `un2co_user_card` WHERE `is_delete` = 1 AND ( `nickname` = '白小白' OR `phone` = '18606995547' )