laravel 基础教程 —— 查询生成器

JSON where 子句

Laravel 援救对协助 JSON 列类型的数据库查询 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();

规则语句

奇迹你可能希望只有当一些原则达标时才去添加一些询问到语句中。又或者你想要在唯有进入的乞请数据中带有指定的字段时才会判定在
where 子句中展开进入。你可以动用 when 方法来落成那一个:

$role = $request->input('role');

$users = DB::table('users')
           ->where($role, function ($query) use ($role) {
             return $query->where('role_id', $role);
           })
           ->get();

when 方法只具有给定的第四个参数为 true
时才会执行给定的闭包。若是第四个参数是 false,那么闭包将不会被实践。

探寻结果

从表中检索所有的行

在开班流畅的进行查询此前,你须求先接纳 DB 假面的 table 方法,table
方法会重回一个给定表的查询生成器实例,那允许你链式添加多样询问约束,并最终赢得结果。大家来看一个演示,大家只是调用
get 来获取具有的表中的记录:

<?php

namespace App\Http\Controllers;

use 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 方法会再次来到一个 array ,其每一项结果都是一个
StdClass 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');

对结果开展分块

要是您与表中的数千条记下合营,你可以设想动用 chunk
方法,该格局一次会从结果中找寻出一小块。并且将那每一块放进闭包中提需求进程。该办法对于编写
Artisan
命令来协作数千条的笔录格外有效。比如,让大家将总体用户表分块成每一回 100
条来行事:

DB::table('users')->orderBy('id')->chunk(100, function ($users) {
  foreach ($users as $user) {
    //
  } 
});

你可以通过在 Closure 中返回 false 来甘休进一步的拍卖块的操作:

DB::table('users')->orderBy('id')->chunk(100, function ($users) {
  // Process the records...

  return false; 
});

搜寻表列的值

一旦你指望得到一个数组来含有一个列中所有的值,你可以使用 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;
}

Where 子句

简单的 Where 子句

你可以在询问生成器中采取 where 方法来在询问中添加 where
约束。半数以上基础的 where
调用都急需提供多个参数,第四个参数是列的称谓,第一个参数是相比操作的方法,第三个参数则是指向列所须求评估的值。

诸如,那里的查询用来验证 “votes” 列的值等于 100:

$users = DB::table('users')->where('votes', '=', 100)->get();

为了有利于,你能够直接传送要求比较的值到首个参数来声明列值与给定值相等的判定:

$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();

或声明

你可以将 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::('users')
           ->whereNotNull('updated_at')
           ->get();

whereColumn

whereColumn 方法可以用来判定两列的值是还是不是等于:

$users = DB::table('users')
           ->whereColumn('first_name', 'last_name');

你也可以传递一个比较符到方法中:

$users = DB::table('users')
           ->whereColumn('updated_at', '>', 'created_at');

whereColumn 方法可以接到一个暗含了四个限制标准的数组。这几个规则会被选取
add 判定操作:

$users = DB::table('users')
           ->whereColumn([
             ['first_name', 'last_name'],
             ['updated_at', '>', 'created_at']
           ]);

选择

点名一个摘取约束

本来,你不会延续想要从数据库中收获具有的列。你可以使用 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();

原生的表明式

有时,你也许须要在查询时接纳原生的表明式,那么些表明式会以字符串的法门注入到查询中,所以你应有小心的不要构造出其他的
SQL 注入点。你可以使用 DB::raw 方法来布局一个原生的表明式:

$users = DB::table('users')
           ->select(DB::raw('count(*) as user_count, status'))
           ->where('status', '<>', 1)
           ->groupBy('status')
           ->get();

高级 Where 子句

参数分组

有时你须要营造一些一发高档的 where 子句,比如,“where
exists”或者嵌套的参数分组。Laravel
的询问生成器也能很好的处理这个。让大家来看一个分组括号内约束的例子:

DB::table('users')
  ->where('name', '=', 'John')
  ->orWhere(function ($query) {
    $query->where('votes', '>', 100)
          ->where('title', '<>', 'Admin');
  })
  ->get();

就像是您所见到的,传递一个 ClosureorWhere
方法来指引查询生成器开端一个组约束。Closure
会接收一个询问生成器的实例,那样你就能够在括号组内营造一些束缚。上边的以身作则将会变动上面的
SQL:

select * from users where name = 'John' or (votes > 100 and title <> 'Admin')

Exists 声明

whereExists 方法允许你编写 where exists SQL 子句。whereExists
方法接收一个 Closure
参数,那么些闭包会接收一个询问生成器实例,那允许你在 “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
)

数据库:查询生成器

更新

自然,除了新增记录之外,查询生成器也提供了为数据库中设有的记录更新的
update 方法。update 方法像 insert
方法同样,接收一个键值对所构成的数组来进展列值的创新。你能够在利用
update 查询时使用 where 子句:

DB::table('users')
  ->where('id', 1)
  ->update(['votes' => 1]);

增量 / 递减

