update db-active-record.md

翻译 2.0.16 新加的关于 OptimisticLockBehavior 的部分文档
This commit is contained in:
deepziyu
2018-11-18 14:42:37 +08:00
parent a82157bbd3
commit f0fc4fbff8

View File

@ -88,6 +88,7 @@ class Customer extends ActiveRecord
```
### 将 Active Record 称为模型Active records are called "models"
Active Record 实例称为[模型](structure-models.md)。因此, 我们通常将 Active Record 类
放在 `app\models` 命名空间下(或者其他保存模型的命名空间)。
@ -742,11 +743,12 @@ class Customer extends ActiveRecord
1. 在与 Active Record 类相关联的 DB 表中创建一个列,以存储每行的版本号。
这个列应当是长整型(在 MySQL 中是 `BIGINT DEFAULT 0`)。
2. 重写 [[yii\db\ActiveRecord::optimisticLock()]] 方法返回这个列的命名。
3.用于用户填写的 Web 表单中添加一个隐藏字段hidden field来存储正在更新的行的当前版本号
Active Record 类中)版本号这个属性你要自行写进 rules() 方法并自己验证一下。
4.使用 Active Record 更新数据的控制器动作中要捕获try/catch [[yii\db\StaleObjectException]] 异常
3.你的 Model 类里实现 [[\yii\behaviors\OptimisticLockBehavior|OptimisticLockBehavior]] 行为(注:这个行为类在 2.0.16 版本加入),以便从请求参数里自动解析这个列的值
然后从验证规则中删除 version 属性,因为 [[\yii\behaviors\OptimisticLockBehavior|OptimisticLockBehavior]] 已经处理它了.
4.用于用户填写的 Web 表单中添加一个隐藏字段hidden field来存储正在更新的行的当前版本号
5. 在使用 Active Record 更新数据的控制器动作中要捕获try/catch [[yii\db\StaleObjectException]] 异常。
实现一些业务逻辑来解决冲突(例如合并更改,提示陈旧的数据等等)。
 
例如,假定版本列被命名为 `version`。您可以使用下面的代码来实现乐观锁。
@ -779,7 +781,23 @@ public function actionUpdate($id)
// 解决冲突的代码
}
}
// ------ Model 代码 -------
use yii\behaviors\OptimisticLockBehavior;
public function behaviors()
{
return [
OptimisticLockBehavior::className(),
];
}
```
> Note因为 [[\yii\behaviors\OptimisticLockBehavior|OptimisticLockBehavior]] 仅仅在保存记录的时候被确认,
> 如果用户提交的有效版本号被直接解析 [[\yii\web\Request::getBodyParam()|getBodyParam()]]
> 那么你的 Model 将扩展成这样:触发在步骤 3 中子类的行为,与此同时,调用步骤 2 中的父类的定义,
> 这样你在把 Model 绑定到负责接收用户输入的控制器的同时,有一个专门用于内部逻辑处理的实例,
> 或者,您可以通过配置其 [[\yii\behaviors\OptimisticLockBehavior::$value|value]] 的属性来实现自己的逻辑。(注:这一堆都是在解释 Behaviors 的原理)
## 使用关联数据Working with Relational Data <span id="relational-data"></span>
@ -1181,7 +1199,9 @@ $customers = Customer::find()
调用 [[yii\db\ActiveQuery::joinWith()|joinWith()]] 方法会默认 [即时加载](#lazy-eager-loading) 相应的关联数据。
如果你不需要那些关联数据,你可以指定它的第二个参数 `$eagerLoading``false`
> Note: 即使在启用即时加载的情况下使用 [[yii\db\ActiveQuery::joinWith()|joinWith()]] 或 [[yii\db\ActiveQuery::innerJoinWith()|innerJoinWith()]]相应的关联数据也**不会**从这个 `JOIN` 查询的结果中填充。 因此,每个连接关系还有一个额外的查询,正如[即时加载](#lazy-eager-loading)部分所述。
> Note: 即使在启用即时加载的情况下使用 [[yii\db\ActiveQuery::joinWith()|joinWith()]] 或 [[yii\db\ActiveQuery::innerJoinWith()|innerJoinWith()]]
相应的关联数据也**不会**从这个 `JOIN` 查询的结果中填充。
因此,每个连接关系还有一个额外的查询,正如[即时加载](#lazy-eager-loading)部分所述。
和 [[yii\db\ActiveQuery::with()|with()]] 一样,你可以 join 多个关联表;你可以动态的自定义
你的关联查询;你可以使用嵌套关联进行 join。你也可以将 [[yii\db\ActiveQuery::with()|with()]]
@ -1493,7 +1513,8 @@ class CommentQuery extends ActiveQuery
```
> Note: 作为 [[yii\db\ActiveQuery::onCondition()|onCondition()]] 方法的替代方案,你应当
调用 [[yii\db\ActiveQuery::andOnCondition()|andOnCondition()]] 或 [[yii\db\ActiveQuery::orOnCondition()|orOnCondition()]] 方法来附加新增的条件,不然在一个新定义的查询方法,已存在的条件可能会被覆盖。
调用 [[yii\db\ActiveQuery::andOnCondition()|andOnCondition()]] 或 [[yii\db\ActiveQuery::orOnCondition()|orOnCondition()]] 方法来附加新增的条件,
不然在一个新定义的查询方法,已存在的条件可能会被覆盖。
然后你就可以先下面这样构建你的查询了: