如上所示,我们通过 Post::model() 调用 find 方法。请记住,静态方法 model() 是每个AR类所必须的。此方法返回在对象上下文中的一个用于访问类级别方法(类似于静态类方法的东西)的AR实例。
如果find方法找到了一个满足查询条件的行,它将返回一个Post实例,实例的属性含有数据表行中相应列的值。然后我们就可以像读取普通对象的属性那样读取载入的值,例如 echo $post->title;。
如果使用给定的查询条件在数据库中没有找到任何东西, find 方法将返回null。
调用find时,我们使用 $condition 和 $params 指定查询条件。此处 $condition 可以是 SQL 语句中的 WHERE 字符串,$params 则是一个参数数组,其中的值应绑定到 $condation 中的占位符。例如:
// 查找 postID=10 的那一行 $post=Post::model()->find('postID=:postID', array(':postID'=>10));
注意: 在上面的例子中,我们可能需要在特定的 DBMS 中将 postID 列的引用进行转义。 例如,如果我们使用 PostgreSQL,我们必须将此表达式写为 "postID"=:postID,因为 PostgreSQL 在默认情况下对列名大小写不敏感。
我们也可以使用 $condition 指定更复杂的查询条件。不使用字符串,我们可以让 $condition 成为一个 CDbCriteria 的实例,它允许我们指定不限于 WHERE 的条件。例如:
$criteria=new CDbCriteria; $criteria->select='title'; // 只选择 'title' 列 $criteria->condition='postID=:postID'; $criteria->params=array(':postID'=>10); $post=Post::model()->find($criteria); // $params 不需要了
注意,当使用 CDbCriteria 作为查询条件时,$params 参数不再需要了,因为它可以在 CDbCriteria 中指定,就像上面那样。
一种替代 CDbCriteria 的方法是给 find 方法传递一个数组。数组的键和值各自对应标准(criterion)的属性名和值,上面的例子可以重写为如下:
$post=Post::model()->find(array( 'select'=>'title', 'condition'=>'postID=:postID', 'params'=>array(':postID'=>10), ));
当一个查询条件是关于按指定的值匹配几个列时,我们可以使用 findByAttributes()。我们使 $attributes
参数是一个以列名做索引的值的数组。在一些框架中,此任务可以通过调用类似 findByNameAndTitle
的方法实现。虽然此方法看起来很诱人, 但它常常引起混淆,冲突和比如列名大小写敏感的问题。
当有多行数据匹配指定的查询条件时,我们可以通过下面的 findAll 方法将他们全部带回。每个都有其各自的 find 方法,就像我们已经讲过的那样。
// 查找满足指定条件的所有行 $posts=Post::model()->findAll($condition,$params); // 查找带有指定主键的所有行 $posts=Post::model()->findAllByPk($postIDs,$condition,$params); // 查找带有指定属性值的所有行 $posts=Post::model()->findAllByAttributes($attributes,$condition,$params); // 通过指定的SQL语句查找所有行 $posts=Post::model()->findAllBySql($sql,$params);
如果没有任何东西符合查询条件,findAll 将返回一个空数组。这跟 find 不同,find 会在没有找到什么东西时返回 null。
除了上面讲述的 find 和 findAll 方法,为了方便,(Yii)还提供了如下方法:
// 获取满足指定条件的行数 $n=Post::model()->count($condition,$params); // 通过指定的 SQL 获取结果行数 $n=Post::model()->countBySql($sql,$params); // 检查是否至少有一行复合指定的条件 $exists=Post::model()->exists($condition,$params);
5、更新记录
在 AR 实例填充了列的值之后,我们可以改变它们并把它们存回数据表。
$post=Post::model()->findByPk(10); $post->title='new post title'; $post->save(); // 将更改保存到数据库
正如我们可以看到的,我们使用同样的 save() 方法执行插入和更新操作。如果一个 AR 实例是使用 new 操作符创建的,调用save()
将会向数据表中插入一行新数据;如果 AR 实例是某个 find 或 findAll 方法的结果,调用 save()
将更新表中现有的行。实际上,我们是使用 CActiveRecord::isNewRecord 说明一个 AR 实例是不是新的。
直接更新数据表中的一行或多行而不首先载入也是可行的。 AR 提供了如下方便的类级别方法实现此目的:
// 更新符合指定条件的行 Post::model()->updateAll($attributes,$condition,$params); // 更新符合指定条件和主键的行 Post::model()->updateByPk($pk,$attributes,$condition,$params); // 更新满足指定条件的行的计数列 Post::model()->updateCounters($counters,$condition,$params);