发布于 2015-12-14 10:27:00 | 113 次阅读 | 评论: 0 | 来源: PHPERZ

这里有新鲜出炉的YII 2.0教程,程序狗速度看过来!

Yii高性能PHP框架

Yii Framework是一个基于组件、用于开发大型 Web 应用的高性能 PHP 框架。Yii提供了今日Web 2.0应用开发所需要的几乎一切功能。Yii是最有效率的PHP框架之一。Yii是创始人薛强的心血结晶,于2008年1月1日开始开发。


表结构

article文章表:aritlceid,content,id(文章发表人的id)

comment评论表:commentid,content,id(评论人的id),articleid(外键)

reply回复表:replyid,content,id(回复人的id),commentid(外键)

user用户表:id,name

关联关系

基于yii 1.16
article->comment->reply,从左到右,两两之间是一对多关系,当然发过来,从右到左是多对一关系。
上面每个表与user之间的关系是多对一关系.
article.php

<?php
class Article extends CActiveRecord{
    ...
    public function tableName()
    {
        return 'article';
    }
    public function relations()
    {
        return array(
            'comments'=>array(self::HAS_MANY, 'comment', 'articleid'),
            'user'=>array(self::BELONGS_TO, 'user', 'id')
        );
    }
}

comment.php

<?php
class Comment extends CActiveRecord{
    ...
    public function tableName()
    {
        return 'comment';
    }
    public function relations()
    {
        return array(
            'article'=>array(self::BELONGS_TO, 'article', 'articleid'),
            'replys'=>array(self::HAS_MANY, 'reply', 'commentid'),
            'user'=>array(self::BELONGS_TO, 'user', 'id')
        );
    }
}

reply.php

<?php
class Reply extends CActiveRecord{
    ...
    public function tableName()
    {
        return 'reply';
    }
    public function relations()
    {
        return array(
            'user'=>array(self::BELONGS_TO, 'user', 'id'),
            'comment'=>array(self::BELONGS_TO,'comment','commentid')
        );
    }
}

user.php

<?php
class User extends CActiveRecord{
    ...
    public function tableName()
    {
        return 'user';
    }
}

查询

符合要求的article

所有字段

选取articleid=1的文章

$article=Article::model()->find(array(
    'condition'=>'articleid=:articleid',
    'params'=>array(':articleid'=>1)
));
foreach ($article as $key => $value) {
    var_dump($key);
    var_dump($value);
    echo "<br>";
}

部分字段

$article=Article::model()->find(array(
    'select'=>'content',
    'condition'=>'articleid=:articleid',
    'params'=>array(':articleid'=>1)
));

选取article及其对应的comment

这里有一对多关联,就不用懒加载了.

$articles=Article::model()->with(array('comments'))->findAll();

输出

        foreach ($articles as $article) {
            echo "<br>";
            var_dump($article->articleid);
            var_dump($article->id);
            var_dump($article->content);
            echo "<br>";
            foreach ($article->comments as $key => $value) {
                var_dump($value->commentid);
                var_dump($value->content);
                var_dump($value->id);
                echo "<br>";
            }
        }


可以看到,active record确实选取了第一篇文章及其下面的5条评论,第二篇文章及其下面的2条评论,以及后面的三篇文章,它们下面没有评论。

  • findAll()方法返回一个列表,find()方法永远只返回一个结果。如果有多个结果,则只返回第一个。

  • with()方法一次性加载关联

加载article关联的user表

$articles=Article::model()->with(array('user','comments'))->findAll();

输出

        foreach ($articles as $article) {
            ...
            var_dump($article->user->name);
            echo "<br>";
        }

加载comment关联的user表

$articles=Article::model()->with(array('user','comments','comments.user'))->findAll();

这时会出现Syntax error or access violation: 1066 Not unique table/alias: 'user',因为本屌懒,把所有多对一关联都设置成'user'=>array(self::BELONGS_TO, 'user', 'id').如果comment设置成'comment_user'=>array(self::BELONGS_TO, 'user', 'id'),查询变成

$articles=Article::model()->with(array('user','comments','comments.comment_user'))->findAll();

就不会报错了.
那么如果不改关联怎么办?

Article::model()->with(array(
    'user',
    'comments',
    'comments.user'=>array('alias'=>'comment_user')))
->findAll();

with()方法也可以像find()方法那样,传入关联数组作为参数。这里为comments.user设置一个别名就行了。

array(
    'alias'=>'article',
    ...
)

选取comment部分字段

前面选取article部分字段时,用的是findAll(array('select'=>'...')),这里不能

