ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
[TOC] # 例子一 Model:Pay,付款记录。表结构应该是这样的: ~~~ user: id ... ... pay: id ... ... user_id ~~~ User 和 Pay 具有一对多关系,换句话说就是一个 User 可以有多个 Pay,这样的话,只在 Pay 表中存在一个 `user_id` 字段即可。 `/app/models/User.php`: ~~~ class User extends Eloquent { protected $table = 'users'; public function hasManyPays() { return $this->hasMany('Pay', 'user_id', 'id'); } } ~~~ 然后,当我们需要用到这种关系的时候,该如何使用呢?如下: ~~~ $accounts = User::find(10)->hasManyPays()->get(); ~~~ 此时得到的 `$accounts` 即为 `Illuminate\Database\Eloquent\Collection` 类的一个实例。大家应该也已经注意到了,这里不是简单的 `-> hasOneAccount` 而是 `->hasManyPays()->get()`,为什么呢?因为这里是 `hasMany`,操作的是一个对象集合。 相应的 belongsTo() 的用法跟上面一对一关系一样: ~~~ class Pay extends Eloquent { protected $table = 'pays'; public function belongsToUser() { return $this->belongsTo('User', 'user_id', 'id'); } } ~~~ ## 总结 **查询** ~~~ $uObj = $user->find(1); //查这个用户下的所有pay记录 $res = $uObj->hasManyPays(); //pay的记录 dd($res->get()->toArray()); ~~~ **新增** ~~~ $uObj = $user->find(1); //新增个pay记录 $pay->pname = '新增的pname'; //保存这个记录 $res = $uObj->hasManyPays()->save($pay); //pay的记录,新增的记录 dd($res->toArray()); ~~~ **删除** ~~~ $uObj = $user->find(2); //删除和这个相关的 $res = $uObj->hasManyPays()->delete(); //返回修改的记录个数,删除的是pay里的记录 dd($res); ~~~ **修改** ~~~ $uObj = $user->find(1); //关联关系 $pObj = $uObj->hasManyPays(); $res = $pObj->update(['pname' => 'user_id为1的全部修改']); //返回修改的记录个数,修改的是pay里的记录 dd($res); ~~~ **联合** ~~~ //找出2个对象 $uObj = $user->find(2); $pObj = $pay->find(1); //把pay(对)中的关联id改为$uObj $pObj->belongsToUser()->associate($uObj); $res = $pObj->save(); //操作的成功与否 true/false dd($res); ~~~ **解除联合** ~~~ $pObj = $pay->find(1); //把pay(多)中的关联id改为NULL $pObj->belongsToUser()->dissociate(); $res = $pObj->save(); //操作的成功与否 true/false dd($res); ~~~ # 例子二 每个帖子有很多评论 **posts 表** | 键名 | 类型 | | --- | --- | | id | PK | | uid | FK users's id | | content | text | | created_at | timestamp | | updated_at | timestamp | **comments 表** | 键名 | 类型 | | --- | --- | | id | PK | | pid | FK posts's id | | uid | FK users's id | | content | text | | created_at | timestamp | | updated_at | timestamp | ## 实现 Post.php ~~~ function comments() { // 参数分别为 model, foreign_key, local_key return $this->hasMany(Comment::class, 'pid', 'id'); } ~~~ Comment.php ~~~ function post() { return $this->belongsTo(Post::class, 'pid', 'id'); //或如下:后两个参数与Post中的参数顺序相反 return $this->hasOne('App\\Post', 'id', 'pid'); } ~~~ ## 操作 `$post = Post::find(1);` ### 查 ~~~ //此用户下的所有帖子 foreach ($post->comment as $comment) echo $comment->content; ~~~ 想通过限制post来达到只查询comment的目的,结果集里不包含文章信息,那么你可以这样写: ~~~ $comment->whereIn('post_id',function($query){ return $query->select('id')->from('posts')->where('title','文章2'); })->get(); ~~~ ### 新建 **create开启白名单或者指定黑名单** ~~~ $comment = Comment::create([ 'pid' => $post->getKey(), 'content' => '评论内容', 'uid'=>1, //如果有$user=User::find(1); 这边就写$user->getKey(); ]); ~~~ 使用关系来实现: ~~~ $post->comments()->create(['content' => '内容','uid'=>1]); 或 $comment = new Comment(['content' => 'A new comment.','uid'=>1]); $post->comments()->save($comment); 保存多条 $post->comments()->saveMany([ new Comment(['content' => 'A new comment.']), new Comment(['content' => 'Another comment.']), ]); ~~~ ### 删除 ~~~ //删除此用户下的所有的帖子 $user->posts()->delete(); ~~~ ### 修改 ~~~ //鉴于发帖这种业务逻辑,还是不要使用关系这种方式来改了 //以下是示例代码 foreach ($user->posts as $post) { $post->title = '修改后的'; $post->save(); //或者 $post->update(['title' => '修改后的']); } ~~~ ### 针对 BelongsTo 的 联合、解除 ~~~ $comment = Comment::find(1); $post = Post::find(1); ~~~ #### 联合 associate 下面的语句 会将 comment 中的 pid 改为 $post->getKey(); ~~~ $comment->post()->associate($post); $comment->save(); ~~~ #### 解除 dissociate 下面的语句 会将 comment 中的 pid 改为 NULL ~~~ $comment->post()->dissociate(); $comment->save(); //看数据表的设计有时候提示不能为null ~~~