天天看點

3分鐘短文:Laravel查詢構造器,告别手寫SQL的艱苦歲月

引言

鑒于上一章标題引起一些開發同學的巨大興趣,本文我們接着此種行文方式繼續我們的“Laravel宇宙”系列文章。

我們在前一些章節,相繼使用遷移建立了資料庫結構,使用seeder為資料庫填充了假資料,現在我們要對資料進行操作了。

哪些操作?增删改查!

3分鐘短文:Laravel查詢構造器,告别手寫SQL的艱苦歲月

本文先不說模型,說說直接的查詢構造器,說說怎麼把資料篩選出來,這用的應該是最多的了。

代碼時間

說起柔順,你想起來什麼?是撸代碼,沒錯,就是它。

大家看看下面這個代碼寫法柔順不柔順:

$users = DB::select(['table' => 'users', 'where' => ['type' => 'donor']]);           

我們說撸代碼,是有一個從前到後,絲滑連貫的感受的,上面這段不柔順,它在各個參數位置傳入了各種結構的資料,

不僅看上去亂,寫上去亂,連代碼自己都覺得亂。

下面是laravel裡用的最多的寫法:

$users = DB::table('users')->where('type', 'donor')->get();           

這些是不是順多了,一氣呵成,要的就是這個感覺。

為了示範查詢構造器的功能用法,我們直接使用 DB 門面建立 QueryBuilder 對象。比如執行原生的語句:

DB::statement('drop table users')           

還有參數綁定的方式傳入SQL語句:

DB::select('select * from contacts where validated = ?', [true]);           

這種是按照參數順序依次綁定的,還可以使用占位符和鍵值對的方式:

$usersOfType = DB::select('select * from users where type = :type', ['type' => $userType]);           

這樣綁定的參數就不會擔心傳入的次序了。

我們引入查詢構造器,引入模型,就是為了擺脫繁雜的SQL文法,這裡又傳入原生語句,不提倡!

寫一條不附加任何限制條件的查詢:

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

還有複雜的多表聯合查詢,使用 INNER JOIN 方式:

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

上面這個寫法就是我們常用的SQL寫法,生成的SQL語句如下:

SELECT * FROM `users` INNER JOIN `contacts` ON `user`.`id` = `contacts`.`user_id` WHERE `contacts`.`type` = `valid`;           

對于寫操作,我們也使用參數位置綁定的方式展示:

DB::insert('insert into contacts (name, email) values (?, ?)',['sally', '[email protected]']);           

這一條是建立新的資料條目,還有更新資料:

$countUpdated = DB::update('update contacts set status = ? where id = ?',['valie', $id]);           

和按照條件删除條目:

$countDeleted = DB::delete('delete from contacts where archived = ?',[true]);           

為了程式設計愉悅感,還是回歸我們的laravel推薦的鍊式操作的方式來示範更多更複雜的功能。舉例一些正常的查詢:

$emails = DB::table('contacts')->select('email', 'email2 as second_email')->get();           

select 方法用于指定SQL傳回哪些列。可以指定多個,也可以使用 addSelect 追加:

$emails = DB::table('contacts')->select('email')->addSelect('email2 as second_email')->get();           

多個限制條件的查詢:

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

複雜的查詢莫過于使用多表聯合查詢,使用子查詢,使用比較繞的or查詢,我們對or查詢舉兩個例子,

大家在調試的時候,一定要對自己寫的代碼列印一下最終生成的SQL語句反複檢查和測試,以降低故障。

比如兩個條件:

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

這一條要求要麼vip是true,要麼created_at字段在一天以内。還有更複雜的,需要使用閉包的方式組裝:

$contacts = DB::table('contacts')
    ->where('vip', true)
    ->orWhere(function ($query) {
        $query->where('created_at', '>', Carbon::now()->subDay())
        ->where('trial', false);
    })
    ->get();           

上面的代碼主旨上還是兩個條件的 OR,隻不過第二個條件包含更多的限制。生成的語句應該是下面這樣的:

SELECT * FROM contacts WHERE vip = 1 OR (trial = 0 AND created_at > '2020-10-30 11:00:00');           

好吧,查詢的用法先介紹到這兒,更多的查詢,我們後面的代碼會用的很多,再給大家慢慢細講。

寫在最後

本文輕描淡寫地講解了laravel中的查詢構造器,講了一個比較複雜的OR查詢,因為使用閉包組裝WHERE限制條件,是以會有些難以了解,

不過對比列印生成的SQL語句後,大家應該會豁然開朗!

Happy coding :-)

我是 @程式員小助手 ,專注程式設計知識,圈子動态的IT領域原創作者