• yii框架详解 之 CActiveRecord


    【特别注意事项】
    1、所有要用于访问的属性,都要先在类中声明(原数据表中的字段是默认可访问的,自定义的属性值,一定要先在类中添加声明,才可以正常访问)
    2、数据库的表面引用,一般都是有固定的数据库表前缀的,在类中,使用 {{tableName}} 代表着 table_pre.tableName
    3、model()方法是 static 方法,不用实例化即可直接使用,多用于查询。
    4、rules() 方法 是用来验证字段合法性的,而且可以设置每个规则的应用环境标示,如 'on'=>'search',这点要好好利用。
    5、attributeLabels() 方法是设置每个字段的描述信息。
    6、search()方法,用来查询

    【如何获取关联数据表的其他字段值】
    1)首先在关系声明里,指定要查询的字段别名
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    /**
         * @return array relational rules.
         */
        public function relations()
        {
            // NOTE: you may need to adjust the relation name and the related
            // class name for the relations automatically generated below.
            return array(
                'visas'=>array(self::MANY_MANY, 'Visa',
                    '{{visa_to_order}}(id_order, id_visa)',
                    'select'=>array(
                        '*',                                  #获取所有字段
                       'visas_visas.price AS price_visa',     #visas_visas是关系表的别名,获取关系表里的字段值
                    ),
                ),
     
                'user'=>array(self::BELONGS_TO, 'User','id_customer)'),
            );
        }

    2)然后,将关系别名在AR实体里增加保存其值的属性。
    class Visa extends CActiveRecord
    {
        public $price_visa;
    }

    3)然后通过关联实体来访问该别名字段的值。
    $orderModel->visas[0]->price_visa;


    BELONGS_TO关系表,关联的keyid如何自定义指定

    Yii的relations里self::BELONGS_TO默认是用当前指定的键跟关联表的主键进行join,例如:

    return array(
    'reply' => array(self::BELONGS_TO, 'BookPostReply', 'postid'),
    );

    默认生成的sql是 on id = postid,id是BookPostReply的主键。
    但今天我遇到的需求却是需要生成 on BookPostReply.postid = t.postid,不去关联主键,

    后来无意中看到有个on的属性,刚好跟sql里的on一样,于是抱着试试的想法,在配置里加了上去

    return array(
    'reply' => array(self::BELONGS_TO, 'BookPostReply', 'postid', 'on' => 't.postid=reply.postid'),
    );

    看调试信息里的SQL语句,发现yii生成了一条 on id = postid and t.postid=reply.postid 这样的语句,看到这就已经明白这个东西的作用了,于是将postid清空,改成如下:

    return array(
    'reply' => array(self::BELONGS_TO, 'BookPostReply', '', 'on' => 't.postid=reply.postid'),
    );

    其实,Yii的文档有说明: 如果你需要指定自定义的pk->fk关联,你可以定义数组(‘fk’=> ‘pk')。



    【多条件下关联查询结果集】

    案例:

    $this->news = News::model()->with(array(

                    'sites'=>array('condition'=>'sites.id_site='.Yii::app()->params['siteId'],'together'=>true),

                    'categories'=>array('condition'=>'categories.id_category='.$this->categoryId,'together'=>true),

                ))->findAll(array(

                        'limit'=>$this->limit,

                        'condition'=>'t.active=1',

                        'order'=>'t.position'

                    ));

    使用with('关系名称1','关系名称2')方法,将延后查询关联表,

    若如上案例,在with方法中,返回关系数组,将更灵活。

    若想即时联合查询,需要添加'together'=>true属性值,才会组合为一句SQL进行查询。



    我们来看下CActiveRecord.php文件里,yii是如何设计with()方法的。

    /**

    * Specifies which related objects should be eagerly loaded.

    * This method takes variable number of parameters. Each parameter specifies

    * the name of a relation or child-relation. For example,

    * <pre>

    * // find all posts together with their author and comments

    * Post::model()->with('author','comments')->findAll();

    * // find all posts together with their author and the author's profile

    * Post::model()->with('author','author.profile')->findAll();

    * </pre>

    * The relations should be declared in {@link relations()}.

    *

    * By default, the options specified in {@link relations()} will be used

    * to do relational query. In order to customize the options on the fly,

    * we should pass an array parameter to the with() method. The array keys

    * are relation names, and the array values are the corresponding query options.

    * For example,

    * <pre>

    * Post::model()->with(array(

    *     'author'=>array('select'=>'id, name'),

    *     'comments'=>array('condition'=>'approved=1', 'order'=>'create_time'),

    * ))->findAll();

    * </pre>

    *

    * @return CActiveRecord the AR object itself.

    */

    public function with()

    {

    if(func_num_args()>0)

    {

    $with=func_get_args();

    if(is_array($with[0]))  // the parameter is given as an array

    $with=$with[0];

    if(!empty($with))

    $this->getDbCriteria()->mergeWith(array('with'=>$with));

    }

    return $this;

    }


    我们再去看 CDbCriteria 类中的 mergeWith 方法定义

    /**

    * Merges with another criteria.

    * In general, the merging makes the resulting criteria more restrictive.

    * For example, if both criterias have conditions, they will be 'AND' together.

    * Also, the criteria passed as the parameter takes precedence in case

    * two options cannot be merged (e.g. LIMIT, OFFSET).

    * @param mixed $criteria the criteria to be merged with. Either an array or CDbCriteria.

    * @param string|boolean $operator the operator used to concatenate where and having conditions. Defaults to 'AND'.

    * For backwards compatibility a boolean value can be passed:

    * - 'false' for 'OR'

    * - 'true' for 'AND'

    */

    public function mergeWith($criteria,$operator='AND'){......}



    注意,这里就是我要强调的地方,yii默认且只执行关联表之间的AND条件查询,也就是说,在给定不同条件查询时,yii只为我们求取不同条件的交集结果返回。

    但是在底层的CDbCriteria 类中,预留了参数$operator给我们。有需求的同学需要重写CActiveRecord来实现拓展了哦。

















  • 相关阅读:
    Mysql-存储过程-批量增加数据
    VIM
    查看Chrome浏览器同步数据状态工具
    Tomcat运行配置
    mysql的engine不同,导致事物回滚失败的问题
    git在MAC,Linux的terminator(命令行)下自动显示当前分支
    SED单行脚本快速参考(Unix 流编辑器)
    awk中使用shell的环境变量
    Grep Sed Awk
    shred_linux_unix
  • 原文地址:https://www.cnblogs.com/caryfang/p/4535901.html
Copyright © 2020-2023  润新知