Yii 多表关联

582 查看

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 keyuid),因为 uiduser 表的索引,所以这里只用指定 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')

详细的语法可以去看官方文档