thinkPHP3.2.3 关联模型 - 多对多关联

官方手册地址:http://document.thinkphp.cn/manual_3_2.html#relation_model

关联模型示例 -  一对多关联

MANY_TO_MANY:当前模型可以属于多个对象,而父对象则可能包含有多个子对象,通常两者之间需要一个中间表类约束和关联。

(例:每个用户可以属于多个组,每个组可以有多个用户;操作数据时,某些操作会影响子对象,如删除当前用户会同时删除对应的子对象数据)

 

1.创建数据表并插入数据

CREATE TABLE `think_group` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '组表ID',
  `name` varchar(30) NOT NULL COMMENT '名称',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8;
insert  into `think_group`(`id`,`name`) values (1,'会员管理'),(2,'用户管理'),(3,'文章管理'),(4,'评论管理'),(5,'网站管理'),(6,'角色管理'),(7,'新闻管理'),(8,'博客管理'),(9,'商店管理');

# 用户与组关联表(中间表)
CREATE TABLE `think_user_group` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户与组关联表ID',
  `user_id` int(11) NOT NULL COMMENT '用户表ID',
  `group_id` int(11) NOT NULL COMMENT '组表ID',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8;
insert  into `think_user_group`(`id`,`user_id`,`group_id`) values (1,2,1),(2,2,2),(3,2,3),(4,2,4),(5,2,5),(6,2,6),(10,2,7),(11,2,8),(16,4,5),(17,4,6),(18,4,8);

 

当前用户表所关联的其他表数据

 2. 用户控制器 (/Application/Home/Controller)

<?php
namespace Home\Controller;
use Think\Controller;

class UserController extends Controller {
    // 关联模型查询数据
    public function relationModelQuery(){
        $id = I('id/d');
        $condition = 1;
        if($id > 0)
            $condition = "id=$id";

        $user = D("User");
        $result = $user-> relation(true)->where($condition)->select();
        echo '<pre>';var_dump($result);exit;
    }

    // 关联模型新增数据
    public function relationModelAdd(){
        // 组装数据 方便验证
        $data = array();
        $data['account']  = I('account/s');
        $data['password'] = I('password/s');
        $data['email']    = I('email/s');
        $data['nickname'] = I('nickname/s');

        // 档案表数据
        $data["Profile"]  = array(
            'email'    => $data['email'],
            'nickname' => $data['nickname']
        );

        // 实例化模型并验证数据
        $user = D("User");
        if(!$user->create($data))
            exit($user->getError());

        // 移除用户表多余数据
        unset($data['email']);
        unset($data['nickname']);

        // 数据通过模型插入到数据库表中
        $result = $user->relation(true)->add($data);
        if(!$result)
            exit('新增数据失败!');
        exit('新增数据成功! ID:' . $result);
    }

    // 关联模型更新数据
    public function relationModelSave(){
        // 获取修改数据
        $id = I('id/d');
        $account  = I('account/s');
        $password = I('password/s');
        $email    = I('email/s');
        $nickname = I('nickname/s');

        if($id <= 0)
            exit('ID 不存在');

        // 拼装需要更改的数据
        $data = array();
        if(strlen($account) > 0)
            $data['account'] = $account;
        
        if(strlen($password) > 0)
            $data['password'] = $password;

        if(strlen($email) > 0)
            $data['Profile']['email'] = $email;

        if(strlen($nickname) > 0)
            $data['Profile']['nickname'] = $nickname;
        
        // 实例化模型并通过关联模型更新数据
        $user = D("User");
        $result = $user-> relation(true)->where(array('id'=>$id))->save($data);
        if(!$result)
            exit('更新失败!');
        exit('更新成功!影响行数:' . $result);
    }

    // 关联模型删除数据
    public function relationModelDel(){
        $id = I('id/d');
        if($id <= 0)
            exit('ID 不存在');

        $user = D("User");
        $result = $user->relation(true)->delete($id);
        if(!$result)
            exit('删除失败!');
        exit('删除成功!');
    }
}
View Code

3. 用户模型 (/Application/Home/Model)

<?php
namespace Home\Model;
use Think\Model\RelationModel;
class UserModel extends RelationModel{
    // 指定用户表
    protected $tableName = 'user';

    // 数据验证
    protected $_validate = array(
        //array(验证字段1,验证规则,错误提示,[验证条件,附加规则,验证时间]),
        array('account', 'require', '账户不能为空!', '', '', 1),         // 必填验证
        array('account', '', '帐号名称已经存在!', 0, 'unique', 1),         // 唯一验证

        array('password', 'require','密码不能为空!', '', '', 1),         // 必填验证

        array('email', 'email', 'email 格式错误', '', '', 1),            // 邮箱验证

        array('nickname', 'require', '昵称不能为空!', '', '', 1),        // 必填验证
   );

