[关闭]
@a5635268 2016-03-20T13:06:28.000000Z 字数 9686 阅读 1780

Lumen的数据库链接

源码分析与使用笔记


数据库

http://laravelacademy.org/post/2942.html

  1. # DB门面
  2. // 取消bootstrap/app.php文件中$app->withFacades()调用前的注释。才能使用DB门面
  3. $data = DB::select('select * from stock where id = ?', [11]);
  4. DB::insert('insert into users (id, name) values (?, ?)', [1, 'Dayle']);
  5. DB::update('update users set votes = 100 where name = ?', ['John']);
  6. DB::delete('delete from users');
  7. // 通用语句
  8. DB::statement('drop table users');
  9. // 自动事务
  10. DB::transaction(function () {
  11. DB::table('users')->update(['votes' => 1]);
  12. DB::table('posts')->delete();
  13. });
  14. // 手动事务
  15. DB::beginTransaction();
  16. DB::rollBack();
  17. DB::commit();
  18. // 多数据库切换,链接名为config/database.php
  19. $users = DB::connection('foo')->select();
  20. // 还可以通过连接实例上的getPdo方法底层原生的 PDO 实例
  21. $pdo = DB::connection()->getPdo();

使用DB门面的事务方法还可以用于控制查询构建器和 Eloquent ORM 的事务。

监听查询事件

略,学习完服务定位相关内容再回来看;

查询构建器

查询

  1. // 获取users表上有信息
  2. DB::table('users')->get();
  3. // 获取 where name = 'John' 的一行
  4. DB::table('users')->where('name', 'John')->first();
  5. // 获取列
  6. DB::table('users')->where('name', 'John')->value('email');
  7. DB::table('users')->chunk(100, function($users) {
  8. foreach ($users as $user) {
  9. //块数据处理:在编写处理大量数据库记录的 Artisan 命令的时候非常有用
  10. //返回false来中止组块的运行
  11. return false;
  12. }
  13. });
  14. // 获取数据的列值
  15. $titles = DB::table('user')->lists('username');
  16. // 获取数据的列值,以另外一列的值作为key
  17. DB::table('user')->lists('username','id');
  18. // 聚合函数,支持count, max, min, avg, 和 sum
  19. $users = DB::table('users')->count();
  20. $price = DB::table('orders')->max('price');
  21. // field
  22. DB::table('users')->select('name', 'email as user_email')->get();
  23. DB::table('users')->distinct()->get();
  24. // 再已有的field后再追加field
  25. $query = DB::table('user')->select('username'); // 返回一个对象
  26. $users = $query->addSelect('nickname')->get();
  27. // 在构建查询器重通过DB::raw方法使用原生sql
  28. $users = DB::table('users')
  29. ->select(DB::raw('count(*) as user_count, status'))
  30. ->where('status', '<>', 1)
  31. ->groupBy('status')
  32. ->get();
  33. # join
  34. DB::table('users')
  35. ->join('contacts', 'users.id', '=', 'contacts.user_id')
  36. ->join('orders', 'users.id', '=', 'orders.user_id')
  37. ->select('users.*', 'contacts.phone', 'orders.price')
  38. ->get();
  39. DB::table('users')
  40. ->leftJoin('posts', 'users.id', '=', 'posts.user_id')
  41. ->get();
  42. DB::table('order')->join(
  43. 'order_goods' , function ($join){
  44. $join->on('order.id' , '=' , 'order_goods.order_id');
  45. }
  46. )->limit(1)->get();
  47. DB::table('users')
  48. ->join('contacts', function ($join) {
  49. $join->on('users.id', '=', 'contacts.user_id')
  50. ->where('contacts.user_id', '>', 5);
  51. })
  52. ->get();
  53. // Union
  54. $first = DB::table('users')
  55. ->whereNull('first_name');
  56. $users = DB::table('users')
  57. ->whereNull('last_name')
  58. ->union($first)
  59. ->get();
  60. //第二个参数是一个数据库系统支持的任意操作符
  61. DB::table('users')->where('votes', '=', 100)->get();
  62. // 如果你只是简单比较列值和给定数值是否相等,可以将数值直接作为where方法的第二个参数
  63. DB::table('users')->where('votes', 100)->get();
  64. // or
  65. DB::table('users')
  66. ->where('votes', '>', 100)
  67. ->orWhere('name', 'John')
  68. ->get();
  69. // Between
  70. DB::table('users')
  71. ->whereBetween('votes', [1, 100])->get(); // whereNotBetween
  72. // in
  73. DB::table('users')
  74. ->whereIn('id', [1, 2, 3]) //whereNotIn
  75. ->get();
  76. // null
  77. DB::table('users')
  78. ->whereNull('updated_at') //whereNull/whereNotNull
  79. ->get();
  80. // 参数分组
  81. DB::table('users')
  82. ->where('name', '=', 'John')
  83. ->orWhere(function ($query) {
  84. $query->where('votes', '>', 100)
  85. ->where('title', '<>', 'Admin');
  86. })
  87. ->get();
  88. // select * from users where name = 'John' or (votes > 100 and title <> 'Admin')
  89. // whereExists
  90. DB::table('users')
  91. ->whereExists(function ($query) {
  92. $query->select(DB::raw(1))
  93. ->from('orders')
  94. ->whereRaw('orders.user_id = users.id');
  95. })
  96. ->get();
  97. // select * from users where exists ( select 1 from orders where orders.user_id = users.id )
  98. // orderBy
  99. DB::table('users')
  100. ->orderBy('name', 'desc')
  101. ->get();
  102. // groupBy / having / havingRaw
  103. DB::table('users')
  104. ->groupBy('account_id')
  105. ->having('account_id', '>', 100)
  106. ->get();
  107. DB::table('orders')
  108. ->select('department', DB::raw('SUM(price) as total_sales'))
  109. ->groupBy('department')
  110. ->havingRaw('SUM(price) > 2500')
  111. ->get();
  112. // skip / take offset,limit
  113. DB::table('users')->skip(10)->take(5)->get();

