Skip to content

Commit add25a0

Browse files
committed
Merge branch 'zh' of https://github.com/mafeifan/docs into zh
2 parents ea861dc + 8c46a4b commit add25a0

File tree

2 files changed

+233
-0
lines changed

2 files changed

+233
-0
lines changed

zh/models/deleting-data.rst

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
删除数据
2+
########
3+
4+
CakePHP的模型类提供了多种从数据库中删除记录的方法。
5+
6+
.. _model-delete:
7+
8+
delete方法
9+
======
10+
11+
``delete(int $id = null, boolean $cascade = true);``
12+
13+
删除指定$id的记录。默认情况下,会级联删除依赖于该记录的所有记录。
14+
15+
例如,当删除一个User,User关联了许多条Recipe记录(使用 'hasMany' 或'hasAndBelongsToMany' 来关联Recipes)。
16+
17+
- 如果$cascade设置为true,并且被关联的模型中dependent属性值为true,删除User的同时会删除关联的Recipe记录。
18+
- 如果$cascade设置为false,删除User不会删除关联的Recipe记录。
19+
20+
如果你使用的数据库支持外键和级联删除,会比CakePHP自带的级联删除效率更高。
21+
使用模型中的 ``Model::delete()`` 方法好处之一是支持使用行为及回调方法::
22+
23+
$this->Comment->delete($this->request->data('Comment.id'));
24+
25+
在处理删除操作中,可以在自定义业务逻辑使用 ``beforeDelete`` 和 ``afterDelete`` 回调方法。
26+
这些方法位于模型和行为中。更多信息参见
27+
:doc:`/models/callback-methods`。
28+
29+
.. _model-deleteall:
30+
31+
deleteAll
32+
=========
33+
34+
``deleteAll(mixed $conditions, $cascade = true, $callbacks = false)``
35+
36+
``deleteAll()`` 与 ``delete()`` 类似,将删除匹配条件的所有记录。
37+
``$conditions`` 作为条件可以是SQL语句片段或数组形式。
38+
39+
* **conditions** 匹配的条件
40+
* **cascade** 布尔型,设置true,会导致级联删除
41+
* **callbacks** 布尔型, 执行回调函数
42+
43+
执行成功返回true,失败返回false。
44+
45+
Example::
46+
47+
// 与 find() 方法类似,删除满足条件的记录
48+
$this->Comment->deleteAll(array('Comment.spam' => true), false);
49+
50+
如果通过回调方法和(或)级联方式删除记录,这往往会导致更多的查询。在deleteAll() 中匹配的记录被删除前,关联会重置。如果是使用bindModel()或unbindModel()来改变关联,应该设置 **reset** 为 ``false``。
51+
52+
.. note::
53+
54+
如果删除条件执行正确但没有找到匹配的记录,造成没有任何记录被删除,deleteAll() 也将返回true。
55+
56+
.. meta::
57+
:title lang=zh_CN: Deleting Data
58+
:keywords lang=zh_CN: doc models,custom logic,callback methods,model class,database model,callbacks,information model,request data,deleteall,fragment,leverage,array,cakephp,failure,recipes,benefit,delete,data model