    // 关联模型
    protected $_link = array(
        // 一对一 关联档案表
        // HAS_ONE关联表示当前模型拥有一个子对象
        'Profile'=>array(
            'mapping_type'  => self::HAS_ONE,
            'class_name'    => 'Profile',
            // 定义更多的关联属性
            'foreign_key'     => 'user_id', // 关联的外键名称
            'as_fields'     => 'email,nickname', // 字符串中间不要有空格 例:'email, nickname' 这样是错误的
        ),

        // 一对一 关联部门
        // Belongs_to 关联表示当前模型从属于另外一个父对象
        'Dept' => array(
            'mapping_type'  => self::BELONGS_TO,
            'class_name'    => 'Dept',
            'foreign_key'   => 'dept_id', // 部门表ID
            'mapping_name'  => 'dept',
            // 定义更多的关联属性
            'as_fields'     => 'name:dept_name',
        ),

        // 一对多
        // HAS_MANY 关联表示当前模型拥有多个子对象
        'Article' => array(
            'mapping_type'  => self::HAS_MANY,
            'class_name'    => 'Article',
            'foreign_key'   => 'user_id',
            'mapping_name'  => 'articles',
            'mapping_order' => 'create_time desc',
            // 定义更多的关联属性
            
        ),

        // 多对多
        // 当前模型可以属于多个对象,而父对象则可能包含有多个子对象,通常两者之间需要一个中间表类约束和关联。
        'Group' => array(
            'mapping_type'          =>  self::MANY_TO_MANY,
            'class_name'            =>  'Group',
            'mapping_name'          =>  'groups',
            'foreign_key'           =>  'user_id',
            'relation_foreign_key'  =>  'group_id',
            // 'relation_table'        =>  'think_group_user' //此处应显式定义中间表名称,且不能使用C函数读取表前缀
            'relation_table'        =>  '__USER_GROUP__'
        )
    );
}
View Code

4. 删除操作

  删除用户表 id=2 的数据

   访问 域名/home/user/relationModelDel/id/2

  此操作会删除 

      user 表 id 为 2 的数据;

      dept 表不受影响;

      article 表将删除对应用户表ID的项,也就是 user_id=2 的值;

      profile 表会删除 user_id=2 的值;

      group 表不受影响

      user_guroup 表会删除 user_id=2 的值

