DB::table('users')->get();
get
方法返回包含结果集的Illuminate\Support\Collection
,其中每一个结果都是 PHP 的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) { // } });
你可以通过从闭包函数中返回
false
来终止组块的运行:DB::table('users')->orderBy('id')->chunk(100, function($users) { // 处理结果集... return false; });
聚合函数
查询构建器还提供了多个聚合方法,如
count
,max
,min
,avg
和sum
,你可以在构造查询之后调用这些方法:$users = DB::table('users')->count(); $price = DB::table('orders')->max('price');
当然,你可以联合其它查询子句和聚合函数来构建查询:
$price = 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();
内连接(等值连接)
查询构建器还可以用于编写基本的 SQL “内连接”,你可以使用查询构建器实例上的
join
方法,传递给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('sizes') ->crossJoin('colours') ->get();
简单where子句
使用查询构建器上的
where
方法可以添加where
子句到查询中,调用where
最基本的方法需要传递三个参数,第一个参数是列名,第二个参数是任意一个数据库系统支持的操作符,第三个参数是该列要比较的值。例如,下面是一个验证“votes”列的值是否等于 100 的查询:
$users = DB::table('users')->where('votes', '=', 100)->get();
为了方便,如果你只是简单比较列值和给定数值是否相等,可以将数值直接作为where方法的第二个参数:
$users = DB::table('users')->where('votes', 100)->get();
当然,你还可以使用其它操作符来编写
where
子句:$users = DB::table('users') ->where('votes', '>=', 100) ->get(); $users = DB::table('users') ->where('votes', '<>', 100) ->get(); $users = DB::table('users') ->where('name', 'like', 'T%') ->get();
还可以传递条件数组到
where
函数:$users = DB::table('users')->where([ ['status', '=', '1'], ['subscribed', '<>', '1'], ])->get();
or语句
你可以通过方法链将多个
where
约束链接到一起,也可以添加or
子句到查询,orWhere
方法和where
方法接收参数一样:$users = DB::table('users') ->where('votes', '>', 100) ->orWhere('name', 'John') ->get();
更多Where子句
whereBetween
whereBetween
方法验证列值是否在给定值之间:$users = DB::table('users') ->whereBetween('votes', [1, 100])->get();
whereNotBetween
whereNotBetween
方法验证列值不在给定值之间:$users = DB::table('users') ->whereNotBetween('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('updated_at') ->get();
whereNotNull
方法验证给定列的值不是NULL
:$users = DB::table('users') ->whereNotNull('updated_at') ->get();
whereDate / whereMonth / whereDay / whereYear
whereDate
方法用于比较字段值和日期:$users = DB::table('users') ->whereDate('created_at', '2016-10-10') ->get();
whereMonth
方法用于比较字段值和一年中的指定月份:$users = DB::table('users') ->whereMonth('created_at', '10') ->get();
whereDay
方法用于比较字段值和一月中的制定天:$users = DB::table('users') ->whereDay('created_at', '10') ->get();
whereYear
方法用于比较字段值和指定年:$users = DB::table('users') ->whereYear('created_at', '2016') ->get();
whereColumn
whereColumn
方法用于验证两个字段是否相等:$users = DB::table('users') ->whereColumn('first_name', 'last_name') ->get();
还可以传递一个比较运算符到该方法:
$users = DB::table('users') ->whereColumn('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 查询构建器也可以处理这些。作为开始,让我们看一个在括号中进行分组约束的例子:
DB::table('users') ->where('name', '=', 'John') ->orWhere(function ($query) { $query->where('votes', '>', 100) ->where('title', '<>', 'Admin'); }) ->get();
正如你所看到的,传递闭包到
orWhere
方法构造查询构建器来开始一个约束分组,该闭包将会获取一个用于设置括号中包含的约束的查询构建器实例。上述语句等价于下面的 SQL:select * from users where name = 'John' or (votes > 100 and title <> 'Admin')
where exists子句
whereExists
方法允许你编写where exists
SQL子句,whereExists
方法接收一个闭包参数,该闭包获取一个查询构建器实例从而允许你定义放置在“exists”子句中的查询: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 字段类型的数据库(目前是 MySQL 5.7 和 Postgres)上使用操作符
->
查询 JSON 字段类型:$users = DB::table('users') ->where('options->language', 'en') ->get(); $users = DB::table('users') ->where('preferences->dining->meal', 'salad') ->get();
orderBy
orderBy
方法允许你通过给定字段对结果集进行排序,orderBy
的第一个参数应该是你希望排序的字段,第二个参数控制着排序的方向——asc
或desc
:$users = DB::table('users') ->orderBy('name', 'desc') ->get();
latest / oldest
latest
和oldest
方法允许你通过日期对结果进行排序,默认情况下,结果集通过created_at
字段进行排序,或者,你可以你想要排序的字段作为字段名传入:$user = DB::table('users') ->latest() ->first();
inRandomOrder
inRandomOrder
方法可用于对查询结果集进行随机排序,比如,你可以用该方法获取一个随机用户:$randomUser = DB::table('users') ->inRandomOrder() ->first();
groupBy / having / havingRaw
groupBy
和having
方法用于对结果集进行分组,having
方法和where
方法的用法类似:$users = DB::table('users') ->groupBy('account_id') ->having('account_id', '>', 100) ->get();
havingRaw
方法可用于设置原生字符串作为having
子句的值,例如,我们可以这样找到所有售价大于$2,500
的部分:$users = DB::table('orders') ->select('department', DB::raw('SUM(price) as total_sales')) ->groupBy('department') ->havingRaw('SUM(price) > 2500') ->get();
skip / take
想要限定查询返回的结果集的数目,或者在查询中跳过给定数目的结果,可以使用
skip
和take
方法:$users = DB::table('users')->skip(10)->take(5)->get();
作为替代方法,还可以使用
limit
和offset
方法:$users = DB::table('users') ->offset(10) ->limit(5) ->get();
查询构建器还提供了
insert
方法用于插入记录到数据表。insert
方法接收数组形式的字段名和字段值进行插入操作:DB::table('users')->insert( ['email' => 'john@example.com', 'votes' => 0] );
你甚至可以一次性通过传入多个数组来插入多条记录,每个数组代表要插入数据表的记录:
DB::table('users')->insert([ ['email' => 'taylor@example.com', 'votes' => 0], ['email' => 'dayle@example.com', 'votes' => 0] ]);
自增ID
如果数据表有自增ID,使用
insertGetId
方法来插入记录并返回ID值:$id = DB::table('users')->insertGetId( ['email' => 'john@example.com', 'votes' => 0] );
注:当使用 PostgresSQL 时
insertGetId
方法默认自增列被命名为id
,如果你想要从其他“序列”获取ID,可以将序列名作为第二个参数传递到insertGetId
方法。11、更新(Update)
当然,除了插入记录到数据库,查询构建器还可以通过使用
update
方法更新已有记录。update
方法和insert
方法一样,接收字段名和字段值的键值对数组包含要更新的列,你可以通过where
子句来对update
查询进行约束:DB::table('users') ->where('id', 1) ->update(['votes' => 1]);
更新JSON字段
更新 JSON 字段的时候,需要使用
->
语法访问 JSON 对象上相应的值,该操作只能用于支持 JSON 字段类型的数据库:DB::table('users') ->where('id', 1) ->update(['options->enabled' => true]);
增加/减少
查询构建器还为增减给定字段名对应数值提供方便。相较于编写
update
语句,这是一条捷径,提供了更好的体验和测试接口。这两个方法都至少接收一个参数:需要修改的列。第二个参数是可选的,用于控制列值增加/减少的数目。
DB::table('users')->increment('votes'); DB::table('users')->increment('votes', 5); DB::table('users')->decrement('votes'); DB::table('users')->decrement('votes', 5);
在操作过程中你还可以指定额外的列进行更新:
DB::table('users')->increment('votes', 1, ['name' => 'John']);
12、删除(Delete)
当然,查询构建器还可以通过
delete
方法从表中删除记录,你可以在调用delete
方法前通过添加where
子句来添加约束条件:DB::table('users')->delete(); DB::table('users')->where('votes', '>', 100)->delete();
如果你希望清除整张表,也就是删除所有列并将自增ID置为0,可以使用
truncate
方法:DB::table('users')->truncate();