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

程式設計師小助手發表於2020-10-30

引言

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

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

哪些操作?增刪改查!

img

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

程式碼時間

說起柔順,你想起來什麼?是擼程式碼,沒錯,就是它。

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

$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', 'sally@me.com']);

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

$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領域原創作者

本作品採用《CC 協議》,轉載必須註明作者和本文連結
write-less-do-more-make-you-out-of-door

相關文章