在 Yii 里面对数据库操作有一个很方便的功能就是多表关联,通过在 model
里面指定对某个表的关联,这样就可以很快得到相关信息而不需要自己去写复杂的 sql
语句。
下面我们拿 user
表和 news
表举例。(一个用户发表了多篇文章)
首先,我们需要在我们需要的 model
里面的配置 relation
:User Model
:
public function relations()
{
return array(
'news' => array(self::HAS_MANY, 'News', 'uid', 'order'=>'nid DESC'),
);
}
在 news
表中我们有一个 uid
字段对应着 user
表的 primary key
(uid
),因为 uid
是 user
表的索引,所以这里只用指定 news
表中的字段即可。
当我们需要指定其他的字段时可以这样写:
'news' => array(self::HAS_MANY, 'News', array('uid'=>'user_id') ),
//这样就是news 表中字段uid与user表中user_id对应
我们执行如下的代码看效果:
$user = User::app()->model()->fingByPk( $uid );
printr( $user );
在我们取出的 $user
中就会存在 news
的信息:
$allnews = $user->news;
foreach( $allnews as $new ) {
printr( $new );
}
这样我们就完成了简单的两个表之间的关联。在上面的例子中我们会看到 self::HAS_MANY
这个东西,在 Yii 里面还有其他的几种关系:
HAS_ONE // 一对一
HAS_MANY // 一对多
BELONGS_TO // 多对一
MANY_TO_MANY // 多对多
在 News Model
中我们也可以指定那样一个 relation
:News Model
:
public function relations()
{
return array(
'user' => array(self::BELONGS_TO, 'User', 'uid'),
);
}
在我们取出的 news
中每一条都会附带上 User
的数据,方便操作。
$allnews = News::app()->model()->findAll();
foreach( $allnews as $new ) {
printr( $new->user );
}
其他的两种情况就不演示了,同样的道理。
在上面的例子中我们会看到前一个有一个 order
参数,而第二个没有。这个很好理解,就相当于我们 sql
语句中的条件。常见的条件有:
condition
order
with
joinType
select
params
on
alias
together
group
having
index
还有用于lazy loading
的:
limit // 只取5个或10个
offset
through
官方手册:
'posts'=>array(self::HAS_MANY, 'post', 'author_id', 'order'=>'posts.create_time DESC', 'with'=>'categories')
详细的语法可以去看官方文档。