zh/models/virtual-fields.rst

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
虚字段
2+
######
3+
4+
虚字段可以将任意的SQL表达式当作模型中的字段来使用,这些字段不能保存数据,但是像其他字段一样可以进行读操作。和其他字段一样。作为model的键名使用,
5+
6+
7+
创建虚字段
8+
==========
9+
10+
创建虚拟字段很简单。在每个模型中可以设置 ``$virtualFields`` 属性,该属性是一个数组,
11+
形式如 字段名 => 表达式。下面是一个使用MySQL定义虚字段的例子::
12+
13+
public $virtualFields = array(
14+
'name' => 'CONCAT(User.first_name, " ", User.last_name)'
15+
);
16+
17+
PostgreSQL中的写法::
18+
19+
public $virtualFields = array(
20+
'name' => 'User.first_name || \' \' || User.last_name'
21+
);
22+
23+
在随后的查找操作中,User的查询结果中会一个多出键名为 ``name`` 键值为连接内容的字段。虚字段不要与数据库中已存在的字段名相同。否则会导致错误。
24+
25+
有时可以不带 **User.first\_name**,如果不遵循规范,(比如和其他表有多个关联)可能会出现错误。这种情况下,应该不带模型名,最好使用 ``first_name || \' \' || last_name``。
26+
27+
使用虚字段
28+
==========
29+
30+
操作虚拟字段有多种方法。
31+
32+
Model::hasField()
33+
-----------------
34+
35+
如果模型中存在第一个参数指定的实际存在的字段,将返回true。
36+
将第二个参数 `hasField()` 设为true,虚拟字段也会被检查。使用上面的代码来举例::
37+
38+
$this->User->hasField('name'); // 返回false,因为不存在名为name的实际字段
39+
$this->User->hasField('name', true); // 放回true,因为存在名为name的虚字段
40+
41+
Model::isVirtualField()
42+
-----------------------
43+
44+
检测一个字段/列是虚字段还是实际字段。如果是虚拟字段将返回true::
45+
46+
$this->User->isVirtualField('name'); //true
47+
$this->User->isVirtualField('first_name'); //false
48+
49+
Model::getVirtualField()
50+
------------------------
51+
52+
该方法用来取得虚字段对应的SQL表达式,如果没有参数,会返回该模型所有的虚字段::
53+
54+
//将返回 'CONCAT(User.first_name, ' ', User.last_name)'
55+
$this->User->getVirtualField('name');
56+
57+
模型的find()方法和虚字段
58+
--------------------------------
59+
60+
如前所述,``Model::find()`` 像处理其他字段一样处理虚字段。虚字段的值会包括在模型的结果中::
61+
62+
$results = $this->User->find('first');
63+
64+
// 输出的结果
65+
array(
66+
'User' => array(
67+
'first_name' => 'Mark',
68+
'last_name' => 'Story',
69+
'name' => 'Mark Story',
70+
//更多的字段...
71+
)
72+
);
73+
74+
分页和虚字段
75+
------------
76+
77+
由于查询时虚字段与一般字段的行为一样,所以也可以用 ``Controller::paginate()`` 来排序。
78+
79+
虚字段和模型别名(model aliases)
80+
================================
81+
82+
当你使用虚字段和带别名的模型,可能会遇到虚字段的模型不会更新映射到新的模型别名中去。
83+
如果使用的虚字段所在的模型中有多个别名,最好在模型的构造函数中来定义虚字段::
84+
85+
public function __construct($id = false, $table = null, $ds = null) {
86+
parent::__construct($id, $table, $ds);
87+
$this->virtualFields['name'] = sprintf(
88+
'CONCAT(%s.first_name, " ", %s.last_name)', $this->alias, $this->alias
89+
);
90+
}
91+
92+
这将使虚字段在给定模型的所有别名中都有效。
93+
94+
SQL查询中的虚字段
95+
=================
96+
97+
使用query函数直接进行SQL查询,其返回的数据并不和模型的数据一样。比如::
98+
99+
$this->Timelog->query(
100+
"SELECT
101+
project_id, SUM(id) as TotalHours
102+
FROM
103+
timelogs
104+
AS
105+
Timelog
106+
GROUP BY
107+
project_id;"
108+
);
109+
110+
返回如下格式的数据::
111+
112+
Array
113+
(
114+
[0] => Array
115+
(
116+
[Timelog] => Array
117+
(
118+
[project_id] => 1234
119+
)
120+
[0] => Array
121+
(
122+
[TotalHours] => 25.5
123+
)
124+
)
125+
)
126+
127+
如果想把TotalHours放到Timelog数组中,我们需要为合计列指定一个虚拟字段。
128+
我们可以临时定义虚拟字段比定义在模型中更有效果。我们设定默认值为 ``0``,免得其他查询使用这个虚拟字段。
129+
如果那样,TotalHours列会返回 ``0`` ::
130+
131+
$this->Timelog->virtualFields['TotalHours'] = 0;
132+
133+
除了增加虚拟字段,我们还需要用 ``MyModel__MyField`` 的形式给列起别名。比如::
134+
135+
$this->Timelog->query(
136+
"SELECT
137+
project_id, SUM(id) as Timelog__TotalHours
138+
FROM
139+
timelogs
140+
AS
141+
Timelog
142+
GROUP BY
143+
project_id;"
144+
);
145+
146+
在指定虚拟字段后再次查询,将会得到一个格式化好的的结果::
147+
148+
Array
149+
(
150+
[0] => Array
151+
(
152+
[Timelog] => Array
153+
(
154+
[project_id] => 1234
155+
[TotalHours] => 25.5
156+
)
157+
)
158+
)
159+
160+
虚字段的局限
161+
============
162+
163+
使用虚字段会带来一些局限。首先,不能在模型关联的条件(conditions),排序(order),字段(fields)数组中使用虚拟字段。如果那样做会产生SQL错误。因为字段被没有被ORM替代。很难去估算模型关联的深度。
164+
165+
常见的解决办法是在运行时将 ``virtualFields`` 复制到其他模型::
166+
167+
$this->virtualFields['name'] = $this->Author->virtualFields['name'];
168+
169+
或::
170+
171+
$this->virtualFields += $this->Author->virtualFields;
172+
173+
.. meta::
174+
:title lang=zh_CN: Virtual fields
175+
:keywords lang=zh_CN: sql expressions,array name,model fields,sql errors,virtual field,concatenation,model name,first name last name

0 commit comments

Comments
 (0)