最近小編在學(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');