@a5635268
2016-03-20T13:06:28.000000Z
字数 9686
阅读 1780
源码分析与使用笔记
http://laravelacademy.org/post/2942.html
# DB门面
// 取消bootstrap/app.php文件中$app->withFacades()调用前的注释。才能使用DB门面
$data = DB::select('select * from stock where id = ?', [11]);
DB::insert('insert into users (id, name) values (?, ?)', [1, 'Dayle']);
DB::update('update users set votes = 100 where name = ?', ['John']);
DB::delete('delete from users');
// 通用语句
DB::statement('drop table users');
// 自动事务
DB::transaction(function () {
DB::table('users')->update(['votes' => 1]);
DB::table('posts')->delete();
});
// 手动事务
DB::beginTransaction();
DB::rollBack();
DB::commit();
// 多数据库切换,链接名为config/database.php
$users = DB::connection('foo')->select();
// 还可以通过连接实例上的getPdo方法底层原生的 PDO 实例
$pdo = DB::connection()->getPdo();
使用DB门面的事务方法还可以用于控制查询构建器和 Eloquent ORM 的事务。
略,学习完服务定位相关内容再回来看;
// 获取users表上有信息
DB::table('users')->get();
// 获取 where name = 'John' 的一行
DB::table('users')->where('name', 'John')->first();
// 获取列
DB::table('users')->where('name', 'John')->value('email');
DB::table('users')->chunk(100, function($users) {
foreach ($users as $user) {
//块数据处理:在编写处理大量数据库记录的 Artisan 命令的时候非常有用
//返回false来中止组块的运行
return false;
}
});
// 获取数据的列值
$titles = DB::table('user')->lists('username');
// 获取数据的列值,以另外一列的值作为key
DB::table('user')->lists('username','id');
// 聚合函数,支持count, max, min, avg, 和 sum
$users = DB::table('users')->count();
$price = DB::table('orders')->max('price');
// field
DB::table('users')->select('name', 'email as user_email')->get();
DB::table('users')->distinct()->get();
// 再已有的field后再追加field
$query = DB::table('user')->select('username'); // 返回一个对象
$users = $query->addSelect('nickname')->get();
// 在构建查询器重通过DB::raw方法使用原生sql
$users = DB::table('users')
->select(DB::raw('count(*) as user_count, status'))
->where('status', '<>', 1)
->groupBy('status')
->get();
# join
DB::table('users')
->join('contacts', 'users.id', '=', 'contacts.user_id')
->join('orders', 'users.id', '=', 'orders.user_id')
->select('users.*', 'contacts.phone', 'orders.price')
->get();
DB::table('users')
->leftJoin('posts', 'users.id', '=', 'posts.user_id')
->get();
DB::table('order')->join(
'order_goods' , function ($join){
$join->on('order.id' , '=' , 'order_goods.order_id');
}
)->limit(1)->get();
DB::table('users')
->join('contacts', function ($join) {
$join->on('users.id', '=', 'contacts.user_id')
->where('contacts.user_id', '>', 5);
})
->get();
// Union
$first = DB::table('users')
->whereNull('first_name');
$users = DB::table('users')
->whereNull('last_name')
->union($first)
->get();
//第二个参数是一个数据库系统支持的任意操作符
DB::table('users')->where('votes', '=', 100)->get();
// 如果你只是简单比较列值和给定数值是否相等,可以将数值直接作为where方法的第二个参数
DB::table('users')->where('votes', 100)->get();
// or
DB::table('users')
->where('votes', '>', 100)
->orWhere('name', 'John')
->get();
// Between
DB::table('users')
->whereBetween('votes', [1, 100])->get(); // whereNotBetween
// in
DB::table('users')
->whereIn('id', [1, 2, 3]) //whereNotIn
->get();
// null
DB::table('users')
->whereNull('updated_at') //whereNull/whereNotNull
->get();
// 参数分组
DB::table('users')
->where('name', '=', 'John')
->orWhere(function ($query) {
$query->where('votes', '>', 100)
->where('title', '<>', 'Admin');
})
->get();
// select * from users where name = 'John' or (votes > 100 and title <> 'Admin')
// whereExists
DB::table('users')
->whereExists(function ($query) {
$query->select(DB::raw(1))
->from('orders')
->whereRaw('orders.user_id = users.id');
})
->get();
// select * from users where exists ( select 1 from orders where orders.user_id = users.id )
// orderBy
DB::table('users')
->orderBy('name', 'desc')
->get();
// groupBy / having / havingRaw
DB::table('users')
->groupBy('account_id')
->having('account_id', '>', 100)
->get();
DB::table('orders')
->select('department', DB::raw('SUM(price) as total_sales'))
->groupBy('department')
->havingRaw('SUM(price) > 2500')
->get();
// skip / take offset,limit
DB::table('users')->skip(10)->take(5)->get();
# 插入
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]
]);
// 获得自增ID
$id = DB::table('users')->insertGetId(
['email' => 'john@example.com', 'votes' => 0]
);
# 更新
DB::table('users')->increment('votes');
DB::table('users')->increment('votes', 5);
DB::table('users')->decrement('votes');
DB::table('users')->decrement('votes', 5);
// 对指定的额外值进行更新; votes+1 name=John
DB::table('users')->increment('votes', 1, ['name' => 'John']);
# 删除
DB::table('users')->delete(); //删除所有记录,但自增值依旧
DB::table('users')->truncate(); //清空所有记录,自增值变为0
DB::table('users')->where('votes', '<', 100)->delete();
# 悲观锁
//使用sharedLock方法从而在运行语句时带一把”共享锁“。共享锁可以避免被选择的行被修改直到事务提交:
DB::table('users')->where('votes', '>', 100)->sharedLock()->get();
//使用lockForUpdate方法。“for update”锁避免选择行被其它共享锁修改或删除:
DB::table('users')->where('votes', '>', 100)->lockForUpdate()->get();
http://laravelacademy.org/post/2965.html
也就是一些表的操作
http://laravelacademy.org/post/2976.html
http://laravelacademy.org/post/2995.html
如果可以的话,尽量把数据的调用以及处理都放在model里面;
查
$data = Order::all();
foreach($data as $v){
//输出特定列
echo $v -> order_sn;
echo '<br />';
}
// 增加约束
App\Flight::where('active', 1)
->orderBy('name', 'desc')
->take(10)
->get();
// all和get返回值是Illuminate\Database\Eloquent\Collection的一个实例,Collection类提供了多个有用的函数来处理Eloquent结果
//组块结果集
Flight::chunk(200, function ($flights) {
foreach ($flights as $flight) {
//
}
});
# ↓↓ 返回单个模型实例而不是返回模型集合
// 通过主键获取模型...
$flight = Flight::find(1);
// 获取匹配查询条件的第一个模型...
$flight = Flight::where('active', 1)->first();
# ↓↓没结果时就抛出错误
$model = Flight::findOrFail(1);
$model = Flight::where('legs', '>', 100)->firstOrFail();
# 获取聚合
Flight::where('active', 1)->count();
DML
# 插入
$flight = new Flight;
$flight->name = $request->name;
$flight->save();
# 更新
$flight = App\Flight::find(1);
$flight->name = 'New Flight Name';
$flight->save();
Flight::where('active', 1)
->where('destination', 'San Diego')
->update(['delayed' => 1]);
# 批量赋值,前提是必须指定黑白名单
Flight::create(['name' => 'Flight 10']);
// 通过属性获取航班, 如果不存在则创建...
$flight = App\Flight::firstOrCreate(['name' => 'Flight 10']);
// 通过属性获取航班, 如果不存在初始化一个新的实例,注意此时并没有持久化到数据库中,你还需要调用save方法手动持久化
$flight = App\Flight::firstOrNew(['name' => 'Flight 10']);
# 删除
$flight = App\Flight::find(1);
$flight->delete();
// 根据主键删除
App\Flight::destroy(1);
App\Flight::destroy([1, 2, 3]);
App\Flight::destroy(1, 2, 3);
// 通过查询删除
$deletedRows = App\Flight::where('active', 0)->delete();
软删除: http://laravelacademy.org/post/2995.html#ipt_kb_toc_2995_17;
查询作用域: 简单的说就是为查询封装好where条件
http://laravelacademy.org/post/2995.html#ipt_kb_toc_2995_19
事件: 简单的说就是回调,creating, created, updating, updated, saving, saved,deleting, deleted, restoring, restored; ing在前,ed在后;
http://laravelacademy.org/post/2995.html#ipt_kb_toc_2995_22
研究完服务提供者以后再过来看;
一对一: http://laravelacademy.org/post/3011.html#one-one
$phone = User::find(1)->phone;
return $this->hasOne('App\Phone', 'foreign_key', 'local_key');
return $this->belongsTo('App\User', 'foreign_key', 'other_key');
一对多: http://laravelacademy.org/post/3011.html#one-many
$comments = App\Post::find(1)->comments()->where('title', 'foo')->first();
return $this->hasMany('App\Comment', 'foreign_key', 'local_key');
return $this->belongsTo('App\Post', 'foreign_key', 'other_key');
多对多: http://laravelacademy.org/post/3011.html#many-many
$roles = App\User::find(1)->roles()->orderBy('name')->get();
return $this->belongsToMany('App\Role', 'user_roles', 'user_id', 'role_id'); // 相对关系都可以用一个方法来搞定;
return $this->belongsToMany('App\Role')->withPivot('column1', 'column2');
$role->pivot->created_at; //可以使用模型上的pivot属性访问中间表,我们获取到的每一个Role模型都被自动赋上了pivot属性。该属性包含一个代表中间表的模型,并且可以像其它 Eloquent 模型一样使用。
远层的一对多: http://laravelacademy.org/post/3011.html#has-many-through
class Country extends Model{
/**
* 获取指定国家的所有文章
*/
public function posts()
{
// user -> country -> post
return $this->hasManyThrough('App\Post', 'App\User', 'country_id', 'user_id');
}
}
多态关联: http://laravelacademy.org/post/3011.html#polymorphic-relations
一对多,多的那张表有多个类别的数据; 如果点赞表,有对文章的点赞也有对评论的点赞;
likeable_type
一定要是半限定命名空间,但是程序里面一般都不这样做;
# 动态属性获得
App\User::find(1)->posts
// 获取所有至少有一条评论的文章...
$posts = App\Post::has('comments')->get();
// 获取所有至少有三条评论的文章...
$posts = Post::has('comments', '>=', 3)->get();
// 获取所有至少有一条评论获得投票的文章...
$posts = Post::has('comments.votes')->get();
// 获取所有至少有一条评论包含foo字样的文章
// 可以使用whereHas和orWhereHas方法将where条件放到has查询上,这些方法允许你添加自定义条件约束到关联关系条件约束
$posts = Post::whereHas('comments', function ($query) {
$query->where('content', 'like', 'foo%');
})->get();
# 渴求式加载
/*
缓解了N+1查询问题
select * from books
select * from authors where id in (1, 2, 3, 4, 5, ...)
*/
$books = App\Book::with('author')->get();
// 渴求式加载多个关联关系
$books = App\Book::with('author', 'publisher')->get();
// 嵌套的渴求式加载
$books = App\Book::with('author.contacts')->get();
// 带条件约束的渴求式加载
$users = App\User::with(['posts' => function ($query) {
// 只渴求式加载 title 包含 first 的文章
$query->where('title', 'like', '%first%');
}])->get();
// 懒惰渴求式加载
$books = App\Book::all();
if ($someCondition) {
//动态决定是否加载关联模型
$books->load('author', 'publisher');
}
$books->load(['author' => function ($query) {
$query->orderBy('published_date', 'asc');
}]);
// 插入新的Comment到Post模型,save方法会自动添加post_id值到新的Comment模型
$comment = new App\Comment(['message' => 'A new comment.']);
$post = App\Post::find(1);
$post->comments()->save($comment);
// 保存多个关联模型
$post->comments()->saveMany([
new App\Comment(['message' => 'A new comment.']),
new App\Comment(['message' => 'Another comment.']),
]);
// 还可以使用create方法,该方法接收属性数组、创建模型、然后插入数据库。
$comment = $post->comments()->create([
'message' => 'A new comment.',
]);
# save & 多对多关联
App\User::find(1)->roles()->save($role, ['expires' => $expires]);
# 更新[属于]关联
$account = App\Account::find(10);
$user->account()->associate($account); // 该方法会在子模型设置外键
$user->save();
// 移除关联
$user->account()->dissociate();
$user->save();
# 多对多关联
// ↓↓附加角色到用户上
$user = App\User::find(1);
$user->roles()->attach($roleId);
//以数组形式传递额外被插入数据到中间表
$user->roles()->attach($roleId, ['expires' => $expires]);
// 从指定用户中移除角色...
$user->roles()->detach($roleId);
// 从指定用户移除所有角色...
$user->roles()->detach();
// 还接收数组形式的 ID 作为输入
$user = App\User::find(1);
$user->roles()->detach([1, 2, 3]);
$user->roles()->attach([1 => ['expires' => $expires], 2, 3]);
// sync方法接收数组形式的ID并将其放置到中间表,任何不在该数组中的ID对应记录将会从中间表中移除。因此,该操作完成后,只有在数组中的ID对应记录还存在于中间表;
$user->roles()->sync([1, 2, 3]);
$user->roles()->sync([1 => ['expires' => true], 2, 3]);
# 触发父级时间戳
// 当一个模型属于另外一个时,例如Comment属于Post,子模型更新时父模型的时间戳也被更新
// 在model层指明要触发的所有关联关系
protected $touches = ['post'];