0

0

0

修罗

站点介绍

只有了解事实才能获得真正的自由

tp5.1模型关联关系

修罗 2019-12-16 1600 0条评论 thinkphp5.1

首页 / 正文

一、一对一关系

1.获取用户详细信息

(1)不使用关联关系模型

在不使用关联关系模型时, 如果想获取用户的详细信息怎么处理?

需求: 查找xiaoming的手机号

分为两步

  1. 根据name查找user表, 找id
  2. 根据id查找user_info表, 条件是user_info表中的user_id=id

1589781406449.png

测试:

1589781252314.png

需要执行两条SQL语句, 最终返回的是一条user_info表中的数据

(2)获取用户详细信息使用关联关系模型

1) 在user模型中编写userInfo方法

在userInfo方法中, 调用hasOne(), 带3个参数

https://www.kancloud.cn/manual/thinkphp5_1/354057

1543088969219.png

// userInfo名字随便写小驼峰命名
public function userInfo()
{
    /**
    * 第一个参数: 要关联的模型类名
    * 第二个参数: 外键名, 要关联的表中的字段
    * 第三个参数: 主键名, 本表中跟关联表对应的字段
    */
    return $this->hasOne('UserInfo', 'user_id', 'id');
}

2) 在控制器中调用

在控制器中调用时, user_info可以做为user模型的一个属性来查询

关联方法命名是驼峰法,userInfo, 关联属性则是小写+下划线user_info

https://www.kancloud.cn/manual/thinkphp5_1/354057

1543089095949.png

// 使用关联模型,tp中数组可以当对象使用,对象当数组使用,tp做了转换
public function one_one_yes()
{
    // 找到id为1的记录
    $user = User::find(1);
    dump($user);
    // 会根据$user的id找UserInfo的user_id
    dump($user->user_info);
}

3) 测试

1543089367709.png

2 根据关联表查本表

需求, 查询手机号为18973245670的用户密码

分析: 手机号保存在关联表user_info中, 密码在本表user中

一般的思路是:

  • 先从user_info表中查找, 条件是tel=18973245670, 找到user_id(3)
  • 再根据user_id到user表中查找, 条件是id=user_id(3)

1) 不使用关联关系

public function info2user()
{
    //不使用关联关系
    $tel = '18973245670';
    // 查找user_id
    $user_id = UserInfo::where('tel', $tel)->value('user_id');
    // 通过id找用户,得到密码
    $user = User::find($user_id);
    echo $user->password;
}

1543090142170.png

也可以使用一条sql语句, 连表查询

select it_user.password from 
it_user join it_user_info 
on it_user_info.user_id =it_user.id 
where it_user_info.tel='18973245670';

2) 使用关联关系

public function info2user()
{
    // 使用关联关系
    $tel = '18973245670';
    // 第一个参数是关联方法名(不是关联模型名)
    $user = User::hasWhere('userInfo', ['tel'=>$tel])->find();
    echo $user->password;
}

说明:

1543090544195.png

执行的sql语句:

1543090615871.png

3 关联自动写入

1543092243949.png

分别创建两个模型, 在写入数据库时, 使用together

1) 关联新增

应用场景, 在添加用户的同时, 添加用户的详情

案例:

public function add()
{
    $user = new User;
    $user->name = 'xiaozhang';
    $user->password = '123456';

    $user_info = new UserInfo;
    $user_info->tel = '13909876543';
    $user_info->email = 'xiaozhang@163.com';
    $user_info->addr = '南京';

    // 建立关联关系
    $user->user_info = $user_info;
    // 这里必须指定关联属性名, user_info跟上面的关联属性保持一致
    $user->together('user_info')->save();
}

测试

1543093125887.png

2) 关联更新

需求, 更新id为7的用户的密码和手机号

密码是保存在本表user中

手机号是保存在关联表user_info中

使用关联更新, 同时更新两张表