询问生成器也提供部分利于的艺术来对列的值举行增量和递减。那只是一种高效的方式,用来提供比手动写入
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']);

排序,分组,限制 & 位移

orderBy

orderBy 方法允许你对给定列的询问结果开展排序。orderBy
所接受的率先个参数应该是您期望进行排序的列,而第三个参数应该是你控制开展排序的趋向,它们应该是
asc 或者 desc:

$users = DB::table('users')
           ->orderBy('name', 'desc')
           ->get();

inRandomOrder

inRandomOrder
方法可以用来对查询的结果进行任意排序。比如,你可以行使这一个艺术来随便的得到用户:

$randomUser = DB::table('users')
                ->inRandomOrder()
                ->first();

groupBy / having / havingRaw

groupByhaving 方法可以用来对查询结果开展分组。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

您可以拔取 takeskip
方法来限制查询所重临结果的数额和在询问中跳过早晚的多少(offset):

$users = DB::table('users')->skip(10)->take(5)->get();

简介

Laravel
的数据库查询生成器提供了一种便利流利的接口来营造和运行数据库查询。它可以用来在利用中提供执行大部分的数据库操作,并且它可以在所有扶助的数据库系统中展开合营。

注意:Laravel 的查询生成器使用了 PDO 参数绑定来针对可能的 SQL
注入攻击。所以那里不需求手动的去清洗作为绑定所传递的字符串。

悲观锁

询问生成器也提供了一部分方法来扶助你在 select
申明中完毕“悲观锁”。你可以在询问中利用 sharedLock
方法来运转“共享锁”。共享锁可以确保所选定的行在业务提交前不会被涂改:

DB::table('users')->where('votes', '>', 100)->sharedLock()->get();

其余,你也得以应用 lockForUpdate
方法。更新锁可以戒备行被改动或者被另统计享锁所选中:

DB::table('users')->where('votes', '>', 100)->lockForUpdate()->get();

合计

查询生成器也提供了各类合计的措施。比如 countmaxminavg,和
sum。你可以在查询创设后调用那么些办法:

$users = DB::table('users')->count();

$price = DB::table('orders')->max('price');

当然,你可以组合其余约束来打造你的询问:

$price = DB::table('orders')
           ->where('finalized', 1)
           ->avg('price');

插入

询问生成器也为插入记录到数据库中提供了 insert 方法。insert
方法可以接受列名所组成的键值对数组作为参数:

DB::table('users')->insert(
  ['email' => 'john@example.com', 'votes' => 0]
);

您也得以在三遍调用 insert
方法时添加多条记下到数据库中,你必要传递一个嵌套的数组,数组中的每一个数组都代表了数据库中的一行:

DB::table('users')->insert([
  ['email' => 'taylor@example.com', 'votes' => 0],
  ['email' => 'dayle@example.com', 'votes' => 0]
]);

电动递增的 IDs

一旦挑中留存活动递增的 id,你可以选取 insertGetId
方法来插入记录的还要获得 ID:

$id = DB::table('users')->insertGetId(
  ['email' => 'john@example.com', 'votes' => 0]
);

小心:当使用 PostgreSQL 时,insertGetId 方法期望自增的列名为
id。假设您想要检索的 ID 是一个任何列名,你须求传递列名到
insertGetId 方法的第四个参数。

Joins

内一而再注解

询问生成器也足以用来编排 join 申明。为了执行一个基础的 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();

左连接申明

即便您须求实践 left join 来代替 inner join,你可以接纳 leftJoin
方法,leftJoin 方法具有和 join 方法同样的利用办法:

$users = DB::table('users')
           ->leftJoin('posts', 'users.id', '=', 'posts.user_id')
           ->get();

交叉连接申明

您可以动用 crossJoin 方法来进行一个接力的接连操作,你须要为
crossJoin
提供一个你想要交叉连接的表名。交叉连接会扭转第四个表和参与的表的笛Carl积:

$users = DB::table('sizes')
           ->crossJoin('colours')
           ->get();

高级的 Join 声明

你也能够指定更尖端的 join 约束。你可以传递一个 Closure 作为 join
方法的第三个参数。Closure 会接收一个 JoinClause
对象并且该对象允许你指定 join 约束:

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

若是您欣赏在 joins 中选择 where 风格约束,那么您可以在 join 上应用
whereorWhere 方法。该方法会对比列的值而代表直接相比两列:

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

删除

理所当然,查询生成器也提供了从数据库中除去记录的 delete 方法:

DB::table('users')->delete();

您可以在调用 delete 方法从前增进一些 where 子句:

DB::table('users')->where('votes', '>', 100)->delete();

设若您期望消除整个表的数据,你可以利用 truncate
方法,它将免除所有的行并且重置自增的 ID 到 0:

DB::table('users')->truncate();

Unions(联合)

查询生成器也提供了一种高效的点子来将三个查询联合起来。比如,你可以打造一个早先化的查询,然后拔取
union 方法来将其与随后的查询联合起来:

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

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

unionAll 方法也是可用的,并且它与 union 方法具有相同的签证格局。

相关文章