Yii2动态模型
本文字数:356 字 | 阅读时长 ≈ 1 min

Yii2动态模型

本文字数:356 字 | 阅读时长 ≈ 1 min

我们在使用Yii2框架时,有些业务会有一些特殊的场景,比如数据量大的时候,会考虑按月、年分表。
这样多个数据表的字段属性一模一样,这时若有一个动态的AR模型可以使用,体验将是极好的。

下面提供一个我在原AR上修改后得到的动态AR,详细代码如下:

<?php

namespace app\models;

use Yii;
use yii\db\ActiveQuery;

class Test extends \yii\db\ActiveRecord
{
    public static $table = '';

    /**
     * constructor.
     * @param array $table
     * @param array $config
     */
    public function __construct($table, $config = [])
    {
        self::$table = $table;
        parent::__construct($config);
    }

    /**
     * {@inheritdoc}
     */
    public static function instantiate($row)
    {
        return new static(self::tableName());
    }

    /**
     * {@inheritdoc}
     */
    public static function tableName()
    {
        return self::$table;
    }

    /**
     * {@inheritdoc}
     * @return ActiveQuery the newly created [[ActiveQuery]] instance.
     */
    public static function find($table = '')
    {
        self::$table = $table;
        return Yii::createObject(ActiveQuery::className(), [get_called_class(), ['from' => [self::tableName()]]]);
    }
}

假设我这里的规则是按月分表,假设我现在新增数据,则首先需要指定数据表,可以通过当前日期获取,如下:

$table = Yii::$app->db->schema->getRawTableName('{{%test_' . date('Ym', strtotime($date)) . '}}');

后面需要验证数据表是否存在,不存在则创建表(数据表中必须有原表test),代码如下:

$res = Yii::$app->db->createCommand("SHOW TABLES LIKE '{$table}'")->queryScalar();
if (empty($res)) {
    Yii::$app->db->createCommand("CREATE TABLE {$table} LIKE test")->execute();
}

模型的使用方式如下:

$table = Yii::$app->db->schema->getRawTableName('{{%test_' . date('Ym', strtotime($date)) . '}}');
$test = new Test($table);
$list = Test::find($table)->all();
Jan 03, 2020
Jan 02, 2020
Nov 07, 2019
Nov 07, 2019