public function upd()
{
    $user = User::find(7);
    $user->password = '777';
    $user->user_info->tel = '77777777';

    $user->together('user_info')->save();
}

执行的sql语句

1543093746718.png

3) 关联删除

需求: 删除id为8的用户时, 同时删除详情

public function del()
{
    $user = User::get(8, 'userInfo');

    $user->together('user_info')->delete();
}

这个地方, tp好像有bug, 完全按照手册的写法写, 但是依然出问题

二、 一对多关系

用户表(it_user)和文章表(it_article)之间就是一对多关系

2.1 建立关联关系

在user模型中, 定义一个方法articles

public function articles()
{
    /**
    * 第一个参数: 要关联的模型名
    * 第二个参数: 外键名, 要关联的表中的字段
    * 第三个参数: 主键名, 本表中跟关联表对应的字段
    */
    return $this->hasMany('Article', 'user_id', 'id');
}

2.2 关联查询

public function article()
{
    $user = User::find(1);
    // 将模型中的方法做为属性来使用
    dump($user->articles);
}

效果

1543098192843.png

2.3 关联新增

public function article_add()
{
    $data = [
        'title'=>'新增的文章',
        'content'=>'新增的文章'
    ];

    $user = User::find(1);
    // 这里的articles必须加(), 表示调用模型的方法
    // 用户id1在article表也会插入用户关联id
    $user->articles()->save($data);
}

执行的sql语句

1543098473039.png

1543098494092.png

2.4 关联删除

public function article_del()
{
    // user id为1删除,article中关联记录也全部删除。要用get
    $user = User::get(1, 'articles');
    $user->together('articles')->delete();
}

执行的sql语句

1543098888398.png

三、 多对一关系

一对多关系反过来就是多对一关系

用户表(it_user)与国家表(it_country)之间就是多对一关系

3.1 建立关联关系

在用户模型(user)中, 定义一个方法country

1543138578946.png

public function country()
{
    /**
    * 第一个参数: 要关联的模型类名
    * 第二个参数: 外键名, 由于本表是子表, 外键字段在本表中
    * 第三个参数: 主键名, 需要关联的模型的主键
    */
    return $this->belongsTo('Country', 'country_id', 'id');
}

3.2 关联查询

public function country()
{
    $user = User::find(1);
    dump($user->country);
}

四、 多对多关系

用户表(it_user)与角色表(it_role)是多对多的关系

对于多对多关系, 需要一张中间表(it_user_role)

4.1 建立关联关系

在User模型中, 定义一个roles方法

public function roles()
{
    /**
    * 第一个参数: 要关联的模型类名
    * 第二个参数: 中间表名
    * 第三个参数: 外键, 中间表的当前模型外键
    * 第四个参数: 关联键, 中间表的当前模型关联键名
    */
    return $this->belongsToMany('Role', 'user_role', 'role_id', 'user_id');
}

使用belongsToMany()函数

1543103451237.png

4.2 关联查询

public function role()
{
    $user = User::find(1);
    dump($user->roles);
}

可以直接获取id为1的用户的角色信息

1543103574649.png

4.3 关联新增

public function role_add()
{
    $user = User::find(1);

    $user->roles()->save(['name'=>'管理员']);
}

这里执行了两个操作

  1. 向关联的角色表里添加了一条记录
  2. 向中间表添加了一条记录

不用手动的维护中间表, 这个还不错~~

1543103812386.png

评论(0)


最新评论

  • 1

    1

  • 1

    1

  • -1' OR 2+158-158-1=0+0+0+1 or 'TKCTZnRa'='

    1

  • 1

    1

  • 1

    1

  • 1

    1

  • 1

    1

  • @@5Qa2D

    1

  • 1

    1

  • 1

    1

日历

2025年09月

 123456
78910111213
14151617181920
21222324252627
282930    

文章目录

推荐关键字: Linux webpack js 算法 MongoDB laravel JAVA jquery javase redis