zoukankan      html  css  js  c++  java
  • 说说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
                    )

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

  • 相关阅读:
    服务器选型:x86 vs 小型机谁更胜一筹?
    MySQL与PostgreSQL相比哪个更好?
    微服务架构优缺点
    聊聊Flume和Logstash的那些事儿
    HDFS文件系统
    阿里巴巴鹰眼技术解密
    OLAP、OLTP的介绍和比较
    storm架构及原理
    swift ClassNameFromString 的替换方法 + 创建TableviewHelper
    swift 屏幕的翻转 + 状态栏(statusBar)的隐藏
  • 原文地址:https://www.cnblogs.com/mafeifan/p/3402849.html
Copyright © 2011-2022 走看看