DB Facade 的用法

原生 SQL

  1. // Basic statement 放入各种 sql 语句 return bool
  2. DB::statement('drop table users');
  3. // 查询 返回标准对象的集合
  4. $users = DB::select('select * from users');
  5. // 参数绑定1
  6. $usersOfType = DB::select('select * from users where type = ?', [$type]);
  7. // 参数绑定2
  8. $usersOfType = DB::select('select * from users where type = :type', ['type' => $userType]);
  9. // 插入
  10. $countInsert = DB::insert('insert into contacts (name, email) values (?, ?)', ['sally', 'sally@me.com']);
  11. // 修改
  12. $countUpdated = DB::update('update contacts set status = ? where id = ?', [1, $id]);
  13. // 删除
  14. $countDeleted = DB::delete('delete from contacts where archived = ?', [true]);

查询构建器

允许链式调用

约束方法

select()

// 等价
$emails = DB::table('contacts')->select('email', 'email2 as second_email')->get();
// or
$emails = DB::table('contacts')->select(['email', 'email2 as second_email'])->get(); 
// Or
$emails = DB::table('contacts')
    ->select('email')
    ->addSelect('email2 as second_email')
    ->get();

where()

// where('列名', '操作符', '值') '=' 可以省略
$newContacts = DB::table('contact')
    ->where('created_at', '>', now()->subDay())
    ->orWhere('vip',true)
    ->get();
// 且
$newVips = DB::table('contacts')
    ->where('vip', true)
    ->where('created_at', '>', now()->subDay());
// 数组形式 且
$newVips = DB::table('contacts')->where([
        ['vip', true],
        ['created_at', '>', now()->subDay()],
    ]);

orWhere()

$priorityContacts = DB::table('contacts')
    ->where('vip', true)
    ->orWhere('created_at', '>', now()->subDay())
    ->get();

复杂的闭包,注意逻辑运算的优先级


$canEdit = DB::table('users')
    ->where('admin', true)
    ->orWhere('plan', 'premium')
    ->where('is_plan_owner', true)
    ->get();
// 返回 SELECT * FROM users WHERE admin = 1 OR plan = 'premium' AND is_plan_owner = 1;

$canEdit = DB::table('users')
    ->where('admin', true)
    ->orWhere(function ($query) {
        $query->where('plan', 'premium')
            ->where('is_plan_owner', true);
    })
    ->get();
// 返回 SELECT * FROM users WHERE admin = 1 OR (plan = 'premium' AND is_plan_owner = 1);

whereBetween(colName, [low, high])

$mediumDrinks = DB::table('drinks')
    ->whereBetween('size', [6, 12])
    ->get();

$notMediumDrinks = DB::table('drinks')
    ->whereNotBetween('size',[6, 12])
    ->get();

whereIn(colName, [1, 2, 3]) 和 whereNotIn()

查找在集合中的值

whereNull(colName) 和 whereNotNUll(colName)

查找 null 和 非 null 的值

whereRaw()

使用原生的sql语句,注意防止 sql 注入

$goofs = DB::table('contacts')->whereRaw('id = 12345')->get()

whereExists()

查找存在的行,例如查找至少有一条评论的文章

$articles = Db::table('articles')->whereExists(function($query){
    $query->select('id')
        ->from('comments')
        ->whereRaw('comments.article_id = articles.id');
})

distinct()

去重

$lastNames = DB::table('contacts')->select('city')->distinct()->get();

修改方法

orderBy(colName, direction)

groupBy() and having() or havingRaw()

skip() and take()

分页

// returns rows 31-40
$page4 = DB::table('contacts')->skip(30)->take(10)->get();

latest(colName) and oldest(colName)

按照 colName 排序,如果不传 colName 则使用 created_at ,latest:降序,oldest:升序

inRandomOrder()

随机排序

条件方法

when()

当第一个参数为真值时,执行闭包中的查询

$status = request('status'); // Defaults to null if not set
$posts = DB::table('posts')
    ->when($status, function ($query) use ($status) {
        return $query->where('status', $status);
    })
    ->get();

    // Or
$posts = DB::table('posts')
    ->when($ignoreDrafts, function ($query) {
        return $query->where('draft', false);
    })
    ->get();

unless()

when() 相反,当第一个参数为假值时执行闭包中的查询

结束、返回方法

如果没有这些方法,你将只会得到一个查询构造器的实例,这些方法将停止查询链,并且触发sql执行。

get()

返回所有结果

$contacts = DB::table('contacts')->get();
$vipContacts = DB::table('contacts')->where('vip', true)->get();

first() 和 firstOrFail()

返回一条结果,就像 get() , 但是加了 LIMIT 1

如果没有查询到结果,first() 默认是 null,而 firstOrFail() 则抛出一个异常

Db 没有 firstOrFail() 方法

如果你只想要某一列或几列,传入列名即可,字符串或数组形式

find(id) 和 findOrFail(id)

和 first() 一样,但是你要传入一个id值,与主键对比查找

Db 也没有 findOrFail() 方法

// 查找id是5 的记录
$contactFive = DB::table('contacts')->find(5);

value()

返回第一行的某个字段的值,只能单列的值,不能传数组

count()

min() 和 max()

sum() 和 avg()

使用 DB::raw 在查询中使用原生sql

$contacts = DB::table('contacts')
    ->select(DB::raw('*, (score * 100) AS integer_score'))
    ->get();

Joins

$users = DB::table('users')
    ->join('contacts', 'users.id', '=', 'contacts.user_id')
    ->select('users.*', 'contacts.name', 'contacts.status')
    ->get();

默认是内连接,你还可以使用 leftJoin()

使用闭包创建复杂的连接

DB::table('users')
    ->join('contacts', function ($join) {
        $join->on('users.id', '=', 'contacts.user_id')
            ->orOn('users.id', '=', 'contacts.proxy_user_id');
    })
    ->get();

Unions

你可以先创建两个查询 然后使用 union() 或者 unionAll(), 把结果合并起来。

$first = DB::table('contacts')
    ->whereNull('first_name');

$contacts = DB::table('contacts')
    ->whereNull('last_name')
    ->union($first)
    ->get();

插入

$id = DB::table('contacts')->insertGetId([
    'name' => 'Abe Thomas',
    'email' => 'athomas1987@gmail.com',
]);

DB::table('contacts')->insert([
    ['name' => 'Tamika Johnson', 'email' => 'tamikaj@gmail.com'],
    ['name' => 'Jim Patterson', 'email' => 'james.patterson@hotmail.com'],
]);

更新

DB::table('contacts')
    ->where('points', '>', 100)
    ->update(['status' => 'vip']);

// 自增和自减
DB::table('contacts')->increment('tokens', 5);
DB::table('contacts')->decrement('tokens');

删除

DB::table('contacts')
    ->where('last_login', '<', now()->subYear())
    ->delete();

// 截断表,使自增从0开始
DB::table('contacts')->truncate();

JSON 操作

DB::table('users')->where('options->isAdmin', true)->get();

DB::table('users')->update(['options->isVerified', true]);

事务

DB::transaction(function () use ($userId, $numVotes) {
    // Possibly failing DB query
    DB::table('users')
        ->where('id', $userId)
        ->update(['votes' => $numVotes]);

     // Caching query that we don't want to run if the above query fails
    DB::table('votes')
        ->where('user_id', $userId)
        ->delete();
});

DB::beginTransaction();

// Take database actions
if ($badThingsHappened {
    DB::rollBack();
}

// Take other database actions
DB::commit();