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);

ThinkPHP的关联操作实例

上一篇:JavaScript做的一个随机点名程序


下一篇:深入理解javascript闭包