非查询

  1. # 插入
  2. DB::table('users')->insert(
  3. ['email' => 'john@example.com', 'votes' => 0]);
  4. DB::table('users')->insert([
  5. ['email' => 'taylor@example.com', 'votes' => 0],
  6. ['email' => 'dayle@example.com', 'votes' => 0]
  7. ]);
  8. // 获得自增ID
  9. $id = DB::table('users')->insertGetId(
  10. ['email' => 'john@example.com', 'votes' => 0]
  11. );
  12. # 更新
  13. DB::table('users')->increment('votes');
  14. DB::table('users')->increment('votes', 5);
  15. DB::table('users')->decrement('votes');
  16. DB::table('users')->decrement('votes', 5);
  17. // 对指定的额外值进行更新; votes+1 name=John
  18. DB::table('users')->increment('votes', 1, ['name' => 'John']);
  19. # 删除
  20. DB::table('users')->delete(); //删除所有记录,但自增值依旧
  21. DB::table('users')->truncate(); //清空所有记录,自增值变为0
  22. DB::table('users')->where('votes', '<', 100)->delete();
  23. # 悲观锁
  24. //使用sharedLock方法从而在运行语句时带一把”共享锁“。共享锁可以避免被选择的行被修改直到事务提交:
  25. DB::table('users')->where('votes', '>', 100)->sharedLock()->get();
  26. //使用lockForUpdate方法。“for update”锁避免选择行被其它共享锁修改或删除:
  27. DB::table('users')->where('votes', '>', 100)->lockForUpdate()->get();

数据库迁移

http://laravelacademy.org/post/2965.html

也就是一些表的操作

数据填充

http://laravelacademy.org/post/2976.html

Eloquent ORM

起步

http://laravelacademy.org/post/2995.html

