在AR类中声明关联时,每个关联会作为一个属性添加到AR类中,属性名就是关联的名称。在进行关联查询时,这些属性就会被设置为关联到的AR类的实例,例如在查询取得一个Post实例时,它的$author属性就是代表Post作者的一个User类的实例。
2、关联查询
进行关联查询最简单的方式就是访问一个关联AR对象的某个关联属性。如果这个属性之前没有被访问过,这时就会启动一个关联查询,通过当前AR对象的主键连接
相关的表,来取得关联对象的值,然后将这些数据保存在对象的属性中。这种方式叫做“延迟加载”,也就是只有等到访问到某个属性时,才会真正到数据库中把这
些关联的数据取出来。下面的例子描述了延迟加载的过程:
// retrieve the post whose ID is 10 $post=Post::model()->findByPk(10); // retrieve the post's author: a relational query will be performed here $author=$post->author;
在不同的关联情况下,如果没有查询到结果,其返回的值也不同:BELONGS_TO 和 HAS_ONE 关联,无结果时返回null; HAS_MANY 和 MANY_MANY, 无结果时返回空数组。
延迟加载方法使用非常方便,但在某些情况下并不高效。例如,若我们要取得N个post的作者信息,使用延迟方法将执行N次连接查询。此时我们应当使用所谓的急切加载方法。
急切加载方法检索主要的 AR 实例及其相关的 AR 实例. 这通过使用 with() 方法加上 find 或 findAll 方法完
成。例如,
$posts=Post::model()->with('author')->findAll();
上面的代码将返回一个由 Post 实例组成的数组. 不同于延迟加载方法,每个Post 实例中的author 属性在我们访问此属性之前已经被关联的
User 实例填充。不是为每个post 执行一个连接查询, 急切加载方法在一个单独的连接查询中取出所有的 post 以及它们的author!
我们可以在with()方法中指定多个关联名字。例如, 下面的代码将取回 posts 以及它们的作者和分类:
$posts=Post::model()->with('author','categories')->findAll();
我们也可以使用嵌套的急切加载。不使用一个关联名字列表, 我们将关联名字以分层的方式传递到 with() 方法, 如下,
$posts=Post::model()->with( 'author.profile', 'author.posts', 'categories')->findAll();
上面的代码将取回所有的 posts 以及它们的作者和分类。它也将取出每个作者的profile和 posts.
急切加载也可以通过指定 CDbCriteria::with 属性被执行, 如下:
$criteria=new CDbCriteria; $criteria->with=array( 'author.profile', 'author.posts', 'categories', ); $posts=Post::model()->findAll($criteria); 或 $posts=Post::model()->findAll(array( 'with'=>array( 'author.profile', 'author.posts', 'categories', ) );
3、关联查询选项
之前我们提到额外的参数可以被指定在关联声明中。这些选项,指定为 name-value 对,被用来定制关联查询。它们被概述如下:
select: 为关联 AR 类查询的字段列表。默认是 '*', 意味着所有字段。查询的字段名字可用别名表达式来消除歧义(例如:COUNT(??.name) AS nameCount)。
condition: WHERE 子语句。默认为空。注意, 列要使用别名引用(例如:??.id=10)。
params: 被绑定到 SQL 语句的参数. 应当为一个由 name-value 对组成的数组()。
on: ON 子语句. 这里指定的条件将使用 and 操作符被追加到连接条件中。此选项中的字段名应被消除歧义。此选项不适用于 MANY_MANY 关联。
order: ORDER BY 子语句。默认为空。注意, 列要使用别名引用(例如:??.age DESC)。
with: 应当和此对象一同载入的子关联对象列表. 注意, 不恰当的使用可能会形成一个无穷的关联循环。
joinType: 此关联的连接类型。默认是 LEFT OUTER JOIN。
aliasToken:列前缀占位符。默认是“??.”。
alias: 关联的数据表的别名。默认是 null, 意味着表的别名和关联的名字相同。
together: 是否关联的数据表被强制与主表和其他表连接。此选项只对于HAS_MANY 和 MANY_MANY 关联有意义。若此选项被设置为 false, ......(此处原文出错!).默认为空。此选项中的字段名以被消除歧义。
having: HAVING 子语句。默认是空。注意, 列要使用别名引用。