@a5635268
2016-03-20T05:06:28.000000Z
字数 9686
阅读 1991
源码分析与使用笔记
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');// 获取数据的列值,以另外一列的值作为keyDB::table('user')->lists('username','id');// 聚合函数,支持count, max, min, avg, 和 sum$users = DB::table('users')->count();$price = DB::table('orders')->max('price');// fieldDB::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();# joinDB::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();// orDB::table('users')->where('votes', '>', 100)->orWhere('name', 'John')->get();// BetweenDB::table('users')->whereBetween('votes', [1, 100])->get(); // whereNotBetween// inDB::table('users')->whereIn('id', [1, 2, 3]) //whereNotIn->get();// nullDB::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')// whereExistsDB::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 )// orderByDB::table('users')->orderBy('name', 'desc')->get();// groupBy / having / havingRawDB::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,limitDB::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=JohnDB::table('users')->increment('votes', 1, ['name' => 'John']);# 删除DB::table('users')->delete(); //删除所有记录,但自增值依旧DB::table('users')->truncate(); //清空所有记录,自增值变为0DB::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 -> postreturn $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 booksselect * 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'];