diff --git a/blog/laravel/debugbar.md b/blog/laravel/debugbar.md new file mode 100644 index 0000000000000000000000000000000000000000..fe3ae146c9a619f4147395b081c583d167f6cb3d --- /dev/null +++ b/blog/laravel/debugbar.md @@ -0,0 +1,35 @@ +# Debugbar 调试器 + +安装Debugbar + +```bash +composer8 require barryvdh/laravel-debugbar +``` + +生成一个配置文件 +```bash +php8 artisan vendor:publish --provider="Barryvdh\Debugbar\ServiceProvider" +``` + +页面底部的调试工具 + +```php +// @deprecated +// use Barryvdh\Debugbar\Facade as DebugBar; +use Barryvdh\Debugbar\Facades\Debugbar; + +DebugBar::info('信息!'); +``` + +```php +// config/debugbar.php + +// 关闭调试工具 +'enabled' => env('DEBUGBAR_ENABLED', false), +``` + +```php +//手工开启或关闭 +DebugBar::enable(); +DebugBar::disable(); +``` \ No newline at end of file diff --git a/blog/laravel/index.md b/blog/laravel/index.md index 4963271c8adadb3646978864d1108781314f7210..45edf3dc8d097d15255de31de31a8b7ba27ac6aa 100644 --- a/blog/laravel/index.md +++ b/blog/laravel/index.md @@ -36,7 +36,9 @@ dev: [集合 collection](/blog/laravel/collection.md) -[模型的数据集合 ](/blog/laravel/model-collection.md) +[模型的数据集合](/blog/laravel/model-collection.md) -[模型关联 relation ](/blog/laravel/model-relation.md) +[模型关联 relation](/blog/laravel/model-relation.md) + +[模型的关联查询](/blog/laravel/model-relation-query.md) diff --git a/blog/laravel/model-preload.md b/blog/laravel/model-preload.md new file mode 100644 index 0000000000000000000000000000000000000000..1868af78b05dc92d2b36a022b660749136e12452 --- /dev/null +++ b/blog/laravel/model-preload.md @@ -0,0 +1,169 @@ +# 模型的预加载 + +预加载: 解决关联查询中产生的`N+1`次查询带来的资源消耗 + +模型 + +```php + +class User extends Model +{ + protected $table = 'user'; + // 一对多关联 Book 表 + public function books() + { + return $this->hasMany(Book::class, 'user_id', 'id'); + } +} + + +class Book extends Model +{ + protected $table = 'book'; + + // 反向关联 + public function user() + { + return $this->belongsTo(User::class, 'user_id', 'id'); + } +} + +``` + +要获取所有书籍的作者(或拥有者),普通查询方案如下 + +```php +//获取所有书籍列表 +$books = Book::all(); + +//遍历每一本书 +foreach ($books as $book) { + //每一本书的关联用户的姓名 + DebugBar::info($book->user->username); +} +``` + +```sql +-- N+1 条,就是起初获取全部数据的 1 条和,遍历的 N 条 +select * from `book` + +select * from `user` where `user`.`id` = ? limit 1 +select * from `user` where `user`.`id` = ? limit 1 +``` + +使用with()关键字,进行预载入设置,提前将SQL整合 + +```php +//with 关键字预载入 +$books = Book::with('user')->get(); + +foreach ($books as $book) { + DebugBar::info($book->user->username); +} +``` + +```sql +select * from `book` + +select * from `user` where `user`.`id` in (1) +``` + +```php +// 预载入设置指定的列 +$books = Book::with('user:id,name')->get(); +``` + +```sql +select * from `book` + +select `id`, `name` from `user` where `user`.`id` in (1) +``` + +模型中定义默认加载的关联 + +```php +class Book extends Model +{ + protected $table = 'book'; + + // 默认加载的关联 + protected $with = ['user']; + + // 反向关联 + public function user() + { + return $this->belongsTo(User::class, 'user_id', 'id'); + } +} +``` + +预载入筛选 + +```php +Book::with([ + 'user' => function ($query) { + $query->where('id', 1); + } +])->get(); +``` + +```sql +select * from `book` + +select * from `user` where `user`.`id` in (1) and `id` = ? +``` + +延迟预载入 +```php +$books = Book::all(); + +$books->load('user'); +``` + +```sql +select * from `book` + +select * from `user` where `user`.`id` in (1) +``` + +实现延迟关联统计 +```php +$users = User::all(); + +$users->loadCount('book'); +``` + +```sql +select * from `user` + +select `id`, +( + select count(*) from `book` where `user`.`id` = `book`.`user_id` +) as `books_count` +from `user` +where `user`.`id` in (?, ?) +``` + +```json +[ + { + "id": 1, + "name": "曹真", + "age": 23, + "create_time": "2022-07-05 10:32:48", + "update_time": "2022-07-05 10:47:36", + "delete_time": null, + "books_count": 2 + }, + { + "id": 2, + "name": "曹丕", + "age": 21, + "create_time": "2022-07-05 10:36:47", + "update_time": "2022-07-05 10:47:22", + "delete_time": null, + "books_count": 0 + } +] + +``` \ No newline at end of file diff --git a/blog/laravel/model-relation-query.md b/blog/laravel/model-relation-query.md new file mode 100644 index 0000000000000000000000000000000000000000..93f798577bb9e604e5b02d96d6d5ed85d98bc695 --- /dev/null +++ b/blog/laravel/model-relation-query.md @@ -0,0 +1,161 @@ +# 模型的关联查询 + +```php + +class User extends Model +{ + protected $table = 'user'; + // 一对多关联 Book 表 + public function books() + { + return $this->hasMany(Book::class, 'user_id', 'id'); + } +} + + +class Book extends Model +{ + protected $table = 'book'; + + // 反向关联 + public function user() + { + return $this->belongsTo(User::class, 'user_id', 'id'); + } +} + +``` + +查询 + +```php +//下面两种查询是一样的; +$books = User::find(1)->books; + +$books = User::find(19)->book()->get(); +``` + +```sql +select * from `user` where `user`.`id` = ? limit 1 + +select * from `book` where `book`.`user_id` = ? and `book`.`user_id` is not null +``` + +```php +//可以采用 where 筛选或闭包 +$books = User::find(1) + ->books() + ->where('id', 1) + ->orWhere('id', 11) + ->get(); +``` +```sql +select * from `user` where `user`.`id` = ? limit 1 + +select * from `book` where `book`.`user_id` = ? and `book`.`user_id` is not null and `id` = ? or `id` = ? +``` + +```php +$books = User::find(1) + ->books() + ->where(function ($query) { + $query->where('id', 1)->orWhere('id', 11); + })->get(); +``` + +```sql +select * from `user` where `user`.`id` = ? limit 1 + +select * from `book` where `book`.`user_id` = ? and `book`.`user_id` is not null and (`id` = ? or `id` = ?) +``` + +has()方法,可以查询某些条件下的关联查询数据 + +```php +// 获取存在关联书籍的用户列表(言下之意:至少一本书) +$users = User::has('books')->get(); +``` +```sql +select * from `user` where exists ( + select * from `book` where `user`.`id` = `book`.`user_id` +) +``` + +```php +// 获取存在关联书籍(并超过 3 条)的用户列表 +$users = User::has('book','>=', 3)->get(); +``` + +```sql +select * from `user` where ( + select count(*) from `book` where `user`.`id` = `book`.`user_id` +) >= 3 +``` + +使用whereHas()方法,创建闭包查询 + +```php +//whereHas 闭包用法 +$users = User::whereHas('books', function ($query) { + //这里$query 是 book 表,通过 user_id 查询,返回 user 表数据 + $query->where('user_id', 19); + })->get(); +``` +```sql +select * from `user` where exists ( + select * from `book` where `user`.`id` = `book`.`user_id` and `user_id` = ? +) +``` + +使用doesntHave()方法,即has()的反向操作 + +```php +// 获取不存在关联书籍的用户列表,闭包用法:whereDoesntHave() +$users = User::doesntHave('books')->get(); +``` +```sql +select * from `user` where not exists ( + select * from `book` where `user`.`id` = `book`.`user_id` +) +``` + +使用withCount()方法,可以进行关联统计 + +```php +//关联统计,会自动给一个 book_count 字段 //统计每个用户有多少本书 +User::withCount('books')->get(); +``` + +```sql +select `user`.*, +(select count(*) from `book` where `user`.`id` = `book`.`user_id`) as `books_count` +from `user` +``` +```php +// 给多个关系添加统计:profile_count,book_count +User::withCount(['profile', 'books'])->get(); +``` + +```sql +select `user`.*, +(select count(*) from `profile` where `user`.`id` = `profile`.`user_id`) as `profile_count`, +(select count(*) from `book` where `user`.`id` = `book`.`user_id`) as `books_count` +from `user` +``` + +```php +//关联统计再结合闭包进行筛选,还可以设置别名 +User::withCount(['profile', 'books' => function ($query) { + //这里限制被统计的记录 + $query->where('user_id', 19); + }])->get(); +``` + +```sql +select `user`.*, +(select count(*) from `profile` where `user`.`id` = `profile`.`user_id`) as `profile_count`, +(select count(*) from `book` where `user`.`id` = `book`.`user_id` and `user_id` = ?) as `books_count` +from `user` +``` + +https://www.bilibili.com/video/BV1gE411j78F?p=29&spm_id_from=pageDriver&vd_source=efbb4dc944fa761b6e016ce2ca5933da \ No newline at end of file diff --git a/blog/laravel/model-relation.md b/blog/laravel/model-relation.md index a5bb93234ee7eca139dd65185a84794c1ac82012..89f6f580d4f16671344f19d56ff55c994f5c4544 100644 --- a/blog/laravel/model-relation.md +++ b/blog/laravel/model-relation.md @@ -621,5 +621,3 @@ where `user_role`.`user_id` = ? and `user_role`.`id` = ? - 多态一对多 - 多态多对多 - -https://www.bilibili.com/video/BV1gE411j78F?p=27&spm_id_from=pageDriver&vd_source=efbb4dc944fa761b6e016ce2ca5933da \ No newline at end of file