说说CakePHP的关联模型之一 基本关联

一个无论多么复杂的程序,拆开看无非是三种逻辑结构的组合:顺序结构、条件结构和循环结构。

类似的,数据库中表与表的之间的关联无外乎四种:一对一、一对多、多对一和多对多。

CakePHP的模型层中定义了四种关联模型分别来表示上面的四种关系,他们是hasOne、hasMany、belongsTo和hasAndBelongsToMany。

下面根据代码及生成SQL语句来了解这几种关联模型的用法。

hasOne

假设一条User表的记录对应一条UserSocialInformation表中的记录。

此时UserSocialInformation表中必须要有与User表关联的字段,作为User表的外键。即被关联的模型包含外键

命名格式可以是关联的表名+'_id',如user_id。这种格式。

class User extends AppModel {
    var $hasOne = 'UserSocialInformation';
}

查询User表中的首条记录:$this->User->find('first');

生成的SQL

SELECT 
`User`.`id`, `User`.`created`, `User`.`modified`, `User`.`agent_id`, `User`.`first_name`, `User`.`last_name`,
`UserSocialInformation`.`id`, `UserSocialInformation`.`user_id` FROM `users` AS `User` 
LEFT JOIN `user_social_informations` AS `UserSocialInformation` ON (`UserSocialInformation`.`user_id` = `User`.`id`) 
WHERE 1 = 1 LIMIT 1

注意ON (`UserSocialInformation`.`user_id` = `User`.`id`),两者的关联就靠他了。

belongTo

与hasOne类似,若我们想通过UserSocialInformation表查询时同时也把User表的信息查出来,此时必须当前模型包含外键

class UserSocialInformation extends AppModel {
    var $name = 'UserSocialInformation';
    var $belongsTo = array('User');
}

通过UserSocialInformation查询:$this->UserSocialInformation->find();

生成的SQL

SELECT 
`UserSocialInformation`.`id`,`UserSocialInformation`.`user_id` ,  
`User`.`id`, `User`.`created`, `User`.`modified`, `User`.`agent_id`, `User`.`group_id` 
FROM `user_social_informations` AS `UserSocialInformation` 
LEFT JOIN `users` AS `User` ON (`UserSocialInformation`.`user_id` = `User`.`id`) 
WHERE 1 = 1 LIMIT 1

延伸

一个用户属于某一个组(group)同时属于某一个代理商(agent),意味着user表中要有对应group表和agent表的外键,为了规范,最好命名为group_id和agent_id,这样CakePHP会自动关联。

class User extends AppModel {
  var $name = 'User';
  var $belongsTo = array('Group', 'Agent');
}

查询时生成的大概SQL(省去了多余的表字段)

SELECT `User`.`id`, `User`.`created`, `User`.`modified`, `User`.`agent_id`, `User`.`group_id`,  `User`.`username`, `User`.`password`,
`Group`.`id`, `Group`.`parent_id`, `Group`.`name`, 
`Agent`.`id`, `Agent`.`affiliate_id`, `Agent`.`agency_name`
FROM `users` AS `User` 
LEFT JOIN `groups` AS `Group` ON (`User`.`group_id` = `Group`.`id`) 
LEFT JOIN `agents` AS `Agent` ON (`User`.`agent_id` = `Agent`.`id`) WHERE 1 = 1 LIMIT 1

hasMany

打开一篇文章可能有属于该文章的多条评论,他们是一对多的关系。我们可以在文章表和留言表之间建立关联,留言表中保存文章表的主键。即其他模型包含外键

这样就可以把一篇文章的记录和属于该文章的评论全部提取出来。

类似的以一条房屋表Property记录包含多条房屋图片(PropertyImage)记录为例。

Property的模型文件

class Property extends AppModel {
    var $name = 'Property';
    public $hasMany = array('PropertyImages'=>array('order'=>'PropertyImages.is_deleted, PropertyImages.order_image ASC'));
}

PropertyImage的模型文件

class PropertyImage extends AppModel {
  var $name = 'PropertyImage';
 }

查询指定ID的房屋记录

$result = $this->Property->findById('cec390de-75dd-4544-351c-f34a408e6f51');

CakePHP会自动进行两条查询语句

SELECT `Property`.`id`, `Property`.`modified`,`Property`. ......
FROM `properties` AS `Property` 
WHERE `Property`.`id` = 'cec390de-75dd-4544-351c-f34a408e6f51' LIMIT 1

SELECT `PropertyImages`.`id`, `PropertyImages`.`property_id`, `PropertyImages`.`image_name`......
FROM `property_images` AS `PropertyImages` 
WHERE `PropertyImages`.`property_id` = ('cec390de-75dd-4544-351c-f34a408e6f51') 
ORDER BY `PropertyImages`.`is_deleted` ASC, `PropertyImages`.`order_image`

生成的结果是个数组,结构类似:

Array
(
    [Property] => Array
        (
            [id] => cec390de-75dd-4544-351c-f34a408e6f51
            [modified] => 2013-10-28 16:40:15
        )

    [PropertyImages] => Array
        (
            [0] => Array
                (
                    [id] => 3ee846ec-e378-e014-8196-a5acdb8dcb32
                    [property_id] => cec390de-75dd-4544-351c-f34a408e6f51
                    [image_name] => 1330043177_20111118174028.jpg
                )

            [1] => Array
                (
                    [id] => 3ebf5363-580a-50c4-b55d-c11b0f958876
                    [property_id] => cec390de-75dd-4544-351c-f34a408e6f51
                    [image_name] => 1330043177_201111161100362.jpg
                )

            [2] => Array
                (
                    [id] => 9c34181f-f2fd-6d84-25cd-23583535e218
                    [property_id] => cec390de-75dd-4544-351c-f34a408e6f51
                    [image_name] => 1330043178_201111181740281.jpg
                )

            [3] => Array
                (
                    [id] => 94d817a4-5bb0-ae94-adbc-0749f63c4cff
                    [property_id] => cec390de-75dd-4544-351c-f34a408e6f51
                    [image_name] => 1330043175_1_Orana_St.jpg
                )

这种结构结果使用起来非常方便。

原文地址:https://www.cnblogs.com/mafeifan/p/3402849.html