xml地图|网站地图|网站标签 [设为首页] [加入收藏]

的完整定义详解,ThinkPHP的关联操作实例

来源:http://www.ccidsi.com 作者:最新解决方案 人气:193 发布时间:2019-07-10
摘要:关系模型的最底层在 : ThinkPHP包ExtendModelRelationModel.class.php 转自: 用thinkphp这么久了,这一个效果还一向没用过。 论及关系 平凡大家所说的关系关系满含上面二种: 一对一关联 :ON

关系模型的最底层在ThinkPHP包ExtendModelRelationModel.class.php

转自:

用thinkphp这么久了,这一个效果还一向没用过。

论及关系

平凡大家所说的关系关系满含上面二种:
一对一关联 :ONE_TO_ONE,包括HAS_ONE和BELONGS_TO
一对多关联 :ONE_TO_MANY,包括HAS_MANY和BELONGS_TO
多对多关联 :MANY_TO_MANY
关系关系一定有二个参照表,举例:
有二个职员和工人档案管理系统项目,那个体系要富含下边包车型客车部分数据表:基本音讯表、职员和工人档案表、部门表、项目组表、银行卡表(用来记录职员和工人的银行卡资料)。
那个数据表之间存在必然的关系关系,大家以职工基本信息表为参照来分析和任何表之间的涉及:
各类职工必然有相应的员工档案资料,所以属于HAS_ONE关联;
各类职员和工人必须属于某些机构,所以属于BELONGS_TO关联;
各个职员和工人能够有八个信用卡,然而每张存折只大概属于四个职工,因而属于HAS_MANY关联;
各种职工能够况且在多少个品种组,每一种项目组同一时候有五个职员和工人,由此属于MANY_TO_MANY关联;
浅析领会数据表从前的关系关系后,大家才方可拓展关联定义和涉及操作。

 

日常都是间接接轨的Model类

涉及定义

ThinkPHP能够十分轻巧的产生数据表的关联CU君越D操作,这两天支撑的涉嫌关系包含下边多样:HAS_ONE、BELONGS_TO、HAS_MANY和MANY_TO_MANY
二个模子依照作业模型的复杂程度能够何况定义多少个事关,不受限制,全体的关联定义都统一在模型类的 $_link 成员变量里面定义,並且能够支撑动态定义。要协助关联操作,模型类必须继续RelationModel类,关联定义的格式是:

