Active Record(AR)是一种流行的 对象-关系映射(ORM)技术,其映射关系为
- AR class:数据表
- AR class property:数据表的一列
- AR 实例:数据表的一条数据
所以对于常用的数据库操作(CRUD)可以转化成一种面向对象的数据操作形式。
实现一个AR类的的最简代码如下:
class Post extends CActiveRecord
{
public static function model($className=__CLASS__)
{
return parent::model($className);
}
public function tableName()
{
return 'tbl_post';
}
}
只需重载数据表方法tableName,返回数据表名字即可。
但是现在的问题是,如果数据表的名字不确定,是否可以在插入或者查询时动态的分配数据表的名字。例如,如果对业务中的log流水做查询的工作,我们知道,一般写log时都是每天一张表,例如tbl_log_20140601, tbl_log_20140602, ...。因此没有办法把每天定义成一个AR class。
解决方法如下:
/*
* Usage:
* $result = Log::model()->setDate("20140603")->findAll();
*/
class Log extends CActiveRecord
{
private $_date;
public static function model($className=__CLASS__)
{
return parent::model($className);
}
public function tableName()
{
return "tbl_log_". $this->getDate();
}
public function setDate($date){
$this->_date = $date;
$this->refreshMetaData();
return $this;
}
public function getDate(){
if($this->_date === NULL){
$this->setDate("20140601");
}
return $this->_date;
}
}
其使用方法为:
$result = Log::model()->setDate("20140603")->findAll();
在执行Log::model()时,Yii框架会初始化当前的instance,因此会立刻调用tableName(),并且形成一些中间数据(metaData),因此在setDate以后需要调用 refreshMetaData() 来刷新当前已经形成的中间数据。
简要做个笔记,希望对大家有帮助。