Yii2 优雅的 Active Record

548 查看

这篇文章我们来看看在 Yii2 之中的 Active Record,为啥要将 Active Record 单独出来说呢?因为个人认为这是 Yii(不管是 Yii1.1 还是 Yii2)最强大的一部分功能之一,何况又遇上在 Yii2 中其实对 Active Record的改进还是比较多的,所以我们就通过这篇文章来瞅瞅 Yii2 的 Active Record 新特性。

1.支持更多的数据库

Yii2的Active Record首先值得称道的一点就是它已经可以支持更多的数据库,包括一些NoSQL类型的数据库如MongoDB,还有一些流行的存储后端如: elasticsearch, redis, Sphinx search也得到很好的支持,现在真是随意你怎么玩数据了。因为我们在想换一个存储后端的时候可以轻松地在配置文件里切换过来,完全不用去修改Active Record的代码,酷毙!

2.在Yii2中使用Active Record查询数据

在Yii2中使用Active Record的时候,第一个最直观的感受可能就是model()调用已经跟Yii1.1变得不同了,可以说所有的查询函数都源自 find()findBySql()这两个函数,所以像在Yii1.1中的Post::model()->findAll()等函数就没有了。这里对Active Record的查询模块介绍都是很简单的,当然也可能包含一些个人的主观因素在里面,不说废话,如果你能看看下面这些来自官方文档中Active Record介绍的代码片段你就会变得很清晰。

<?php
    // 检索出所有的customer然后根据id排序:
    $customers = Customer::find()
    ->where(['status' => Customer::STATUS_ACTIVE])
    ->orderBy('id')
    ->all();

    // 查找出id为1的customer(注意时一个):
    $customer = Customer::find()
        ->where(['id' => 1])
        ->one();

    // 返回 *active* customers的数量:
    $count = Customer::find()
        ->where(['status' => Customer::STATUS_ACTIVE])
        ->count();

    // 找到所有将id作为索引的customer:
    $customers = Customer::find()->indexBy('id')->all();
    // $customers array is indexed by customer IDs

    // 用查询语句查找所有的customer:
        $sql = 'SELECT * FROM customer';
        $customers = Customer::findBySql($sql)->all();

还有一个值得注意的地方是,在Yii1.1中使用的findByPk()find()在Yii2中有了新的替代者,

<?php
    // 查找一个id为1的customer:
    $customer = Customer::findOne(1);

    // 找到id为1的 *active* customer:
    $customer = Customer::findOne([
    'id' => 1,
    'status' => Customer::STATUS_ACTIVE,
    ]);

    // 查找出id为1,或2,或3的所有customer:
    $customers = Customer::findAll([1, 2, 3]);

    // 找到状态为 "deleted" 的customer:
    $customer = Customer::findAll([
    'status' => Customer::STATUS_DELETED,
    ]);

3.关联(Relations)

在Yii2中,不再存在relations()函数,而是使用getters的方式返回一个ActiveQuery对象

class Post extends yii/db/ActiveRecord{

   public function getComments()
   {
      return $this->hasMany('Comment', array('post_id' => 'id'));
   }
}

但是关联性还是可以使用类似$game->players,不过在Yii2你可以根据自己的情况来自定义你的查询环境(查询语句),比如:

$comments = $post->getComments()->andWhere('approve=1')->all();

高级特性:

但目前为止如果你觉Active Record还是没法说服觉得它很强大,那么你可以好好看看这里。我会在这里罗列一些在Yii2中Active Record的(我觉得还不错的)细微的小改进,不过也是很贴心,因为在开发过程中,你可能更喜欢将查询到的数据存到一个数组里,这样不仅会方便我们在Views中的输出,也在一定程度上节约了内存,于是,我在这里推荐你调用asArray()这个函数

$posts = Post::find()->asArray()->all();

说到内存,上面的函数还是不能满足你的需求?全部查出来还是太大了?你想限制一下内存?OK,在Yii2中,你可以使用batch()函数来限制你的查询请求;PS:batch就是批量的意思

// 一次查询10个
foreach (Post::find()->batch(10) as $posts) {
    // $posts 是一个包含10个(有可能更少)Post对象的数组
}

// 查询10个的同时一个一个输出
foreach (Post::find()->each(10) as $post) {
    // $post 是一个Post对象
}

// 跟with一起使用
foreach (Post::find()->with('comments')->each() as $post) {
}

另外,Yii2中已经自动支持数据库中的事务管理(transactions),所以你完全不用担心在使用数据查询,更新的时候是否开启了事务管理,Yii2已经帮你做好了这一切。

写在最后:

这些就是我在学习Yii2中总结的一些有关Active Record的改进,不得不说,Yii2的这些改进使得我们的开发更友好,更优雅了,仅是Active Record,就可以让人用的很爽,所以,上手Yii2吧

原文来自:http://www.jellybool.com/post/yii2-active-record