protected $_link = array(      '关联1'  =>  array(          '关联属性1' => '定义',          '关联属性N' => '定义',      ),      '关联2'  =>  array(          '关联属性1' => '定义',          '关联属性N' => '定义',      ),      '关联3'  =>  HAS_ONE, // 快捷定义      ...  );  

 下边大家第一来深入分析下一一关联格局的概念:
HAS_ONE
HAS_ONE关联表示近些日子模型具有贰个子目的,比方,各种职员和工人都有一个人事档案。大家可以建立一个用户模型UserModel,况且拉长如下事关定义:

class UserModel extends RelationModel{      protected $_link = array(         'Profile'=> HAS_ONE,      );  }  

 上边是最简便的法子,表示其遵照了系统内置的数据库标准,完整的定义方式是:

class UserModel extends RelationModel{      protected $_link = array(              'Profile'=>array(              'mapping_type'    =>HAS_ONE,                   'class_name'    =>'Profile',                   // 定义更多的关联属性                ……               ),           );  }  

 关联HAS_ONE协助的关联属性有:

 

mapping_type 关联类型,这个在HAS_ONE 关联里面必须使用HAS_ONE 常量定义。
class_name 要关联的模型类名
例如,class_name 定义为Profile的话则表示和另外的Profile模型类关联,这个Profile模型类是无需定义的,系统会自动定位到相关的数据表进行关联。
mapping_name 关联的映射名称,用于获取数据用
该名称不要和当前模型的字段有重复,否则会导致关联数据获取的冲突。如果mapping_name没有定义的话,会取class_name的定义作为mapping_name。如果class_name也没有定义,则以数组的索引作为mapping_name。
foreign_key 关联的外键名称
外键的默认规则是当前数据对象名称_id,例如:
UserModel对应的可能是表think_user (注意:think只是一个表前缀,可以随意配置)
那么think_user表的外键默认为 user_id,如果不是,就必须在定义关联的时候显式定义 foreign_key 。
condition 关联条件
关联查询的时候会自动带上外键的值,如果有额外的查询条件,可以通过定义关联的condition属性。
mapping_fields 关联要查询的字段
默认情况下,关联查询的关联数据是关联表的全部字段,如果只是需要查询个别字段,可以定义关联的mapping_fields属性。
as_fields

直接把关联的字段值映射成数据对象中的某个字段
这个特性是ONE_TO_ONE 关联特有的,可以直接把关联数据映射到数据对象中,而不是作为一个关联数据。当关联数据的字段名和当前数据对象的字段名称有冲突时,还可以使用映射定义。    

BELONGS_TO
Belongs_to 关联表示近年来模型从属于别的一个父对象,比如各样用户都属于贰个机构。我们得以做如下事关定义。

'Dept'=> BELONGS_TO  

 完整方式定义为:

'Dept'=> array(         'mapping_type'=>BELONGS_TO,            'class_name'=>'Dept',            'foreign_key'=>'userId',            'mapping_name'=>'dept',             // 定义更多的关联属性          ……  ),  

 关联BELONGS_TO定义扶助的关系属性有:

 

class_name 要关联的模型类名
mapping_name 关联的映射名称,用于获取数据用
该名称不要和当前模型的字段有重复,否则会导致关联数据获取的冲突。
foreign_key 关联的外键名称
mapping_fields 关联要查询的字段
condition 关联条件
parent_key 自引用关联的关联字段
默认为parent_id
自引用关联是一种比较特殊的关联,也就是关联表就是当前表。
as_fields 直接把关联的字段值映射成数据对象中的某个字段

HAS_MANY
HAS_MANY 关联表示近期模型具备多少个子对象,举个例子各个用户有多篇文章,大家能够如此来定义:

'Article'=> HAS_MANY  

 完整定义方式为:

'Article'=> array(        'mapping_type'=>HAS_MANY,                      'class_name'=>'Article',                      'foreign_key'=>'userId',                      'mapping_name'=>'articles',                      'mapping_order'=>'create_time desc',           // 定义更多的关联属性          ……         ),  

 关联HAS_MANY定义支持的涉嫌属性有:

 

class_name 要关联的模型类名
mapping_name 关联的映射名称,用于获取数据用
该名称不要和当前模型的字段有重复,否则会导致关联数据获取的冲突。
foreign_key 关联的外键名称
外键的默认规则是当前数据对象名称_id,例如:
UserModel对应的可能是表think_user (注意:think只是一个表前缀,可以随意配置)
那么think_user表的外键默认为 user_id,如果不是,就必须在定义关联的时候定义 foreign_key 。
parent_key 自引用关联的关联字段
默认为parent_id
condition 关联条件
关联查询的时候会自动带上外键的值,如果有额外的查询条件,可以通过定义关联的condition属性。
mapping_fields 关联要查询的字段
默认情况下,关联查询的关联数据是关联表的全部字段,如果只是需要查询个别字段,可以定义关联的mapping_fields属性。
mapping_limit 关联要返回的记录数目
mapping_order 关联查询的排序

MANY_TO_MANY
MANY_TO_MANY 关联表示近日模型能够属于多少个对象,而父对象则恐怕含有有多身形对象,平时两个之间必要贰在那之中路表类约束和关系。举例每一个用户可以属于多少个组,每种组能够有两个用户:

'Group'=>MANY_TO_MANY  

 完整定义方式为:

array('mapping_type'=>MANY_TO_MANY,  'class_name'=>'Group',  'mapping_name'=>'groups',  'foreign_key'=>'userId',  'relation_foreign_key'=>'goupId',  'relation_table'=>'think_gourpUser'  )  

 MANY_TO_MANY协助的涉及属性定义有:

 

class_name 要关联的模型类名
mapping_name 关联的映射名称,用于获取数据用
该名称不要和当前模型的字段有重复,否则会导致关联数据获取的冲突。
foreign_key 关联的外键名称
外键的默认规则是当前数据对象名称_id
relation_foreign_key 关联表的外键名称
默认的关联表的外键名称是表名_id
mapping_limit 关联要返回的记录数目
mapping_order 关联查询的排序
relation_table 多对多的中间关联表名称

多对多的中档表暗中认可表法规是:数据表前缀_提到操作的主表名_论及表名
如果think_user 和 think_group 存在八个应和的中间表,暗许的表名应该是
若果是由group来操作关联表,中间表应该是 think_group_user,要是是从user表来操作,那么相应是think_user_group,也正是说,多对多涉及的装置,必须有二个Model类里面要求显式定义中间表,不然双向操作会出错。
中间表没有必要另外的id主键(不过那并不影响中间表的操作),平常只是由 user_id 和 group_id 构成。
私下认可会通过当前模型的getRelationTableName方法来机关获得,借使当前模型是User,关联模型是Group,那么关联表的称号也等于应用 user_group那样的格式,假若不是暗许准则,需求钦定relation_table属性。

在复杂的涉及操作中,假使要给关系定义扩张可选的性质,大家得以行使完全定义的艺术。

大家以用户表为宗旨,来陈述怎么着使用表的关系操作。若是存在如下的关系意况:
各样用户有一个档案表是HAS_ONE关联;
各种用户属于七个部门是BELONGS_TO关联;
每种用户有多张银行卡是HAS_MANY关联;
各种用户或然属于多个门类组,每种门类组也是有八个用户是MANY_TO_MANY关联。
咱俩先是来创设数据表,以MySQL为例:
// 部门表

关系查询

鉴于质量难题,新版撤消了全自动关联合检查询机制,而统一行使relation方法开始展览关联操作,relation方法不但可以启用关联还能决定局地关联操作,完结了关乎操作一切尽在领会个中。

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

 输出$user结果或然是看似于下边包车型大巴数量:

array(  'id'        =>    1,  'account'    =>    'ThinkPHP',  'password'    =>    '123456',  'Profile'    => array(  'email'        =>'liu21st@gmail.com',  'nickname'    =>'流年',     ),   )  

 大家得以看到,用户的关周密据已经被映射到数量对象的属性之中了。个中Profile正是关联定义的mapping_name属性。
一经我们根据下边的主意定义了as_田野同志s属性的话,

    protected $_link = array(          'profile'=>array(      'mapping_type'    =>HAS_ONE,                      'class_name'    =>'Profile',      'foreign_key'=>'userId',      'as_fields'=>'email,nickname',           ),  );  

查询的结果就改为了上面包车型地铁结果

array(  'id'        =>    1,  'account'    =>    'ThinkPHP',  'password'    =>    'name',  'email'        =>'liu21st@gmail.com',  'nickname'    =>'流年',   )  

 email和nickname几个字段已经作为user数据对象的字段来彰显了。
假诺波及数据的字段名和当下多少对象的字段有争论的话,怎么消除吧?
大家得以用上面包车型地铁艺术来扭转下定义:
'as_fields'=>'email,nickname:username',
代表关联表的nickname字段映射成当前数量对象的username字段。
暗许会把具备定义的涉及数据都询问出来,临时候大家并不愿意那样,就足以给relation方法传入参数来决定要涉及查询的。

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

 关联查询同一能够扶助select方法,假诺要询问四个数据,并还要获取相应的涉及数据,能够改成:

$User = D("User");  $list =    $User->relation(true)->Select();  

 假设愿意在做到的询问基础之上 再举行关联数据的询问,能够应用

$User = D("User");  $user = $User->find(1);  // 表示对当前查询的数据对象进行关联数据获取  $profile = $User->relationGet("Profile");  

 事实上,除了当前的参照他事他说加以考察模型User外,其余的涉及模型是无需创建的。

全体定义的格式是:

 

关联操作

除却涉嫌查询外,系统也支撑关联数据的活动写入、更新和删除
事关写入

$User = D("User");  $data = array();  $data["account"]    = "ThinkPHP";  $data["password"] = "123456";  $data["Profile"]    = array(      'email'    =>'liu21st@gmail.com',      'nickname'    =>'流年',  );  $result =$User->relation(true)->add($data);  

 那样就能够活动写加入关贸总协定组织联的Profile数据。
同一,能够运用参数来决定要涉及写入的数量:

$result = $User->relation("Profile")->add($data);  

 事关更新
数量的涉及更新和涉及写入类似

$User = D("User");  $data["account"]    = "ThinkPHP";  $data["password"] = "123456";  $data["Profile"]    = array(      'email'    =>'liu21st@gmail.com',      'nickname'    =>'流年',  );  $result = $User-> relation(true)->where('id=3')->save($data);  

 Relation(true)会涉及保存User模型定义的具备涉及数据,假诺只要求关联合保障存部分数据,能够行使:

$result = $User->relation("Profile")->save($data);  

 那样就只会同不经常间更新关联的Profile数据。
关系保存的平整:
HAS_ONE: 关联数据的翻新直接赋值
HAS_MANY: 的涉及数据假若传入主键的值 则意味更新 否则就象征新添
MANY_TO_MANY: 的数目更新是剔除以前的数码后再也写入事关删除
除去用户ID为3的记录的还要删除关联数据

$result = $User->relation(true)->delete("3");  

 要是只供给关联删除部分数据,能够运用

$result = $User->relation("Profile")->delete("3");  

 


protected $_link = array(

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

    '关联表名1'  =>  array(

 

        '该表的关联格局的脾性1' => '定义',

// 用户表

        '该表的涉及格局的性质N' => '定义',

 

    ),

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 ;

    '关联表名2'  =>  array(

 

        '该表的关联形式的习性1' => '定义',

// 用户档案表

        '该表的关系格局的性质N' => '定义',

 

    ),

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 ;

我们换一种形式去啃下这几个最费力的难题,先来打听全部允许定义的本性含义,然后再依据种种关系关系去对号落座。

 

完全形式的概念,替换下边包车型客车格式,会类似这样,这里以Area表进行身体力行表明允许定义的质量那几个概念

// 项目组表

class UserModel extends Model{

 

    protected $_link = array(

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

        'Area'=>array(

 

             'mapping_type'=> BELONGS_TO,

// 用户-项目组表

             'mapping_name'=> 'Area',

 

             'class_name' => 'Area',

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;

             'foreign_key' => 'area_id',

 

        ),

上边我们独家来给多少表定义对应的模型,这里首要是用户模型的概念,因为大家以用户表为主旨来定义和动用关联,所以任何模型中不需求再定义关联关系。

    );

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

}

 

地点代码中,mapping_type,foreign_key ...这几个,正是允许定义的习性
-------------------------全体可定义的属性概述-------------------------------- mapping_type 

 

用以定义该表与主表的关联类型mapping_type所定义的从头到尾的经过必须是常量,共有上面两种方法:

上面的涉及定义,大家运用了最精简的概念方式,也正是怀有准则都依据系统的暗许法则举办。这个准绳饱含主键、外键、表名的规范。完整的涉及定义能够写成:

HAS_ONE  代表目前模型(主表)具备二个子对象,举例本例中的user_info,每种会员对应三个资料表

 

Belongs_to  代表近些日子模型从属于别的一个父对象,举例每一个会员都从属于三个地面

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',
 ),
 );
 }

HAS_MANY  代表近日模型具备八个子对象,比方每种用户有八个志趣花费卡

 

MANY_TO_MANY 表示近日模型能够属于八个指标,而父对象则也许带有有多少个头对象,平常两个之间必要一个个中表类约束和涉嫌。举例本例中的每种会员能够属于多少个志趣组,各类兴趣组能够有八个用户

假诺要给关系定义扩充可选的品质,则必须采纳全体定义的方法。
中间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属性。
为了演示的福利,大家率先给部门表和类型组表扩充部分数量:

class_name

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

要涉及的模型类名称。

 

比方说示例代码所定义的Area,再度提示,必供给保管已定义了此模型类(AreaModel)。

接下去首先演示关联写入,大家成立二个IndexAction用于演示操作,记得在项目布署文件之中定义好数据库的连接音信。
在IndexAction的index操作方法里面加多

mapping_name

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

波及的炫人眼目名称,用于获取数据用,作为数据聚集与主表字段并列的数目索引。

 

该名称不能够与近日模型的字段重复,不然会导致关联数据获得的争执mapping_name未有概念的话,会取class_name的概念作为mapping_name。即模型类名称

在实行User模型的add方法的相同的时候,大家早就写入了think_profile、think_card和think_user_group八个表的数额,BELONGS_TO关联关系是不会活动写入的。
假使大家在模型里面安装了autoAddRelations属性为True的话,使用

foreign_key

$User->add();

涉嫌的外键名称

主意就能够同期展按键联写入。
为了求证关联数据是或不是业已写入,大家未来来行使关联查询把有关的数据查出来。

foreign_key假设没概念,则私下认可是 当前多少对象名称 _id 作为外键

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

举例:UserModel对应的表是think_user(注意:think只是三个数据表前缀,能够随便配置)

 

那么think_user表的外键默认为user_id,假使不是,就用该属性进行显式钦定,举例数据表定义的外键是userId,则动用'foreign_key'=>'userId',这种办法去表明

能够看来输出的结果,把User模型关联的多寡都来得出来了。若是我们只愿意得到有个别关联数据,可以选取

Condition

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

论及条件,在论及查询的时候会自行带上海外国语大学键的值,假若有非凡的查询条件,能够应用该属性实行定义

 

mapping_fields

代表只是获取涉及的用户档案数据。
数据集的查询也得以支撑关联合检查询,使用

关联要询问的字段

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

若是未有概念,暗中同意关联合检查询的涉及数据是该关联表的一体字段。

 

一旦单纯是索要查询在那之中的各自字段,能够使用该属性实行点名

可见显得出完整的蕴藏关联数据的数额集。
作者们再来更新关联数据

as_fields

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

直接把涉及的字段值映射成数据对象中的有些字段

 

本条天性是ONE_TO_ONE(包括HAS_ONE 和 BELONGS_TO)关联关系特有的,能够直接把事关数据映射到多少对象中,实际不是当做一个关周到据。举个例子当提到数据的字段名和近日多少对象的字段名称有冲突时,能够接纳上边这种办法进行定义:

只顾关联更新的时候必须要含有主键数据。
关联删除

'as_田野先生s'=>'email,nickname:username',未有定义该属性时数据类似于:

$User->deleteById(2,true);

["id"] => string(1) "2"


["name"] => string(8) "thinkphp"

["Card"] => array(1) {

    [0] => array(1) {

        ["card"] => string(8) "88888888"

    }

借使定义了绚烂,则类似于

["id"]   => string(1) "2"

["name"] => string(8) "thinkphp"

["card"] => string(8) "88888888"

parent_key

自征引关联的关联字段

默认为parent_id (BELONGS_TO和HAS_MANY才有此属性)

自引用关联是一种相比较独特的关系,相当于关联表就是日前表。

mapping_limit

关联要赶回的笔录数据(HAS_MANY和MANY_TO_MANY才有此属性)

mapping_order

提到查询的排序 (HAS_MANY和MANY_TO_MANY才有此属性)

本文由68399皇家赌场发布于最新解决方案,转载请注明出处:的完整定义详解,ThinkPHP的关联操作实例

关键词: 68399皇家赌场

最火资讯