如果可以的话,尽量把数据的调用以及处理都放在model里面;

  1. $data = Order::all();
  2. foreach($data as $v){
  3. //输出特定列
  4. echo $v -> order_sn;
  5. echo '<br />';
  6. }
  7. // 增加约束
  8. App\Flight::where('active', 1)
  9. ->orderBy('name', 'desc')
  10. ->take(10)
  11. ->get();
  12. // all和get返回值是Illuminate\Database\Eloquent\Collection的一个实例,Collection类提供了多个有用的函数来处理Eloquent结果
  13. //组块结果集
  14. Flight::chunk(200, function ($flights) {
  15. foreach ($flights as $flight) {
  16. //
  17. }
  18. });
  19. # ↓↓ 返回单个模型实例而不是返回模型集合
  20. // 通过主键获取模型...
  21. $flight = Flight::find(1);
  22. // 获取匹配查询条件的第一个模型...
  23. $flight = Flight::where('active', 1)->first();
  24. # ↓↓没结果时就抛出错误
  25. $model = Flight::findOrFail(1);
  26. $model = Flight::where('legs', '>', 100)->firstOrFail();
  27. # 获取聚合
  28. Flight::where('active', 1)->count();

DML

  1. # 插入
  2. $flight = new Flight;
  3. $flight->name = $request->name;
  4. $flight->save();
  5. # 更新
  6. $flight = App\Flight::find(1);
  7. $flight->name = 'New Flight Name';
  8. $flight->save();
  9. Flight::where('active', 1)
  10. ->where('destination', 'San Diego')
  11. ->update(['delayed' => 1]);
  12. # 批量赋值,前提是必须指定黑白名单
  13. Flight::create(['name' => 'Flight 10']);
  14. // 通过属性获取航班, 如果不存在则创建...
  15. $flight = App\Flight::firstOrCreate(['name' => 'Flight 10']);
  16. // 通过属性获取航班, 如果不存在初始化一个新的实例,注意此时并没有持久化到数据库中,你还需要调用save方法手动持久化
  17. $flight = App\Flight::firstOrNew(['name' => 'Flight 10']);
  18. # 删除
  19. $flight = App\Flight::find(1);
  20. $flight->delete();
  21. // 根据主键删除
  22. App\Flight::destroy(1);
  23. App\Flight::destroy([1, 2, 3]);
  24. App\Flight::destroy(1, 2, 3);
  25. // 通过查询删除
  26. $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

  1. $phone = User::find(1)->phone;
  2. return $this->hasOne('App\Phone', 'foreign_key', 'local_key');
  3. return $this->belongsTo('App\User', 'foreign_key', 'other_key');

一对多: http://laravelacademy.org/post/3011.html#one-many

  1. $comments = App\Post::find(1)->comments()->where('title', 'foo')->first();
  2. return $this->hasMany('App\Comment', 'foreign_key', 'local_key');
  3. return $this->belongsTo('App\Post', 'foreign_key', 'other_key');

多对多: http://laravelacademy.org/post/3011.html#many-many

  1. $roles = App\User::find(1)->roles()->orderBy('name')->get();
  2. return $this->belongsToMany('App\Role', 'user_roles', 'user_id', 'role_id'); // 相对关系都可以用一个方法来搞定;
  3. return $this->belongsToMany('App\Role')->withPivot('column1', 'column2');
  4. $role->pivot->created_at; //可以使用模型上的pivot属性访问中间表,我们获取到的每一个Role模型都被自动赋上了pivot属性。该属性包含一个代表中间表的模型,并且可以像其它 Eloquent 模型一样使用。

远层的一对多: http://laravelacademy.org/post/3011.html#has-many-through

  1. class Country extends Model{
  2. /**
  3. * 获取指定国家的所有文章
  4. */
  5. public function posts()
  6. {
  7. // user -> country -> post
  8. return $this->hasManyThrough('App\Post', 'App\User', 'country_id', 'user_id');
  9. }
  10. }

多态关联: http://laravelacademy.org/post/3011.html#polymorphic-relations

