Laravel学习笔记基础系列--(二十二)Laravel 查询构建器 查询的使用

作者: 温新

分类: 【Laravel】

阅读: 2629

时间: 2021-07-22 13:59:53

作者:温新

时间:2021-06-29

hi,我是温新,一名PHPer

上篇文章介绍了增删改及聚合查询的使用,那么本篇文章将学习最为复杂的查询操作。本篇文章按照官方文档来进行操作,不会深入查询操作。

简单查询

获取所有结果

方法:get()

返回值:集合对象

<span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(0, 85, 170)">$result</span> <span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">DB</span>::<span style="box-sizing: border-box;color: rgb(0, 0, 0)">table</span>(<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'users'</span>)<span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">get</span>();</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(0, 0, 0)">dd</span>(<span style="box-sizing: border-box;color: rgb(0, 85, 170)">$result</span>);</span>

查询一条数据

方法:first()

返回值:StdClass 对象

<span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(170, 85, 0)">// 方式一 返回第一条数据</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(0, 85, 170)">$result</span> <span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">DB</span>::<span style="box-sizing: border-box;color: rgb(0, 0, 0)">table</span>(<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'users'</span>)<span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">first</span>();</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(170, 85, 0)">// 方式二 </span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(0, 85, 170)">$result</span> <span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">DB</span>::<span style="box-sizing: border-box;color: rgb(0, 0, 0)">table</span>(<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'users'</span>)<span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">where</span>(<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'id'</span>,<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'>'</span>,<span style="box-sizing: border-box;color: rgb(17, 102, 68)">10</span>)<span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">first</span>();</span>

获取一行中的单个值

方法:value()

$result = DB::table('users')->where('id',10)->value('name');

获取单条记录

方法:find($id)

返回值:StdClass 对象

$result = DB::table('users')->find(5);

查询指定字段

方法:select(字段1,字段2...)

$result = DB::table('users')->select('name','nickname')->find(5);

条件子句查询

高频使用的查询。如文章搜索时,如有关键词传递到后台则按照关键词匹配文章,若没有则查询全部。

方法:when

<span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(0, 85, 170)">$keywords</span> <span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span> <span style="box-sizing: border-box;color: rgb(170, 17, 17)">'Laravel'</span>;</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(0, 85, 170)">$posts</span> <span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">DB</span>::<span style="box-sizing: border-box;color: rgb(0, 0, 0)">table</span>(<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'posts'</span>)<span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">when</span>(<span style="box-sizing: border-box;color: rgb(0, 85, 170)">$keywords</span>, <span style="box-sizing: border-box;color: rgb(119, 0, 136)">function</span>(<span style="box-sizing: border-box;color: rgb(0, 85, 170)">$query</span>) <span style="box-sizing: border-box;color: rgb(119, 0, 136)">use</span> (<span style="box-sizing: border-box;color: rgb(0, 85, 170)">$keywords</span>) {</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(119, 0, 136)">return</span> <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$query</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">where</span>(<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'title'</span>,<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'like'</span>,<span style="box-sizing: border-box;color: rgb(170, 17, 17)">"%</span><span style="box-sizing: border-box;color: rgb(0, 85, 170)">$keywords</span><span style="box-sizing: border-box;color: rgb(170, 17, 17)">%"</span>);</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">})<span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">get</span>();</span>

when方法在第一个参数为true时才会执行闭包中的查询条件。

连接查询

连接查询就不多说,实际开发中难以避免的存在。

准备工作:

1)users表中保留少量数据,其余全部删除,我这里保留5条,然后posts表中的user_id对应这5个ID;

2)创建posts迁移文件并充填数据,我这里只给出表结构,其控制器与模型自行创建。

到了这里,我相信都已经能够弄出来了。

<span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(0, 0, 0)">Schema</span>::<span style="box-sizing: border-box;color: rgb(0, 0, 0)">create</span>(<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'posts'</span>, <span style="box-sizing: border-box;color: rgb(119, 0, 136)">function</span> (<span style="box-sizing: border-box;color: rgb(0, 0, 0)">Blueprint</span> <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$table</span>) {</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$table</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">increments</span>(<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'id'</span>);</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$table</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">string</span>(<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'title'</span>,<span style="box-sizing: border-box;color: rgb(17, 102, 68)">100</span>)<span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">comment</span>(<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'标题'</span>);</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$table</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">unsignedInteger</span>(<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'user_id'</span>)<span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">comment</span>(<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'用户ID'</span>);</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$table</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">text</span>(<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'content'</span>)<span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">comment</span>(<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'内容'</span>);</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$table</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">timestamps</span>();</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">});</span>

我这里准备的数据:users表5条数据;posts表100条数据。关系为用户发表文章。

准备工作完成后一起开始连接查询之旅吧。

join-内连接

方法:join()

