Laravel學(xué)習(xí)篇-數(shù)據(jù)庫(kù)操作和查詢(xún)構(gòu)造器

最近小編在學(xué)習(xí)號(hào)稱(chēng)世界最沤斜叮框架--Laravel。其實(shí)學(xué)習(xí)框架也就是學(xué)習(xí)框架的思想豺瘤! 我想在我的博客中記錄我在laravel學(xué)習(xí)中的一些心得吆倦,歡迎大家關(guān)注我的其他<a >Github博客</a>和<a >CSDN</a>,互相交流坐求!

版本:Laravel 5.2
數(shù)據(jù)庫(kù):mysql 5.7
php:php7.1

數(shù)據(jù)庫(kù)操作和查詢(xún)構(gòu)造器

在Laravel中執(zhí)行數(shù)據(jù)庫(kù)操作有兩種方式蚕泽,一種是使用\DB外觀對(duì)象的靜態(tài)方法直接執(zhí)行sql查詢(xún),另外一種是使用Model類(lèi)的靜態(tài)方法(實(shí)際上也是Facade的實(shí)現(xiàn)瞻赶,使用靜態(tài)訪問(wèn)方式訪問(wèn)Model的方法赛糟,內(nèi)部采用了__callStatic魔術(shù)方法代理了對(duì)成員方法的訪問(wèn)。

查詢(xún)操作#

使用sql語(yǔ)句執(zhí)行select查詢(xún)操作#

$results = DB::select('select * from users where id = ?', [1]);
foreach ($results as $res) {
    echo $res->name;
}

返回結(jié)果為數(shù)組砸逊,數(shù)組中每一個(gè)值為一個(gè)StdClass對(duì)象璧南。
也可以使用命名綁定,推薦使用這種方式师逸,更加清晰一些

$results = DB::select('select * from users where id = :id', ['id' => 1]);

從數(shù)據(jù)表中取得所有的數(shù)據(jù)列#

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

foreach ($users as $user)
{
    var_dump($user->name);
}

從表中查詢(xún)單行/列#

使用first方法返回單行數(shù)據(jù)司倚,該方法返回的是一個(gè)stdClass對(duì)象

$user = DB::table('users')->where('name', 'John')->first();
echo $user->name;

如果只需要一列的值,則可以使用value方法直接獲取單列的值

$email = DB::table('users')->where('name', 'John')->value('email');

從數(shù)據(jù)表中分塊查找數(shù)據(jù)列#

該方法用于數(shù)據(jù)表中有大量的數(shù)據(jù)的操作篓像,每次從結(jié)果集中取出一部分动知,使用閉包函數(shù)進(jìn)行處理,然后再處理下一部分员辩,該命令一般用于Artisan命令行程序中處理大量數(shù)據(jù)盒粮。

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

在閉包函數(shù)中,如果返回false奠滑,則會(huì)停止后續(xù)的處理丹皱。

從數(shù)據(jù)表中查詢(xún)某一列的列表#

比如我們希望查詢(xún)出角色表中所有的title字段值

$titles = DB::table('roles')->pluck('title');

foreach ($titles as $title) {
    echo $title;
}

這里的pluck函數(shù)有兩個(gè)參數(shù)

Collection pluck( string $column, string|null $key = null)

第一個(gè)參數(shù)為要查詢(xún)的列妒穴,第二個(gè)參數(shù)是每一列的key

$roles = DB::table('roles')->pluck('title', 'name');

foreach ($roles as $name => $title) {
    echo $title;
}

聚合函數(shù)#

查詢(xún)構(gòu)造器也提供了一些聚集函數(shù)如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');

指定select查詢(xún)條件#

查詢(xún)指定的列#

$users = DB::table('users')->select('name', 'email as user_email')->get();

如果已經(jīng)指定了select呢簸,但是又希望再次添加一些字段矮台,使用它addSelect方法

$query = DB::table('users')->select('name');
$users = $query->addSelect('age')->get();

查詢(xún)不同的結(jié)果distinct#

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

使用原生表達(dá)式#

使用DB::raw方法可以向查詢(xún)中注入需要的sql片段,但是非常不推薦使用該方法根时,用不好會(huì) 產(chǎn)生sql注入

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

Join操作#

內(nèi)連接 Inner Join#

使用join執(zhí)行內(nèi)連接操作瘦赫,該函數(shù)第一個(gè)參數(shù)為要連接的表名,其它參數(shù)指定了連接約束

$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#
使用leftJoin方法執(zhí)行左連接操作啸箫,參數(shù)和join一樣$users =

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

高級(jí)Join方法#

如果join方法的約束條件比較復(fù)雜耸彪,可以使用閉包函數(shù)的方式指定

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

如果join約束中要使用列值與指定數(shù)組比較,則可以使用where和OrWhere方法

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

Union操作#

要使用union操作忘苛,可以先創(chuàng)建一個(gè)query蝉娜,然后再使用union方法去綁定第二個(gè)query

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

同樣,unionAll方法也是可以使用的扎唾,參數(shù)與union相同召川。

Where查詢(xún)條件#

簡(jiǎn)單的wehere條件#

使用where方法為查詢(xún)?cè)黾觲here條件,該函數(shù)一般需要三個(gè)參數(shù):列名胸遇,操作符(任何數(shù)據(jù)庫(kù)支持的操作符都可以)荧呐,列值。

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

