Yii2学习之ActiveRecord

简单介绍

AR类是yii2中常用的数据库操作类(还有一种DAO模式,基于sql语句查询),是一种对象化的数据库操作模式,每一个AR类关联着一张数据表,每个AR对象对应着数据表中的一行,对象的每个属性对应着该行的相应列,这样就可以以面向对象的方式操作数据表的数据,而不用写sql语句了。

AR类生命周期

初始化

constructor  
init(): will trigger an EVENT_INIT event

save调用时

beforeValidate(): //return bool  
afterValidate(): will trigger an EVENT_AFTER_VALIDATE event  
beforeSave(): will trigger an EVENT_BEFORE_INSERT or EVENT_BEFORE_UPDATE event  
perform the actual data insertion or updating  
afterSave(): will trigger an EVENT_AFTER_INSERT or EVENT_AFTER_UPDATE event

delete调用时

beforeDelete(): will trigger an EVENT_BEFORE_DELETE event  
perform the actual data deletion  
afterDelete(): will trigger an EVENT_AFTER_DELETE event

常用操作

更改不同数据表
如果你的yii2工程用到了1个以上数据库,在相应的应用目录中配置多个的数据库,然后在相应的基于AR类的数据表中重写的getDb覆盖父类的方法,以达到更换不同的数据表。

return [
    'components' => [
        'db' => [
            'class' => 'yii\db\Connection',
            'dsn' => 'mysql:host=localhost;dbname=testdb1',
            'username' => 'demo1',
            'password' => 'demo1',
        ],
        'db2' => [
            'class' => 'yii\db\Connection',
            'dsn' => 'mysql:host=localhost;dbname=testdb2',
            'username' => 'demo2',
            'password' => 'demo2',
        ],
    ],
];
class OcButlerTask extends \yii\db\ActiveRecord
{
    //...
    public static function getDb()
    {
        return \Yii::$app->db2;  // 使用名为 "db2" 的应用组件
    }
}

数据常用操作

数据表创建保存:

public function actionCreate()
{
    $model = new OcButlerTask();
    if ($model->load(Yii::$app->request->post()) && $model->save()) {
       return $this->redirect(['view', 'id' => $model->id]);
    } else {
       return $this->render('create', [
         'model' => $model,
       ]);
    }
}

Model类的load函数通过请求的参数,将post请求的key=>value赋值给创建的OcButlerTask类的属性。因AR类也是基于Model类的,在Model类的setAttributes函数中将post参数相应的值传递给OcButlerTask的属性。

通过BaseActiveRecord类的save函数,将数据保存在数据表中,通过_oldAttributes属性是否为空判断保存的数据是新创建的还是需要更改的数据。save时会根据你的ar类定义的rules规则去检测相应数据的格式是否正确,若都满足则save返回true表示数据保存成功,false保存失败。保存失败可通过VarDumper::dumpAsString捕捉失败异常。

public function save($runValidation = true, $attributeNames = null)
{
    if ($this->getIsNewRecord()) {
        return $this->insert($runValidation, $attributeNames);
    } else {
        return $this->update($runValidation, $attributeNames) !== false;
    }
}
if (!$model->save()) {
   throw new \Exception("失败原因:\n".VarDumper::dumpAsString($model->getErrors()), 500);
}

常用的查询操作:

//查询id为指定的$task_id的OcButlerTask类
/** @var OcButlerTask $task */
$task = OcButlerTask::find()
    ->where(['id' => $task_id])
    ->one();

//查询所有已完成的任务,并以id排序
$tasks = OcButlerTask::find()
    ->where(['status' => OcButlerTask::BUTLER_TASK_COMPLETE])
    ->orderBy('id')
    ->all();

//返回所有已完成任务的数量
$task_count = OcButlerTask::find()
    ->where(['status' => OcButlerTask::BUTLER_TASK_COMPLETE])
    ->count();

//以sql语句查询,返回所有的任务
$tasks = OcButlerTask::findBySql("select * from oc_butler_task")
    ->all();

//查询id为指定的$task_id的OcButlerTask类,以数组方式返回。
$task = OcButlerTask::find()
    ->where(['id' => $task_id])
    ->asArray()
    ->one();

//快捷方法,返回id为1的任务。
$task = OcButlerTask::findOne(1);

//快捷方法,返回所有状态已完成的任务
$tasks = OcButlerTask::findAll([
    'status' => OcButlerTask::BUTLER_TASK_COMPLETE,
]);

//批量操作,用于数据量大时,返回所有数据需要分配的内存太大等问题
// 一次提取10个任务
foreach (OcButlerTask::find()->batch(10) as $tasks) {
    // $tasks是10个或更少的客户对象的数组
}
// 一次提取10个客户并一个一个地遍历处理
foreach (OcButlerTask::find()->each(10) as $task) {
    // $task是一个‘OcButlerTask’对象
}
// 贪婪加载模式的批处理查询
foreach (OcButlerTask::find()->with('orders')->each() as $task) {
}

数据的更改删除:

//数据更改保存
$task= OcButlerTask::findOne($id);
$task->status = OcButlerTask::BUTLER_TASK_ASSIGN;
$task->save(); 

// 数据删除
$task= OcButlerTask::findOne($id);
$task->delete();

// 删除所有成功的管家任务
Customer::deleteAll('status = :status', [':status' => OcButlerTask::BUTLER_TASK_COMPLETE]);

关联查询
我们在使用migrate创建数据表时,对与创建表使用FOREIGN KEY外联另一张表的id时,经常在使用gii生成相应的model类时会发现,对于外联的表的键会生成相应的关联查询方法。

$this->execute("
    CREATE TABLE IF NOT EXISTS {{oc_butler_task}}
     (
       [[id]] INT NOT NULL AUTO_INCREMENT,
       [[butler_id]] INT ,
       [[user_name]] VARCHAR(32) ,
       [[tel_num]] VARCHAR(20),
       [[create_at]] TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ,
       [[update_at]] TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
       [[status]] INT NOT NULL DEFAULT 0,

       PRIMARY KEY ([[id]]),
       FOREIGN KEY ([[butler_id]]) REFERENCES {{oc_butler}}([[id]]),
     )DEFAULT CHARSET=utf8;
");

对应OcButlerTask类中的关联方法

public function getButler()
{
    return $this->hasOne(OcButler::className(), ['id' => 'butler_id']);
}

以上使用了AR类中的hasOne()方法,该表时关联数据一对一的关系模型,一个管家任务对应着一个管家负责。hasOne返回的是一个ActiveQuery对象,通过ActiveQuery类的one方法找到对应的OcButler类(对应的管家AR类)
$task->getButler()->one() //获取到对应管家id的Butler类,就可以操作对应的Butler表了。

其它的关联操作还有很多,有需要的可以查找相应的API方法。参考API

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值