当前位置:K88软件开发文章中心网站服务器框架ThinkPHP → 文章内容

关联模型

减小字体 增大字体 作者:佚名  来源:网上搜集  发布时间:2019-1-26 15:33:27

要查询的字段 默认情况下,关联查询的关联数据是关联表的全部字段,如果只是需要查询个别字段,可以定义关联的mapping_fields属性。mapping_limit关联要返回的记录数目mapping_order关联查询的排序外键的默认规则是当前数据对象名称_id,例如:UserModel对应的可能是表think_user (注意:think只是一个表前缀,可以随意配置) 那么think_user表的外键默认为 user_id,如果不是,就必须在定义关联的时候定义 foreign_key 。MANY_TO_MANYMANY_TO_MANY 关联表示当前模型可以属于多个对象,而父对象则可能包含有多个子对象,通常两者之间需要一个中间表类约束和关联。例如每个用户可以属于多个组,每个组可以有多个用户:'Group' => self::MANY_TO_MANY完整定义方式为:'Group' => array( 'mapping_type' => self::MANY_TO_MANY, 'class_name' => 'Group', 'mapping_name' => 'groups', 'foreign_key' => 'userId', 'relation_foreign_key' => 'groupId', 'relation_table' => 'think_group_user' //此处应显式定义中间表名称,且不能使用C函数读取表前缀 )MANY_TO_MANY支持的关联属性定义有:属性描述class_name要关联的模型类名mapping_name关联的映射名称,用于获取数据用 该名称不要和当前模型的字段有重复,否则会导致关联数据获取的冲突。foreign_key关联的外键名称 外键的默认规则是当前数据对象名称_idrelation_foreign_key关联表的外键名称 默认的关联表的外键名称是表名_idmapping_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属性。3.2.2版本开始,relation_table定义支持简化写法,例如:'relation_table'=>'__USER_GROUP__'关联查询由于性能问题,新版取消了自动关联查询机制,而统一使用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_fields属性的话,protected $_link = array( 'Profile'=>array( 'mapping_type' => self::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);当MANY_TO_MANY时,不建议使用关联插入。关联更新数据的关联更新和关联写入类似$User = D("User");$data["account"] = "ThinkPHP";$data["password"] = "123456";$data["Profile"] = array( 'email' =>'liu21st@gmail.com', 'nickname' =>'流年',);$result = $User-> relation(true)->where(array('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");

上一页  [1] [2] 


关联模型