為了方便起見(jiàn)纸镊,如果只提供兩個(gè)參數(shù)倍阐,則默認(rèn)第二個(gè)參數(shù)為=,執(zhí)行相等匹配逗威。

$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條件也可以使用數(shù)組提供:

$users = DB::table('users')->where([
    ['status','1'],
    ['subscribed','<>','1'],
])->get();

OR條件#

如果where條件要使用or操作峰搪,則使用orWhere方法

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

其它where條件#

whereBetween / whereNotBetween#

$users = DB::table('users')
    ->whereBetween('votes', [1, 100])->get();
$users = DB::table('users')
    ->whereNotBetween('votes', [1, 100])->get();

whereIn / whereNotIn#

$users = DB::table('users')
     ->whereIn('id', [1, 2, 3])
     ->get();
$users = DB::table('users')
     ->whereNotIn('id', [1, 2, 3])
     ->get();

whereNull / whereNotNull#

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

高級(jí)where條件#

參數(shù)組(嵌套條件)#

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

上述代碼等價(jià)于下列sql

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

whereExists (where exist)#

DB::table('users')
  ->whereExists(function ($query) {
      $query->select(DB::raw(1))
            ->from('orders')
            ->whereRaw('orders.user_id = users.id');
  })
  ->get();

上述代碼與下列sql等價(jià)

select * from users
where exists (
    select 1 from orders where orders.user_id = users.id
)

JSON類(lèi)型的列查詢(xún)#

MySQL 5.7和Postgres數(shù)據(jù)庫(kù)中提供了新的數(shù)據(jù)類(lèi)型json,對(duì)json提供了原生的支持凯旭,使用->可以對(duì)json列進(jìn)行查詢(xún)概耻。

$users = DB::table('users')
      ->where('options->language', 'en')
      ->get();

$users = DB::table('users')
      ->where('preferences->dining->meal', 'salad')
      ->get();

Ordering, Grouping, Limit, & Offset#

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

$users = DB::table('users')
      ->groupBy('account_id')
      ->having('account_id', '>', 100)
      ->get();

$users = DB::table('orders')
      ->select('department', DB::raw('SUM(price) as total_sales'))
      ->groupBy('department')
      ->havingRaw('SUM(price) > 2500')
      ->get();

要限制查詢(xún)返回的結(jié)果行數(shù),或者是跳過(guò)指定行數(shù)的結(jié)果(OFFSET)罐呼,可以使用skip和take方法

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

插入操作#

使用sql語(yǔ)句執(zhí)行插入#

插入操作與select操作類(lèi)似,使用insert函數(shù)

DB::insert('insert into users (id, name) values (?, ?)', [1, 'Dayle']);

基本插入操作#

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

如果希望插入后能夠獲取新增數(shù)據(jù)的id鞠柄,則可以使用insertGetId方法

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

更新操作#

使用sql語(yǔ)句執(zhí)行更新操作#

執(zhí)行DB中的update后,會(huì)返回 操作影響的數(shù)據(jù)行數(shù)

DB::update('update users set votes = 100 where name = ?',['John']);

基本更新操作#

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

指定列的增減#

DB::table('users')->increment('votes');
DB::table('users')->increment('votes', 5);
DB::table('users')->decrement('votes');
DB::table('users')->decrement('votes', 5);

在執(zhí)行自增/減操作的時(shí)候嫉柴,也可以同時(shí)更新其它列

DB::table('users')->increment('votes', 1, ['name' => 'John']);

刪除操作#

使用sql執(zhí)行刪除#

執(zhí)行DB中的delete后厌杜,會(huì)返回 操作影響的數(shù)據(jù)行數(shù)

DB::delete('delete from users');

基本刪除操作#

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

如果希望truncate整個(gè)表,則使用truncate方法

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

