以这段代码为例:
public function actionPostOneWay( $postId )
{
$dependency = new CDbCacheDependency( 'SELECT publish_date FROM posts WHERE id = :post_id;' );
$dependency->params = array( 'post_id'=>$postId );
$post = Post::model()->cache( 59, $dependency )->findByPk( $postId );
// process post one way
}
public function actionPostAnotherWay( $postId )
{
$dependency = new CDbCacheDependency( 'SELECT publish_date FROM posts WHERE id = :post_id;' );
$dependency->params = array( 'post_id'=>$postId );
$post = Post::model()->cache( 59, $dependency )->findByPk( $postId );
// process post another way
}
Run Code Online (Sandbox Code Playgroud)
那么访问/postOneWay和/postAnotherWay重用相同的缓存对象,还是会创建自己的缓存对象?
我尝试在两个不同的操作中缓存相同的查询,是的,将使用相同的缓存对象.可以看到CProfileLogRoute在应用程序的配置文件中启用.
查看CActiveRecord类的源代码我说的public function findByPk($pk,$condition='',$params=array())方法(和其他查询方法)使用protected function query($criteria,$all=false).反过来,这一个最终依赖于Yii使用数据库查询进行缓存private function queryInternal($method,$mode,$params=array())的CDbCommand类.
可以看到用于存储和恢复查询的缓存键的结果定义如下:
$cacheKey='yii:dbquery'.$this->_connection->connectionString.':'.$this->_connection->username;
$cacheKey.=':'.$this->getText().':'.serialize(array_merge($this->_paramLog,$params));
if(($result=$cache->get($cacheKey))!==false)
{
Yii::trace('Query result found in cache','system.db.CDbCommand');
return $result;
}
Run Code Online (Sandbox Code Playgroud)
此密钥不考虑缓存依赖项实例.CDbCacheDependency仅用于确定数据库中是否更改了某些内容,并且要执行新查询以更新缓存.更多 - 如果指定要CDbCacheDependency在两个操作中创建的不同SQL,则只有其中一个(首先执行)在缓存时有意义,因为CDbCacheDependency缓存序列化的实例与查询结果一起:
if(isset($cache,$cacheKey))
$cache->set($cacheKey, $result, $this->_connection->queryCachingDuration, $this->_connection->queryCachingDependency);
Run Code Online (Sandbox Code Playgroud)
在类的public function set($id,$value,$expire=0,$dependency=null)方法中可以看到缓存已评估依赖项的实例CCache:
if ($dependency !== null && $this->serializer !== false)
$dependency->evaluateDependency();
if ($this->serializer === null)
$value = serialize(array($value,$dependency));
elseif ($this->serializer !== false)
$value = call_user_func($this->serializer[0], array($value,$dependency));
Run Code Online (Sandbox Code Playgroud)