一对多,多的那张表有多个类别的数据; 如果点赞表,有对文章的点赞也有对评论的点赞;

  1. # 动态属性获得
  2. App\User::find(1)->posts
  3. // 获取所有至少有一条评论的文章...
  4. $posts = App\Post::has('comments')->get();
  5. // 获取所有至少有三条评论的文章...
  6. $posts = Post::has('comments', '>=', 3)->get();
  7. // 获取所有至少有一条评论获得投票的文章...
  8. $posts = Post::has('comments.votes')->get();
  9. // 获取所有至少有一条评论包含foo字样的文章
  10. // 可以使用whereHas和orWhereHas方法将where条件放到has查询上,这些方法允许你添加自定义条件约束到关联关系条件约束
  11. $posts = Post::whereHas('comments', function ($query) {
  12. $query->where('content', 'like', 'foo%');
  13. })->get();
  14. # 渴求式加载
  15. /*
  16. 缓解了N+1查询问题
  17. select * from books
  18. select * from authors where id in (1, 2, 3, 4, 5, ...)
  19. */
  20. $books = App\Book::with('author')->get();
  21. // 渴求式加载多个关联关系
  22. $books = App\Book::with('author', 'publisher')->get();
  23. // 嵌套的渴求式加载
  24. $books = App\Book::with('author.contacts')->get();
  25. // 带条件约束的渴求式加载
  26. $users = App\User::with(['posts' => function ($query) {
  27. // 只渴求式加载 title 包含 first 的文章
  28. $query->where('title', 'like', '%first%');
  29. }])->get();
  30. // 懒惰渴求式加载
  31. $books = App\Book::all();
  32. if ($someCondition) {
  33. //动态决定是否加载关联模型
  34. $books->load('author', 'publisher');
  35. }
  36. $books->load(['author' => function ($query) {
  37. $query->orderBy('published_date', 'asc');
  38. }]);

关联插入

  1. // 插入新的Comment到Post模型,save方法会自动添加post_id值到新的Comment模型
  2. $comment = new App\Comment(['message' => 'A new comment.']);
  3. $post = App\Post::find(1);
  4. $post->comments()->save($comment);
  5. // 保存多个关联模型
  6. $post->comments()->saveMany([
  7. new App\Comment(['message' => 'A new comment.']),
  8. new App\Comment(['message' => 'Another comment.']),
  9. ]);
  10. // 还可以使用create方法,该方法接收属性数组、创建模型、然后插入数据库。
  11. $comment = $post->comments()->create([
  12. 'message' => 'A new comment.',
  13. ]);
  14. # save & 多对多关联
  15. App\User::find(1)->roles()->save($role, ['expires' => $expires]);
  16. # 更新[属于]关联
  17. $account = App\Account::find(10);
  18. $user->account()->associate($account); // 该方法会在子模型设置外键
  19. $user->save();
  20. // 移除关联
  21. $user->account()->dissociate();
  22. $user->save();
  23. # 多对多关联
  24. // ↓↓附加角色到用户上
  25. $user = App\User::find(1);
  26. $user->roles()->attach($roleId);
  27. //以数组形式传递额外被插入数据到中间表
  28. $user->roles()->attach($roleId, ['expires' => $expires]);
  29. // 从指定用户中移除角色...
  30. $user->roles()->detach($roleId);
  31. // 从指定用户移除所有角色...
  32. $user->roles()->detach();
  33. // 还接收数组形式的 ID 作为输入
  34. $user = App\User::find(1);
  35. $user->roles()->detach([1, 2, 3]);
  36. $user->roles()->attach([1 => ['expires' => $expires], 2, 3]);
  37. // sync方法接收数组形式的ID并将其放置到中间表,任何不在该数组中的ID对应记录将会从中间表中移除。因此,该操作完成后,只有在数组中的ID对应记录还存在于中间表;
  38. $user->roles()->sync([1, 2, 3]);
  39. $user->roles()->sync([1 => ['expires' => true], 2, 3]);
  40. # 触发父级时间戳
  41. // 当一个模型属于另外一个时,例如Comment属于Post,子模型更新时父模型的时间戳也被更新
  42. // 在model层指明要触发的所有关联关系
  43. protected $touches = ['post'];
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注