首页 > 代码库 > Yii Active Record 动态数据表

Yii Active Record 动态数据表

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;
        call_user_func(array(get_class($this),‘model‘))->_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() 来刷新当前已经形成的中间数据。


简要做个笔记,希望对大家有帮助。