• 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);
  • 相关阅读:
    R 多图间距调整
    ggplot2 颜色渐变(离散颜色)设置
    R语言因子排序
    利用plink软件基于LD信息过滤SNP
    利用vcftools比较两个vcf文件
    在R语言中使用Stringr进行字符串操作
    perl 数组快速去除重复元素
    Shell中 ##%% 操作变量名
    Java基础之数值类型之间的转换
    Java中0.2减0.1 结果为什么不是0.1?
  • 原文地址:https://www.cnblogs.com/xiaofeng028/p/3546419.html
Copyright © 2020-2023  润新知