悲觀鎖#

使用sharedLock方法可以避免選定的行在事務(wù)提交之前被修改

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

另外lockForUpdate方法可以避免其它的共享鎖修改或者是選定

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

事務(wù)處理#

使用transaction方法的callback函數(shù)執(zhí)行事務(wù)處理

DB::transaction(function()
{
    DB::table('users')->update(['votes' => 1]);

    DB::table('posts')->delete();
});

在回調(diào)函數(shù)中计螺,拋出任何異常都會(huì)導(dǎo)致事務(wù)回滾
如果需要手動(dòng)管理事務(wù)夯尽,則使用如下函數(shù)

DB::beginTransaction();
DB::rollback();
DB::commit();

使用DB類(lèi)的靜態(tài)方法啟用的事務(wù)不僅對(duì)普通sql查詢(xún)有效侧馅,對(duì)Eloquent ORM同樣有效,因?yàn)樗鼉?nèi)部也是調(diào)用了DB類(lèi)的數(shù)據(jù)庫(kù)連接呐萌。
查看日志記錄#

查看請(qǐng)求執(zhí)行的sql日志記錄,需要先執(zhí)行enableQueryLog開(kāi)啟谊娇,然后執(zhí)行getQueryLog獲取

DB::connection()->enableQueryLog();
$queries = DB::getQueryLog();

其它操作#

執(zhí)行一般的sql語(yǔ)法

DB::statement('drop table users');

監(jiān)聽(tīng)查找事件肺孤,可以用來(lái)對(duì)執(zhí)行的sql進(jìn)行記錄

DB::listen(function($sql, $bindings, $time)
{
    // $query->sql
    // $query->bindings
    // $query->time

});

獲取某個(gè)數(shù)據(jù)庫(kù)連接

$users = DB::connection('foo')->select(...);

如果還不能滿足需求,可以獲取PDO對(duì)象

$pdo = DB::connection()->getPdo();

這樣不管什么操作都可以做了吧

另外含有兩個(gè)方法济欢,用于重新連接到指定數(shù)據(jù)庫(kù)和斷開(kāi)連接

DB::reconnect('foo');
DB::disconnect('foo');
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末赠堵,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子法褥,更是在濱河造成了極大的恐慌茫叭,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,539評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件半等,死亡現(xiàn)場(chǎng)離奇詭異揍愁,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)杀饵,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評(píng)論 3 396
  • 文/潘曉璐 我一進(jìn)店門(mén)莽囤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人切距,你說(shuō)我怎么就攤上這事朽缎。” “怎么了谜悟?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,871評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵话肖,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我葡幸,道長(zhǎng)最筒,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,963評(píng)論 1 295
  • 正文 為了忘掉前任礼患,我火速辦了婚禮是钥,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己绩鸣,他們只是感情好铺峭,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,984評(píng)論 6 393
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著弹囚,像睡著了一般。 火紅的嫁衣襯著肌膚如雪领曼。 梳的紋絲不亂的頭發(fā)上鸥鹉,一...
    開(kāi)封第一講書(shū)人閱讀 51,763評(píng)論 1 307
  • 那天蛮穿,我揣著相機(jī)與錄音,去河邊找鬼毁渗。 笑死践磅,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的灸异。 我是一名探鬼主播府适,決...
    沈念sama閱讀 40,468評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼肺樟!你這毒婦竟也來(lái)了檐春?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤么伯,失蹤者是張志新(化名)和其女友劉穎疟暖,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體田柔,經(jīng)...
    沈念sama閱讀 45,850評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡俐巴,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,002評(píng)論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了凯楔。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片窜骄。...
    茶點(diǎn)故事閱讀 40,144評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖摆屯,靈堂內(nèi)的尸體忽然破棺而出邻遏,到底是詐尸還是另有隱情,我是刑警寧澤虐骑,帶...
    沈念sama閱讀 35,823評(píng)論 5 346
  • 正文 年R本政府宣布准验,位于F島的核電站,受9級(jí)特大地震影響廷没,放射性物質(zhì)發(fā)生泄漏糊饱。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,483評(píng)論 3 331
  • 文/蒙蒙 一颠黎、第九天 我趴在偏房一處隱蔽的房頂上張望另锋。 院中可真熱鬧,春花似錦狭归、人聲如沸夭坪。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,026評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)室梅。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間亡鼠,已是汗流浹背赏殃。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,150評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留间涵,地道東北人仁热。 一個(gè)月前我還...
    沈念sama閱讀 48,415評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像勾哩,于是被迫代替她去往敵國(guó)和親股耽。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,092評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容