[ Laravel 5.2 文檔 ] 數據庫 —— 查詢構建器

從一張表中取出所有行

在查詢之前,使用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;
}

聚合函數

隊列構建器還提供了很多聚合方法,比如countmaxminavg, 和 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”風格的子句,可以在查詢中使用whereorWhere方法。這些方法將會將列和值進行比較而不是列和列進行比較:

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 existSQL子句,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

groupByhaving方法用於對結果集進行分組,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

想要限定查詢返回的結果集的數目,或者在查詢中跳過給定數目的結果,可以使用skiptake方法:

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


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章