Yii2.0-advanced-10—数据库操作3(活动记录AR)

Active Record (活动记录,以下简称AR)提供了一个面向对象的接口, 用以访问数据库中的数据。一个 AR 类关联一张数据表, 每个 AR 对象对应表中的一行,对象的属性(即 AR 的特性Attribute)映射到数据行的对应列。 一条活动记录(AR对象)对应数据表的一行,AR对象的属性则映射该行的相应列。 您可以直接以面向对象的方式来操纵数据表中的数据,妈妈再不用担心我需要写原生 SQL 语句啦。

例如,假定 Customer AR 类关联着 customer 表,且该类的 name 属性代表 customer 表的 name 列。 你可以写以下代码来哉customer 表里插入一行新的记录:

用 AR 而不是原生的 SQL 语句去执行数据库查询,可以调用直观方法来实现相同目标。如,调用 yii\db\ActiveRecord::save() 方法将执行插入或更新轮询,将在该 AR 类关联的数据表新建或更新一行数据:

$customer = new Customer();
$customer->name = 'Qiang';
$customer->save();  // 一行新数据插入 customer 表

上面的代码和使用下面的原生 SQL 语句是等效的,但显然前者更直观, 更不易出错,并且面对不同的数据库系统(DBMS, Database Management System)时更不容易产生兼容性问题。

$db->createCommand('INSERT INTO customer (name) VALUES (:name)', [
    ':name' => 'Qiang',
])->execute();

1、声明 AR 类

要想声明一个 AR 类,你需要扩展 yii\db\ActiveRecord 基类, 并实现 tableName 方法,返回与之相关联的的数据表的名称:

namespace app\models;

use yii\db\ActiveRecord;

class Customer extends ActiveRecord
{
    /**
     * @return string 返回该AR类关联的数据表名
     */
    public static function tableName()
    {
        return 'customer';
    }
}

2、查询数据

AR 提供了两种方法来构建 DB 查询并向 AR 实例里填充数据:

  • yii\db\ActiveRecord::find()
  • yii\db\ActiveRecord::findBySql()

以上两个方法都会返回 yii\db\ActiveQuery 实例,该类继承自yii\db\Query, 因此,他们都支持同一套灵活且强大的 DB 查询方法,如where()join()orderBy(),等等。 下面的这些案例展示了一些可能的玩法:

// 取回所有活跃客户(状态为 *active* 的客户)并以他们的 ID 排序:
$customers = Customer::find()
    ->where(['status' => Customer::STATUS_ACTIVE])
    ->orderBy('id')
    ->all();

// 返回ID为1的客户:
$customer = Customer::find()
    ->where(['id' => 1])
    ->one();

// 取回活跃客户的数量:
$count = Customer::find()
    ->where(['status' => Customer::STATUS_ACTIVE])
    ->count();

// 以客户ID索引结果集:
$customers = Customer::find()->indexBy('id')->all();
// $customers 数组以 ID 为索引

// 用原生 SQL 语句检索客户:
$sql = 'SELECT * FROM customer';
$customers = Customer::findBySql($sql)->all();

有两个快捷方法:findOne 和 findAll() 用来返回一个或者一组ActiveRecord实例。前者返回第一个匹配到的实例,后者返回所有。 例如:

// 返回 id 为 1 的客户
$customer = Customer::findOne(1);

// 返回 id 为 1 且状态为 *active* 的客户
$customer = Customer::findOne([
    'id' => 1,
    'status' => Customer::STATUS_ACTIVE,
]);

// 返回id为1、2、3的一组客户
$customers = Customer::findAll([1, 2, 3]);

// 返回所有状态为 "deleted" 的客户
$customer = Customer::findAll([
    'status' => Customer::STATUS_DELETED,
]);

3、以数组形式获取数据

有时候,我们需要处理很大量的数据,这时可能需要用一个数组来存储取到的数据, 从而节省内存。你可以用 asArray() 函数做到这一点:

// 以数组而不是对象形式取回客户信息:
$customers = Customer::find()
    ->asArray()
    ->all();
// $customers 的每个元素都是键值对数组

4、批量获取数据

在 Query Builder(查询构造器) 里,我们已经解释了当需要从数据库中查询大量数据时,你可以用 batch query(批量查询)来限制内存的占用。 你可能也想在 AR 里使用相同的技巧,比如这样……

// 一次提取 10 个客户信息
foreach (Customer::find()->batch(10) as $customers) {
    // $customers 是 10 个或更少的客户对象的数组
}
// 一次提取 10 个客户并一个一个地遍历处理
foreach (Customer::find()->each(10) as $customer) {
    // $customer 是一个 ”Customer“ 对象
}
// 贪婪加载模式的批处理查询
foreach (Customer::find()->with('orders')->each() as $customer) {
}

5、操作数据

AR 提供以下方法插入、更新和删除与 AR 对象关联的那张表中的某一行:

  • yii\db\ActiveRecord::save()
  • yii\db\ActiveRecord::insert()
  • yii\db\ActiveRecord::update()
  • yii\db\ActiveRecord::delete()

AR 同时提供了一下静态方法,可以应用在与某 AR 类所关联的整张表上。 用这些方法的时候千万要小心,因为他们作用于整张表! 比如,deleteAll() 会删除掉表里所有的记录。

  • yii\db\ActiveRecord::updateCounters()
  • yii\db\ActiveRecord::updateAll()
  • yii\db\ActiveRecord::updateAllCounters()
  • yii\db\ActiveRecord::deleteAll()

下面的这些例子里,详细展现了如何使用这些方法:

// 插入新客户的记录
$customer = new Customer();
$customer->name = 'James';
$customer->email = 'james@example.com';
$customer->save();  // 等同于 $customer->insert();

// 更新现有客户记录
$customer = Customer::findOne($id);
$customer->email = 'james@example.com';
$customer->save();  // 等同于 $customer->update();

// 删除已有客户记录
$customer = Customer::findOne($id);
$customer->delete();

// 删除多个年龄大于20,性别为男(Male)的客户记录
Customer::deleteAll('age > :age AND gender = :gender', [':age' => 20, ':gender' => 'M']);

// 所有客户的age(年龄)字段加1:
Customer::updateAllCounters(['age' => 1]);

须知:save() 方法会调用 insert() 和 update() 中的一个, 用哪个取决于当前 AR 对象是不是新对象(在函数内部,他会检查 yii\db\ActiveRecord::isNewRecord 的值)。 若 AR 对象是由 new 操作符 初始化出来的,save() 方法会在表里插入一条数据; 如果一个 AR 是由 find() 方法获取来的, 则 save() 会更新表里的对应行记录。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值