<span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(170, 85, 0)">// DemoController demo()</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(119, 0, 136)">public</span> <span style="box-sizing: border-box;color: rgb(119, 0, 136)">function</span> <span style="box-sizing: border-box;color: rgb(0, 0, 255)">demo</span>()</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">{</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$result</span> <span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">DB</span>::<span style="box-sizing: border-box;color: rgb(0, 0, 0)">table</span>(<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'users as a'</span>)</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">        <span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(51, 0, 170)">join</span>(<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'posts as b'</span>,<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'a.id'</span>,<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'='</span>,<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'b.user_id'</span>)</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">        <span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">get</span>();</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(0, 0, 0)">dd</span>(<span style="box-sizing: border-box;color: rgb(0, 85, 170)">$result</span>);</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">}</span>

join第一个参数是连接的表名,第二个字段关联字段,第三个字段操作符,第四个字段关联字段

left-左连接/right-右连接

方法:左连接-leftJoin,右连接-right

// 左连接
$result = DB::table('users as a')
            ->leftJoin('posts as b','a.id','=','b.user_id')
            ->get();
// 右连接
$result = DB::table('users as a')
            ->rightJoin('posts as b','a.id','=','b.user_id')
            ->get();

union-联合查询

方法:union

// user_id=1有24条数
// user_id=2有16条数据
// 结果 40条数据
$post1 = DB::table('posts')->where('user_id',1);
$result = DB::table('posts')->where('user_id',2)->union($post1)->get();
dd($result);

union联合查询,需要先创建一个查询,然后使用union将第一个查询和第一个查询进行联合查询。

crossJoin-交叉连接

方法:crossJoin(表名)

$result = DB::table('users')->crossJoin('posts')->get();

由于我这里使的数据都有对应的关系,因此join/leftJoin/rightJoin查询是看不出来明显的区别的。因此,关于连接查询的区别,要明白。

高级连接查询

高级连接查询仍旧的仍旧是join方法,不同的是,其第二个参数需要传入一个闭包函数,这个闭包查询中可以加入更多的查询条件。

$result = DB::table('users as a')
    ->join('posts as b', function($join) {
        $join->on('a.id','=','b.user_id');
        // 更多的条件可以通过链式调用
    })
    ->get();
dd($result);

闭包查询中的$join参数是一个Illuminate\Database\Query\JoinClause实例对象。

子查询连接

子查询连接使用的是joinSubleftJoinSubrightJoinSub方法。与普通连接查询不同的是,子查询连接需要将一个查询和子查询进行连接。这里以joinSub为例,对参数进行说明。

方法:joinSub(子查询,别名,关联字段的闭包)

参数:子查询--第一个查询的条件;别名--把该子查询作为了表,且为其起个别名;关联字段的闭包--查询条件。

// 案例:查询每个用户发布了多少文章
// 分组统计用户文章数量
$posts = DB::table('posts')->select('user_id',DB::raw('count(*) as total'))->groupBy('user_id');
// 查询对应用户
$users = DB::table('users')->joinSub($posts,'postsa',function($join){
    $join->on('users.id','=','postsa.user_id');
})->get();
dd($users);

子查询可以用于很多高级的查询,在复杂的项目中可能会用到。

其他方法条件查询

where子句

方法:where(列名,操作符,需要比较的值)

操作符有:>、<、>=、<=、like、<>、...

// 查询ID大于100的所有数据
$result = DB::table('posts')->where('id','>',100)->get();

orWhere语句

// 方式一
$result = DB::table('posts')->where('id','<=',20)
    ->orWhere('id','>=',110)
    ->get();
// 方式二
$result = DB::table('posts')->where('id','<=',20)
    ->orWhere(function($query){
        $query->where('id','>',90);
    })->get();

whereBetween/orWhereBetween

方法:whereBetween 区间查找

$result = DB::table('posts')->whereBetween('id',[1,10])->get();
$result = DB::table('posts')->whereBetween('id',[1,10])->orWhereBetween('id',[11,20])->get();

whereNotBetween/orWhereNotBetween

whereNotBetween 字段值不在给定的区间内

$result = DB::table('posts')->whereNotBetween('id',[1,10])->get();

whereIn/whereNotIn

whereIn 字段值是否在给定的数组中

$result = DB::table('posts')->whereIn('id',[1,2,3])->get();

还有很多方法,这里就不再一一演示了。如whereNullwhereDatewhereMonthwhereDaywhereYearwhereTimewhereColumn等。

排序/分组/限定

orderBy(字段, asc/desc)

$result = DB::table('posts')->orderBy('id','desc')->orderBy('title','asc')->get();

groupBy/having

方法:groupBy()对结果集分组

方法:having()筛选

// 分组
$result = DB::table('posts')->selectRaw('count(*) as total')->groupBy('user_id')->get();
// 筛选
$result = DB::table('posts')->selectRaw('count(*) as total')->groupBy('user_id')->having('total','>',20)->get();

取出指定多少条数据

用法 :skip/take。跳过skip条开始,取出take条数据。

$result = DB::table('posts')->skip(5)->take(5)->get();

此案例,跳过前5条数据,取后5条数据。

用法:offset/limit

$result = DB::table('posts')->offset(5)->limit(5)->get();

关于更多的方法请参考官方文档。

我是温新

每天进步一点点,就一点点

请登录后再评论