zoukankan      html  css  js  c++  java
  • ThinkPHP的关联操作实例

    用thinkphp这么久了,这个功能还一直没用过。

    平时都是直接继承的Model类

    我们以用户表为核心,来描述如何使用表的关联操作。假设存在如下的关联情况:
    每个用户有一个档案表是HAS_ONE关联;
    每个用户属于一个部门是BELONGS_TO关联;
    每个用户有多张银行卡是HAS_MANY关联;
    每个用户可能属于多个项目组,每个项目组也有多个用户是MANY_TO_MANY关联。
    我们首先来创建数据表,以MySQL为例:
    // 部门表

     

    CREATE TABLE `think_dept` (
     
    `id` smallint(3) NOT NULL auto_increment,
     
    `name` varchar(50) NOT NULL,
     
    PRIMARY KEY (`id`)
     
    ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ;

     


    // 用户表

     

    CREATE TABLE `think_user` (
     
    `id` mediumint(6) NOT NULL auto_increment,
     
    `name` varchar(25) NOT NULL,
     
    `dept_id` smallint(3) NOT NULL,
     
    PRIMARY KEY (`id`)
     
    ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ;

     


    // 用户档案表

     

    CREATE TABLE `think_profile` (
     
    `id` mediumint(6) NOT NULL auto_increment,
     
    `user_id` mediumint(6) NOT NULL,
     
    `email` varchar(255) NOT NULL,
     
    `nickname` varchar(50) NOT NULL,
     
    PRIMARY KEY (`id`)
     
    ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ;

     


    // 银行卡表

     

    CREATE TABLE `think_card` (
     
    `id` mediumint(6) NOT NULL auto_increment,
     
    `user_id` mediumint(6) NOT NULL,
     
    `card` varchar(25) character set latin1 NOT NULL,
     
    PRIMARY KEY (`id`)
     
    ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ;

     


    // 项目组表

     

    CREATE TABLE `think_group` (
     
    `id` mediumint(6) NOT NULL auto_increment,
     
    `name` varchar(50) NOT NULL,
     
    PRIMARY KEY (`id`)
     
    ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ;

     


    // 用户-项目组表

     

    CREATE TABLE `think_user_group` (
     
    `id` mediumint(6) NOT NULL auto_increment,
     
    `group_id` mediumint(5) NOT NULL,
     
    `user_id` mediumint(5) NOT NULL,
     
    PRIMARY KEY (`id`)
     
    ) ENGINE=MyISAM DEFAULT CHARSET=utf8;

     


    下面我们分别来给数据表定义对应的模型,这里关键是用户模型的定义,因为我们以用户表为核心来定义和使用关联,所以其他模型中无需再定义关联关系。

    class UserModel extends RelationModel
     
    {
     
    protected $_link = array(
     
    'Profile'=>HAS_ONE,
     
    'Dept'=>BELONGS_TO,
     
    'Card'=>HAS_MANY,
     
    'Group'=>MANY_TO_MANY,
     
    );
     
    }

     


    上面的关联定义,我们采用了最简洁的定义方式,也就是所有规则都按照系统的默认规则进行。这些规则包括主键、外键、表名的规范。完整的关联定义可以写成:

     

    class UserModel extends Model
     
    {
     
    protected $_link = array(
     
    'Profile'=>array(
     
    'mapping_type'=>HAS_ONE,
     
    'mapping_name'=>'Profile',
     
    'class_name'=>'Profile',
     
    'foreign_key'=>'user_id',
     
    ),
     
    'Dept'=> array(
     
    'mapping_type'=> BELONGS_TO,
     
    'mapping_name'=>'Dept',
     
    'class_name'=>'Dept',
     
    'foreign_key'=>'dept_id',
     
    ),
     
    'Card'=> array(
     
    'mapping_type'=> HAS_MANY,
     
    'mapping_name'=>'Card',
     
    'class_name'=>'Card',
     
    'foreign_key'=>'user_id',
     
    ),
     
    'Group'=> array(
     
    'mapping_type'=> MANY_TO_MANY,
     
    'mapping_name'=>'Group',
     
    'class_name'=>'Group',
     
    'foreign_key'=>'user_id',
     
    'relation_foreign_key'=>'group_id',
     
    'relation_table'=>'think_user_group',
     
    ),
     
    );
     
    }

     

    如果要给关联定义增加可选的属性,则必须采用完整定义的方式。
    其中Profile Dept Card Group 分别是其他几个模型的名称,定义如下:
    class ProfileModel extends Model {}
    class DeptModel extends Model {}
    class CardModel extends Model {}
    class GroupModel extends Model {}
    因为我们以用户表为核心来读取关联,所以用户和项目组的中间表 默认的规则必须是 user_group
    也就是我们上面创建的think_user_group表,如果你的中间表的名称不是这个规则,需要定义relation_table属性。
    为了演示的方便,我们首先给部门表和项目组表增加一些数据:

    INSERT INTO `think_dept` (`id`, `name`) VALUES (1, '开发部'),(2, '销售部') ,(3, '财务部');
     
    INSERT INTO `think_group` (`id`, `name`) VALUES (1, '项目组1'),(2, '项目组2') ,(3, '项目组3');

     


    接下来首先演示关联写入,我们创建一个IndexAction用于演示操作,记得在项目配置文件里面定义好数据库的连接信息。
    在IndexAction的index操作方法里面添加

    $User = D('User');
     
    $User->name = 'thinkphp';
     
    $User->dept_id = 1;
     
    $User->Profile = array(
     
    'email' =>'liu21st@gmail.com',
     
    'nickname' =>'流年',
     
    );
     
    $User->Card = array(
     
    array('id'=>1.'card'=>'12345678'),
     
    array('id'=>2,'card'=>'88888888'),
     
    );
     
    $User->Group = array(
     
    array('id'=>1),
     
    array('id'=>2),
     
    );
     
    $User->add('',true);

     


    在执行User模型的add方法的同时,我们已经写入了think_profile、think_card和think_user_group三个表的数据,BELONGS_TO关联关系是不会自动写入的。
    如果我们在模型里面设置了autoAddRelations属性为True的话,使用

    $User->add();


    方法即可同时进行关联写入。
    为了验证关联数据是否已经写入,我们现在来使用关联查询把相关的数据查出来。

    $user = $User->relation(true)->find(1);
     
    Dump($user);

     

    可以看到输出的结果,把User模型关联的数据都显示出来了。如果我们只希望获取某个关联数据,可以使用

    $user = $User->relation('Profile')->find(1);

     

    表示只是获取关联的用户档案数据。
    数据集的查询也可以支持关联查询,使用

    $user = $User->relation(true)->findAll();

     

    能够显示出完整的含有关联数据的数据集。
    我们再来更新关联数据

    $user['id'] = 1;
     
    $user['name'] = 'tp';
     
    $user['Profile']['email'] = 'thinkphp@qq.com';
     
    $user['Card'] = array(
     
    array('id'=>1,'card'=>'66666666'),
     
    array('id'=>2,'card'=>'77777777'),
     
    );
     
    $user['Group'] = array(
     
    array('id'=>1),
     
    array('id'=>3),
     
    );
     
    $User->save($user,'id=1',true);

     

    注意关联更新的时候一定要包含主键数据。
    关联删除

    $User->deleteById(2,true);
  • 相关阅读:
    BZOJ 1101 莫比乌斯函数+分块
    BZOJ 2045 容斥原理
    BZOJ 4636 (动态开节点)线段树
    BZOJ 2005 容斥原理
    BZOJ 2190 欧拉函数
    BZOJ 2818 欧拉函数
    BZOJ 3123 主席树 启发式合并
    812. Largest Triangle Area
    805. Split Array With Same Average
    794. Valid Tic-Tac-Toe State
  • 原文地址:https://www.cnblogs.com/xiaofeng028/p/3546419.html
Copyright © 2011-2022 走看看