Article::model()->with(array(
    'user',
    'comments',
    'comments.user'=>array('alias'=>'comment_user')))
->findAll(array(
    'select'=>array('comments.content')
));

应该像上面为关联添加别名那样

Article::model()->with(
    array('user',
          'comments'=>array('select'=>'content'),
          'comments.user'=>array('alias'=>'comment_user')
))->findAll();

输出

        foreach ($articles as $article) {
            ...
            foreach ($article->comments as $key => $value) {
                ...
                var_dump($value->user->name);
                echo "<br>";
            }
        }


可以看到,comment表的id字段没有值,content有值。
comment表的id字段可以用$value->user->id从关联的user那获得,但那是user对象里面的。

选取comment对应的reply

这下有两个一对多关系了

$articles=Article::model()->with(array(
    'user',
    'comments'=>array('select'=>'content'),
    'comments.user'=>array('alias'=>'comment_user'),
    'comments.replys'))
->findAll();

输出

        foreach ($articles as $article) {
            ...
            foreach ($article->comments as $key => $value) {
                ...
                foreach ($value->replys as $key => $value) {
                    var_dump($value->replyid);
                    var_dump($value->content);
                    var_dump($value->id);
                    echo "<br>";
                }
                echo "<br>";
            }
        }


可以看到,只有第1,2条评论有回复。
事实上,如果不选取comment部分字段的话,可以直接

$articles=Article::model()->with(array(
    'user',
    'comments.user'=>array('alias'=>'comment_user'),
    'comments.replys'))
->findAll();

加载reply关联的user表

和前面comment关联user一样

Article::model()->with(array(
    'user',
    'comments'=>array('select'=>'content'),
    'comments.user'=>array('alias'=>'comment_user'),
    'comments.replys',
    'comments.replys.user'=>array('alias'=>'reply_user')))
->findAll();

选取reply部分字段

Article::model()->with(array(
    'user',
    'comments'=>array('select'=>'content'),
    'comments.user'=>array('alias'=>'comment_user'),
    'comments.replys'=>array('select'=>'content'),
    'comments.replys.user'=>array('alias'=>'reply_user')))
->findAll();

条件查询

选取articleid=1的文章以及其评论,还有对应的回复

Article::model()->with(array(
    'user',
    'comments.user'=>array('alias'=>'comment_user'),
    'comments.replys',
    'comments.replys.user'=>array('alias'=>'reply_user')))
->findAll(array(
    'condition'=>'articleid=:articleid',
    'params'=>array(':articleid'=>1),
    'alias'=>'article'
));

这时会报错: Integrity constraint violation: 1052 Column 'articleid' in where clause is ambiguous.还是命名冲突.在findAll()方法的参数里设置article别名,条件列前加上设置好的别名就行了。

Article::model()->with(array(
    'user',
    'comments.user'=>array('alias'=>'comment_user'),
    'comments.replys',
    'comments.replys.user'=>array('alias'=>'reply_user')))
->findAll(array(
    'condition'=>'article.articleid=:articleid',
    'params'=>array(':articleid'=>1),
    'alias'=>'article'
));

选取articleid=1且commentid=1的文章以及其评论,还有对应的回复

Article::model()->with(array(
    'user',
    'comments.user'=>array('alias'=>'comment_user'),
    'comments.replys',
    'comments.replys.user'=>array('alias'=>'reply_user')))
->findAll(array(
    'condition'=>'article.articleid=:articleid and comments.commentid=:commentid',
    'params'=>array(':articleid'=>1,':commentid'=>1),
    'alias'=>'article'
));

注意,条件是comments.commentid=:commentid

comment,reply分页

mybatis一样,只能通过复杂的自定义sql实现.写完那纠结的sql后,调用Article::model()->findBySql($sql,$params)
至于最后结果能否映射到对象上,或者说映射到对象上对选取的列的字段名有什么要求,本屌没试过,不知道。



相关阅读 :
yii active record多表关联查询的一些细节
Yii多表联合查询操作详解
实例讲解YII2中多表关联的使用方法
Yii中的relations数据关联查询及统计功能用法详解
Yii实现数据库关联查询 示例
Yii框架关联查询with用法分析
YII 活动记录(Active Record)
详解YII关联查询
Yii框架实现多数据库配置和操作的方法
Yii使用DeleteAll连表删除出现报错问题的解决方法
Yii使用ajax验证显示错误messagebox的解决方法
Yii实现MySQL多数据库和读写分离实例分析
最新网友评论  共有(0)条评论 发布评论 返回顶部

Copyright © 2007-2017 PHPERZ.COM All Rights Reserved   冀ICP备14009818号  版权声明  广告服务