简介
Laravel 查询构造器(query builder)提供流畅的接口,帮助你改造、执行数据库查询。这里的查询,并不只是 select
查询语句,还有 update
、delete
和 `insert' 语句等。在所有支持的数据库系统中都运行良好。
Laravel 的查询构造器使用 PDO 参数绑定保护程序免受 SQL 注入攻击,所以你传递的绑定参数无需进行清理操作了。
查询数据
获得表格里所有数据
使用 DB
门面的 table
方法开启查询。table
方法返回给定表格的查询构造器实例,允许你用链式调用的方式为查询添加约束条件,最后使用 get
方法获得。
get();
return view('user.index', ['users' => $user]);
}
}
get
方法返回一个 Illuminate\Support\Collection
集合实例,集合里的的每个元素都是一个 PDP StdClass
对象。你可以通过访问对象属性过的对应的字段的值:
foreach ( $users as $user){
echo $user->name();
}
获得表格里的一条数据/指定列的值
使用 first
获得表格里的一条数据,这条数据返回一个 StdClass
对象:
$user = DB::table('users')->where('name', 'John')->first();
echo $user->name();
如果只想取出一列值的话,就用 value
,这个方法直接返回指定列的值:
$email = DB::table('users')->where('name', 'John')->value('email');
获得表格里的一列数据
使用 pluck
方法可获得一个列的集合。在下面例子里,我们获得所有的角色名:
$titles = DB::table('roles')->pluck('title');
foreach ($titles as $title){
echo $title;
}
也可以在返回的集合里指定自定义键:
$roles = DB::table('roles')->pluck('title', 'name');
foreach ($roles as $name => $title){
echo $title;
}
分块输出数据
如果要处理成千上万条数据,考虑使用 chunk
方法。这个方法一次取出一小块数据,放到闭包里处理。这在写 Artisan 命令处理成千上万条数据非常有用。例如,从 users
表里分块、每次取出100条记录:
DB::table('users')->orderBy('id')->chunk(100, function($users){
foreach($users as $user){
//
}
})
也可以在闭包函数里 return false
停止继续分块输出数据:
DB::table('users')->orderBy('id')->chunk(100, function($users){
//Process the records...
return false;
})
聚合
查询构造器也提供过了很多聚合方法:count
、max
、min
、avg
和 sum
。在构造好你的查询后即可使用:
$users = DB::table('users')->count();
$prices = DB::table('orders')->max('price');
聚合方法也可以结合查询子句使用:
$prices =DB::table('orders')
->where('finalized', 1)
->avg('price');
Select
又是并不需要获得数据表所有字段的数据,而是选择性的获得指定几个字段的数据,这是可以使用 select
方法:
$users =DB::table('users')->select('name', 'email as user_email')->get();
distinct
方法用于对结果去重:
$users = DB::table('users')->distinct()->get();
如果当前有了一个查询构造器实例,想在此基础上添加一个 select
子句,那么就要用 addSelect
方法了:
$query = DB::table('users')->select('name');
$users = $query->addSelect('age')->get();
原生表达式
有时在一个查询语句里使用原生表达式,那么使用 DB::raw
方法就行,传递给该方法的内容会作为字符串插入到最终的查询语句中:
$users = DB::table('users')
-> select(DB::raw('count(*) as user_count, status'))
-> where('status' ,'<>', 1)
->groupBy('status')
->get();
Joins
内连接
查询语句构造器也可以用来写连接语(join statements)。「内连接」就是用 `join' 方法,该方法第一个参数是要连接的表,剩下的参数就是要连接约束条件了。不仅如此,你可以在一个构造语句中连接多个表格:
$users = DB::table('users')
-> join('contacts', 'users.id', '=', 'contacts.user_id')
-> join('orders', 'users.id', '=', 'orders.user_id')
-> select('users.*', 'contacts.phone', 'orders.price')
->get();
左连接
左连接使用 leftJoin
方法,它的方法签名和 join
是一样的:
$users = DB::table('users')
-> leftJoin('posts', 'users.id', '=', 'posts.user_id')
->get();
交叉连接
交叉连接使用 crossJoin
方法:
$users = DB::table('users')
-> crossJoin('colours')
->get();
高级连接子句
如果要使用更加高级的连接子句,就要通过 join
方法的第二个参数,它是一个闭包。闭包接收一个 joinClause
对象,用于对 join
子句添加约束条件:
DB::table('users')
->join('contacts', function($join){
$join->on('users.id', '=', 'contacts.user_id')0>orOn(...);
})
->get();
你还可以在 join
子句上使用「where」 约束,得用到 where
和 orWhere
方法——限定列的取值范围:
DB::table::('users')
-> join('contacts', function($join){
$join->on('users.id', '=', 'contacts.user_id')
->where('contacts.user_id', '>', 5);
})
->get();
Unions
合并查询 union
方法。例如,我们把第一个查询合并到第二个查询里:
$first = DB::table('users')
-> whereNull('first_name');
$users = DB::table('users')
-> whereNull('last_name')
-> union($first)
-> get();
还有一个 unionAll
方法,它的签名和 union
方法是一样的。
Where 子句
在查询构造器实例上使用 where
方法来添加 where 子句。 where
方法最基本的用法是给它传递三个参数。第一个参数是字段名,第二个参数是操作符(数据库支持任何操作符),第三个参数是字段值。
例如,下面的查询查出所有投票数时 100 的记录:
$users = DB::table('users')->where('votes', '=', '100')->get();
为了方便,当验证某个字段是否等于某个值时,可以省略 中间的 =
:
$users = DB::table('users')->where('votes', '100')->get();
除了 =
, 这里还有使用其他操作符的例子:
$users = DB::table('users')
->where('votes', '>=', '100')
->get();
$users = DB::table('users')
->where('votes', '<>', '100')
->get();
$users = DB::table('users')
->where('votes', 'like', 'T%')
->get();
你也可以给 where
方法传递一个数组,指定多个限制条件:
$users = DB::table('users')->where([
['status', '=' ,1],
['subscriped', '<>', 1]
])->get();
Or 子句
使用 orWhere
方法添加 or
子句约束。orWhere
的方法签名和 where
是一样的:
$users = DB::table('users')
->where('votes', '>', 100)
->orWhere('name', 'John')
->get();
其他子句
whereBetween
whereBetween
方法验证字段值是否在给定范围之内:
$users = DB::table('users')
->whereBetween('votes',[1,100])
->get();
whereNotBetween
whereNotBetween
验证字段值是否在给定范围之外:
$users = DB::table('users')
->whereNoteBetween('votes',[1,100])
->get();
whereIn / whereNotIn
whereIn
验证字段是否在给定值列表里:
$users = DB::table('users')
->whereIn('id', [1,2,3])
->get();
whereNotIn
验证字段是否不在给定值表里:
$users = DB::table('users')
->whereNotIn('id', [1,2,3])
->get();
whereNull / whereNotNull
whereNull
方法验证指定字段值是否为 null
:
$users = DB::table('users)
->whereNull('update_at')
->get();
whereNotNull
方法验证指定字段值是否不是 null
:
$users = DB::table('users')
->whereNotNull('update_at')
->get();
whereDate / whereMonth / whereDay / whereYear
whereDate
用来比较字段值是否满足给定的日期:
$users = DB::table('users')
->whereDate('create_at', '2018-10-17')
->get();
whereMonth
用来比较字段值是否满足给定的月份:
$users = DB::table('users')
->whereMonth('created_at', '12')
->get();
whereDay
用来比较字段值是否满足给定的日期:
$users = DB::table('users')
->whereDay('created_at', '31')
->get();
whereYear
用来比较字段值是否满足给定的年份:
$users = DB::table('users')
->whereYear('created_at', '2018')
->get();
whereColumn
whereColumn
用来比较两字段值是否相等:
$users = DB::table('users')
->whereColumn('first_name','last_name');
->get();
也可以使用比较操作符:
$users = DB::table('users')
->wehreCloumn('updated_at', '>', 'created_at')
->get();
whereColumn
也接受多条件判断,这些条件会使用 and
操作符连接起来:
$users = DB::table('users')
->whereColumn([
['first_name', '=', 'last_name'],
['updated_at', '>', 'created_at']
])->get();
分组参数
有时需要创建高级的 where
子句,比如「where exists」或者内嵌分组参数。交给 Laravel 的查询语句构造器照样 OK。
看个例子:
DB::table('users')
->where('name', '=', 'John')
->orWhere(function($query){
$query->where('votes', '>', 100)
->where('title', '<>', 'Admin')
})
->get();
当传递 Closure
给 orWhere
方法的时候,就表示开始一个分组的约束了。Closure
接收一个查询实例用来在圆括号(()
)内设定限制。上面的例子会产生下面的 SQL :
select * from users where name = "John" or (votes > 100 and title <> 'Admin');
Where Exists
WhereExists
用来写 where exists
SQL 子句。whereExists
接收一个闭包,包含一个查询语句构造器实例,用于定义「where」子句里的内容:
DB::table('users')
->whereExists(function($query){
$query->select(DB::raw(1))
->from('orders')
->whereRaw('orders.user_id = users.id' );
})
->get();
上面的查询语句产生下面的 SQL:
select * from users
where exists(
select 1 from orders where orders.user_id = users.id
)
JSON Where 子句
Laravel 也支持数据库 JSON 字段的查询,前提是数据库支持 JSON 字段类型。现在 MYSQL5.7 和 Postgres 都支持。查询 JSON 字段使用 ->
操作符:
$user = DB::table('users')
->where('options->language', 'en')
->get();
$user = DB::table('users')
->where('preferences->dining->meal', 'salad')
->get();