Laravel Database: Query Builder
Laravel 提供丰富好用的的数据库操作接口,使用了 PDO 参数绑定,避免出现 SQL 注入攻击。
当传送的数据作为绑定时,根本就不需要对数据进行过滤。
查询
查询一张表的所有记录
你可以使用 DB facade 的 method 方法来查询,table 方法返回的是指定表的实际,允许你进行更多的链式操作,最后使用 get 方法来取得结果。
<?php
namespace App\Http\Controllers;
use Illuminate\Support\Facades\DB;
use App\Http\Controllers\Controller;
class UserController extends Controller
{
/**
- Show a list of all of the application's users.
- @return Response
*/
public function index()
{
$users = DB::table('users')->get();
return view('user.index', ['users' => $users]);
}
}
get 方法返回一个 Illuminate\Support\Collection,结果集中包含的每一条记录都是 PHP 标准类的实例。
你可以通过访问对象属性的方式,来访问每一列的值。
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 方法。
该方法可以提取部分数据,并可以再 Closure 中对这些数据进行处理。
特别适合用于 Artisan command 来处理大量的数据记录。
DB::table('users')->orderBy('id')->chunk(100, function($users) {
foreach ($users as $user) {
//
}
});
你还可以通过,闭包中返回 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();
$price = DB::table('orders')->max('price');
还可以结合其他的条件进行使用:
$price = DB::table('orders')
->where('finalized', 1)
->avg('price');
Selects
指定一个 select 条件
我们并不总是想要一条记录中的所有列,那就可以使用 select 方法,你可以为查询指定一个 select 条件。
$users = DB::table('users')->select('name', 'email as user_email')->get();
distinct 方法允许你可以查询到不重复的结果
$users = DB::table('users')->distinct()->get();
如果你已经创建了一个查询实例,然后你想要在已存在的查询中,添加一个条件,可以使用 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
内联查询(Inner Join Clause)
在查询中使用连接查询,一个基本的内连接查询,你可以在查询 builder 实例上,使用 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();
左联接查询(Left Join Clause)
使用 leftJoin 方法,leftJoin 方法的使用与 join 方法是同样的,参数顺序是:表名,约束条件
$users = DB::table('users')
->leftJoin('posts', 'users.id', '=', 'posts.user_id')
->get();
跨表联合查询
使用 crossJoin 方法,只需要指定需要跨表联合查询的表。
$users = DB::table('sizes')
->crossJoin('colours')
->get();
高级联合查询
给 join 方法的第二个参数,传送一个 Closure 。该 Closure 将会收到一个 JoinClause 对象,它允许你在 join 条件中,指定约束。
DB::table('users')
->join('contacts', function ($join) {
$join->on('users.id', '=', 'contacts.user_id')->orOn(...);
})
->get();
如果你想要在联合查询中使用条件,你可以在此联合查询中,使用 where 与 orWhere 方法。这两个是比较列的值,而不是比较两个列。
DB::table('users')
->join('contacts', function ($join) {
$join->on('users.id', '=', 'contacts.user_id')
->where('contacts.user_id', '>', 5);
})
->get();
Unions
一个快速将两个查询联合在一个的方法 union。首先,初始化一个查询,并使用 union 方法将它与第二个查询联合。
$first = DB::table('users')
->whereNull('first_name');
$users = DB::table('users')
->whereNull('last_name')
->union($first)
->get();
注意:unionAll 方法具有与 union 同样的结构