array(2) {
  [0]=>
  array(9) {
    ["id"]=>
    string(1) "2"
    ["account"]=>
    string(4) "lisi"
    ["password"]=>
    string(6) "888888"
    ["dept_id"]=>
    string(1) "1"
    ["email"]=>
    string(12) "lisi@163.com"
    ["nickname"]=>
    string(9) "李四宝"
    ["dept_name"]=>
    string(9) "市场部"
    ["articles"]=>
    array(14) {
      [0]=>
      array(4) {
        ["id"]=>
        string(2) "14"
        ["name"]=>
        string(12) "笑傲江湖"
        ["user_id"]=>
        string(1) "2"
        ["create_time"]=>
        string(10) "1572330030"
      }
      [1]=>
      array(4) {
        ["id"]=>
        string(2) "13"
        ["name"]=>
        string(9) "越女剑"
        ["user_id"]=>
        string(1) "2"
        ["create_time"]=>
        string(10) "1572329940"
      }
      [2]=>
      array(4) {
        ["id"]=>
        string(2) "12"
        ["name"]=>
        string(9) "侠客行"
        ["user_id"]=>
        string(1) "2"
        ["create_time"]=>
        string(10) "1572329890"
      }
      [3]=>
      array(4) {
        ["id"]=>
        string(2) "11"
        ["name"]=>
        string(15) "倚天屠龙记"
        ["user_id"]=>
        string(1) "2"
        ["create_time"]=>
        string(10) "1572329883"
      }
      [4]=>
      array(4) {
        ["id"]=>
        string(2) "10"
        ["name"]=>
        string(15) "白马啸西风"
        ["user_id"]=>
        string(1) "2"
        ["create_time"]=>
        string(10) "1572329853"
      }
      [5]=>
      array(4) {
        ["id"]=>
        string(1) "9"
        ["name"]=>
        string(9) "鸳鸯刀"
        ["user_id"]=>
        string(1) "2"
        ["create_time"]=>
        string(10) "1572329840"
      }
      [6]=>
      array(4) {
        ["id"]=>
        string(1) "8"
        ["name"]=>
        string(9) "碧血剑"
        ["user_id"]=>
        string(1) "2"
        ["create_time"]=>
        string(10) "1572329831"
      }
      [7]=>
      array(4) {
        ["id"]=>
        string(1) "7"
        ["name"]=>
        string(15) "书剑恩仇录"
        ["user_id"]=>
        string(1) "2"
        ["create_time"]=>
        string(10) "1572329787"
      }
      [8]=>
      array(4) {
        ["id"]=>
        string(1) "6"
        ["name"]=>
        string(12) "雪山飞狐"
        ["user_id"]=>
        string(1) "2"
        ["create_time"]=>
        string(10) "1572329775"
      }
      [9]=>
      array(4) {
        ["id"]=>
        string(1) "5"
        ["name"]=>
        string(9) "连城诀"
        ["user_id"]=>
        string(1) "2"
        ["create_time"]=>
        string(10) "1572329763"
      }
      [10]=>
      array(4) {
        ["id"]=>
        string(1) "4"
        ["name"]=>
        string(9) "鹿鼎记"
        ["user_id"]=>
        string(1) "2"
        ["create_time"]=>
        string(10) "1572329745"
      }
      [11]=>
      array(4) {
        ["id"]=>
        string(1) "3"
        ["name"]=>
        string(12) "神雕侠侣"
        ["user_id"]=>
        string(1) "2"
        ["create_time"]=>
        string(10) "1572329708"
      }
      [12]=>
      array(4) {
        ["id"]=>
        string(1) "2"
        ["name"]=>
        string(15) "射雕英雄传"
        ["user_id"]=>
        string(1) "2"
        ["create_time"]=>
        string(10) "1572329697"
      }
      [13]=>
      array(4) {
        ["id"]=>
        string(1) "1"
        ["name"]=>
        string(12) "天龙八部"
        ["user_id"]=>
        string(1) "2"
        ["create_time"]=>
        string(10) "1572329680"
      }
    }
    ["groups"]=>
    array(8) {
      [0]=>
      array(2) {
        ["id"]=>
        string(1) "1"
        ["name"]=>
        string(12) "会员管理"
      }
      [1]=>
      array(2) {
        ["id"]=>
        string(1) "2"
        ["name"]=>
        string(12) "用户管理"
      }
      [2]=>
      array(2) {
        ["id"]=>
        string(1) "3"
        ["name"]=>
        string(12) "文章管理"
      }
      [3]=>
      array(2) {
        ["id"]=>
        string(1) "4"
        ["name"]=>
        string(12) "评论管理"
      }
      [4]=>
      array(2) {
        ["id"]=>
        string(1) "5"
        ["name"]=>
        string(12) "网站管理"
      }
      [5]=>
      array(2) {
        ["id"]=>
        string(1) "6"
        ["name"]=>
        string(12) "角色管理"
      }
      [6]=>
      array(2) {
        ["id"]=>
        string(1) "7"
        ["name"]=>
        string(12) "新闻管理"
      }
      [7]=>
      array(2) {
        ["id"]=>
        string(1) "8"
        ["name"]=>
        string(12) "博客管理"
      }
    }
  }
  [1]=>
  array(9) {
    ["id"]=>
    string(1) "4"
    ["account"]=>
    string(7) "zhaoliu"
    ["password"]=>
    string(6) "333333"
    ["dept_id"]=>
    string(1) "1"
    ["email"]=>
    string(15) "zhaoliu@163.com"
    ["nickname"]=>
    string(6) "赵六"
    ["dept_name"]=>
    string(9) "市场部"
    ["articles"]=>
    array(1) {
      [0]=>
      array(4) {
        ["id"]=>
        string(2) "16"
        ["name"]=>
        string(12) "盗墓笔记"
        ["user_id"]=>
        string(1) "4"
        ["create_time"]=>
        string(10) "1572330066"
      }
    }
    ["groups"]=>
    array(3) {
      [0]=>
      array(2) {
        ["id"]=>
        string(1) "5"
        ["name"]=>
        string(12) "网站管理"
      }
      [1]=>
      array(2) {
        ["id"]=>
        string(1) "6"
        ["name"]=>
        string(12) "角色管理"
      }
      [2]=>
      array(2) {
        ["id"]=>
        string(1) "8"
        ["name"]=>
        string(12) "博客管理"
      }
    }
  }
}
删除前 用户表id=2的关联数据

    删除后 各数据表数据状态

 

数据已同步删除。

 

thinkPHP 3.2.3 关联模型 - 一对一 (https://www.cnblogs.com/koreyoshi/articles/11758080.html)

thinkPHP 3.2.3 关联模型 - 一对多  (https://www.cnblogs.com/koreyoshi/articles/11759851.html)

thinkPHP 3.2.3 关联模型 - 多对多  (https://www.cnblogs.com/koreyoshi/articles/11760159.html)

 

posted @ 2019-10-29 17:27  梦缘&江南~  阅读(500)  评论(0)    收藏  举报