從一張表中取出所有行
在查詢之前,使用DB
門面的table
方法,table
方法爲給定表返回一個查詢構建器,允許你在查詢上鍊接更多約束條件並最終返回查詢結果。在本例中,我們使用get
方法獲取表中所有記錄:
<?php namespace App\Http\Controllers; use DB; use App\Http\Controllers\Controller; class UserController extends Controller{ /** * 顯示用戶列表 * * @return Response */ public function index() { $users = DB::table('users')->get(); return view('user.index', ['users' => $users]); } }
和原生查詢一樣,get
方法返回結果集的數組,其中每一個結果都是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');
從一張表中獲取組塊結果集
如果你需要處理成千上百條數據庫記錄,可以考慮使用chunk
方法,該方法一次獲取結果集的一小塊,然後填充每一小塊數據到要處理的閉包,該方法在編寫處理大量數據庫記錄的 Artisan 命令的時候非常有用。比如,我們可以將處理全部 users 表數據處理成一次處理 100 記錄的小組塊:
DB::table('users')->chunk(100, function($users) { foreach ($users as $user) { // } });
你可以通過從閉包函數中返回false來中止組塊的運行:
DB::table('users')->chunk(100, function($users) { // 處理結果集... return false; });
獲取數據列值列表
如果想要獲取包含單個列值的數組,可以使用lists
方法,在本例中,我們獲取所有title
的數組:
$titles = DB::table('roles')->lists('title'); foreach ($titles as $title) { echo $title; }
在還可以在返回數組中爲列值指定更多的自定義鍵(該自定義鍵必須是該表的其它字段列名,否則會報錯):
$roles = DB::table('roles')->lists('title', 'name'); foreach ($roles as $name => $title) { echo $title; }
聚合函數
隊列構建器還提供了很多聚合方法,比如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');
3、查詢(Select)
指定查詢子句
當然,我們並不總是想要獲取數據表的所有列,使用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 注入。想要創建一個原生表達式,可以使用 DB::raw
方法:
$users = DB::table('users') ->select(DB::raw('count(*) as user_count, status')) ->where('status', '<>', 1) ->groupBy('status') ->get();
4、連接(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();
左連接
如果你是想要執行“左連接”而不是“內連接”,可以使用leftJoin
方法。該方法和join
方法的使用方法一樣:
$users = DB::table('users') ->leftJoin('posts', 'users.id', '=', 'posts.user_id') ->get();
高級連接語句
你還可以指定更多的高級連接子句,傳遞一個閉包到join
方法作爲該方法的第2個參數,該閉包將會返回允許你指定join
子句約束的JoinClause
對象:
DB::table('users') ->join('contacts', function ($join) { $join->on('users.id', '=', 'contacts.user_id')->orOn(...); }) ->get();
如果你想要在連接中使用“where”風格的子句,可以在查詢中使用where
和orWhere
方法。這些方法將會將列和值進行比較而不是列和列進行比較:
DB::table('users') ->join('contacts', function ($join) { $join->on('users.id', '=', 'contacts.user_id') ->where('contacts.user_id', '>', 5); }) ->get();
5、聯合(Union)
查詢構建器還提供了一條“聯合”兩個查詢的快捷方式,比如,你要創建一個獨立的查詢,然後使用union
方法將其和第二個查詢進行聯合:
$first = DB::table('users') ->whereNull('first_name'); $users = DB::table('users') ->whereNull('last_name') ->union($first) ->get();
unionAll
方法也是有效的,並且和union
有同樣的使用方法。
6、Where子句
簡單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();
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();
高級Where子句
參數分組
有時候你需要創建更加高級的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')
exists語句
whereExists
方法允許你編寫where exist
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 )
7、排序、分組、限定
orderBy
orderBy
方法允許你通過給定列對結果集進行排序,orderBy
的第一個參數應該是你希望排序的列,第二個參數控制着排序的方向——asc或desc:
$users = DB::table('users') ->orderBy('name', 'desc') ->get();
groupBy / having / havingRaw
groupBy
和having
方法用於對結果集進行分組,having
方法和where
方法的用法類似:
$users = DB::table('users') ->groupBy('account_id') ->having('account_id', '>', 100) ->get();
havingRaw
方法可以用於設置原生字符串作爲having
子句的值,例如,我們要找到所有售價大於$2500
的部分:
$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();