yii2之ActiveRecord 模型
Posted niuben
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了yii2之ActiveRecord 模型相关的知识,希望对你有一定的参考价值。
??????Active Record 模型是一种设计模式,用面向对象的方式抽象地访问数据的模式。在 Yii2 中,每一个 Active Record 模型对象的实例是 yii\db\ActiveRecord 类或它的子类,它封装了数据库表或视图中的一行记录,并封装了所有逻辑和访问数据库的细节,如果有大部分的业务逻辑,很适合使用这种模式。
1. ActiveRecord 模型概述
?????? 在大多数企业级开发中,都需要用到面向对象方法和关系型数据库。在软件的业务逻辑层和用户界面层,都需要操作对象,而在操作对象后,需要把对象的信息存储至数据库中。因此,在 MVC 模式下开放一个应用程序时,程序员要写很多数据访问层的代码,用来执行增删改查。通常情况下,这些数据访问层的代码基本上都是先传入操作对象,然后设置存储过程,再设置对象与属性对应,最后执行存储过程。这些具有相同模式的代码,在每个软件项目都重复出现,这显然是一种资源的浪费,由此,可以使用 ActiveRecord 模型解决这些问题。
?????? ActiveRecord (AR)模型是一种流行的对象——关系映射技术。对象——关系映射(Object Relational Mapping,ORM)是一种为解决面向对象与关系型数据库存在的互不匹配现象的技术。ORM 在关系型数据库和对象之间产生一个自动映射,这样在具体的数据库操作中就不需要再与复杂的 SQL 语句打交道。软件设计人员只需要关注业务逻辑中的对象架构,而不是底层重复性的数据库 SQL 语句。
下面是一个 user 表的模型类
<?php
namespace common\models;
use Yii;
use yii\db\ActiveRecord;
use yii\web\IdentityInterface;
/**
* User model
*
* @property integer $id
* @property string $username
* @property string $password_hash
* @property string $password_reset_token
* @property string $email
* @property string $auth_key
* @property integer $status
* @property integer $created_at
* @property integer $updated_at
* @property string $password write-only password
*/
class User extends ActiveRecord implements IdentityInterface
/**
* @inheritdoc
*/
public static function tableName()
return '%user';
/**
* @inheritdoc
*/
public function behaviors()
return [
TimestampBehavior::className(),
];
/**
* @inheritdoc
*/
public function rules()
return [
['status', 'default', 'value' => self::STATUS_ACTIVE],
['status', 'in', 'range' => [self::STATUS_ACTIVE, self::STATUS_DELETED]],
];
演示下 AR 的新增操作吧
$user = new User(); // 实例化 user 表对应的 ActiveRecord 模型类
$user->username = '小牛'; // 给表中的 username 字段赋值
$user->email = '[email protected]'; // 给表中的 email 字段赋值
$user->save(); // 执行 insert into 语句完成一次插入记录的操作
上面的代码相当于执行了下面的 SQL 语句。
insert into user('username','email') value('小牛','[email protected]');
ActiveRecord 的优点是简单、直观,一个类就包括了数据访问和业务逻辑。减少了软件开发时间和成本,极大的提高了数据的可读性,也简化了代码的调优和测试。
2. 通过查询操作理解 ActiveRecord 类
静态方法 find() 返回了 ActiveRecord 类的静态实例对象,从而可以调用其他的方法,查询实例。
我们打印了一个 one() 方法查询返回的信息,如下:
api\models\UserRole Object
(
[_attributes:yii\db\BaseActiveRecord:private] => Array
(
[role_id] => 1
[role_name] => 超级管理员
[role_desc] => 超级管理员
[role_sort] => 10
[created_at] => 2019-06-17 15:10:21
[delete_flg] => 0
[updated_uid] => 1
[updated_at] => 2019-06-19 18:12:40
)
[_oldAttributes:yii\db\BaseActiveRecord:private] => Array
(
[role_id] => 1
[role_name] => 超级管理员
[role_desc] => 超级管理员
[role_sort] => 10
[created_at] => 2019-06-17 15:10:21
[delete_flg] => 0
[updated_uid] => 1
[updated_at] => 2019-06-19 18:12:40
)
[_related:yii\db\BaseActiveRecord:private] => Array
(
)
[_relationsDependencies:yii\db\BaseActiveRecord:private] => Array
(
)
[_errors:yii\base\Model:private] =>
[_validators:yii\base\Model:private] =>
[_scenario:yii\base\Model:private] => default
[_events:yii\base\Component:private] => Array
(
)
[_eventWildcards:yii\base\Component:private] => Array
(
)
[_behaviors:yii\base\Component:private] => Array
(
)
)
one()方法找到了一个满足查询条件的行,返回一个实例对象,实例的属性含有数据表行中相应列的值。然后,就可以像读取普通对象的属性那样读取查询结构
$role->role_name; // 输出 “超级管理员”
如果是传统的面向对象语言,如 C++ 或 Java,这里就会报编译错误,因为类没有定义“role_name”成员属性。而对于 PHP 而言,语言有着对动态特性(魔术方法)的支持,当写入【读取】对象属性不存在时,会触发 ActiveRecord 中定义的 __set()【__get()】 方法,这样的调用就没有任何问题。
3. 通过插入和更新操作理解 ActiveRecord 类
同样使用 save() 方法执行插入和更新操作。如果实例对象是 new 操作符创建的,调用 save() 方法会新增一条数据,而实例对象是 find() 方法的结果,那么调用 save() 将更新表中现有的行。
查看在 vendor\yiisoft\yii2\db\BaseActiveRecord.php 文件中的代码
/*
* 保存当前的记录
* 插入记录到数据表的一行,如果它的 isNewRecord 属性为 true(通常情况下使用 new 运算符来创建记录),
* 否则,将被用于更新表中的相应行(通常情况下使用 find 方法查找记录
*/
public function save($runValidation = true, $attributeNames = null)
if ($this->getIsNewRecord())
return $this->insert($runValidation, $attributeNames);
return $this->update($runValidation, $attributeNames) !== false;
如上代码所示,通过判断 $this->getIsNewRecord() 方法的返回值,判断执行不同的操作。
以上是关于yii2之ActiveRecord 模型的主要内容,如果未能解决你的问题,请参考以下文章