不能否认Cakephp对于查询的封装是有限制的,可是经过利用Cakephp的语法规则,能够很好的弥补这一点。php
咱们在应用中遇到的问题:app
{查询Note的ID小于10的全部User,User表和Note表是一对多关联}函数
咱们一般的作法是post
1.
$users
=
$this
->User->find(
'all'
,
array
(
2.
'conditions'
=>
array
(
3.
'Note.id <'
=> 10
4.
)
5.
));
注意:这种作法是错误的。this
缘由是:spa
Cakephp对于hasMany的关联,会生成下列的语句debug
1.
SELECT
`
User
`.`id`, `
User
`.`
name
`, `
User
`.`username`, `
User
`.`
password
`, `
User
`.`created`
FROM
`users`
AS
`
User
`
WHERE
`Note`.`id` < 10
能够看到,Note表并无被Join到查询中,因此,MySql会提示code
1.
Unknown
column
'Note.id'
in
'where clause'
咱们应该怎样查询条件从属于关联表的记录呢?ci
简单介绍一下Cakephp的四种关联模式对应的从属关联条件的方法。unicode
1. 最简单的hasOne和belongsTo关联
这类的关联咱们能够直接写关联表的条件,而不会出现Unknow column的错误。
2. 稍稍复杂的hasMany关联(一对多关联)
就像你在上面看见的,hasMany关联是不能直接实现上述的查询条件的,可是咱们能够变通一下,咱们能够把hasMany关联查询转换为belongsTo关联查询,按照上面的条件,咱们再试一试
01.
$users
=
$this
->User->Note->find(
'all'
,
array
(
02.
'conditions'
=>
array
(
03.
'Note.id <'
=> 10
04.
),
05.
'contain'
=>
array
(
'User'
),
06.
'fields'
=>
array
(
07.
'Note.id'
,
08.
'User.id'
,
09.
'User.name'
10.
)
11.
));
此次获得的结果相似于下面的数据
01.
Array
02.
(
03.
[0] => Array
04.
(
05.
[Note] => Array
06.
(
07.
[id] => 1
08.
)
09.
[User] => Array
10.
(
11.
[id] => 54
12.
[name] => Cole Cox
13.
)
14.
)
15.
[1] => Array
16.
(
17.
[Note] => Array
18.
(
19.
[id] => 2
20.
)
21.
[User] => Array
22.
(
23.
[id] => 81
24.
[name] => Vincent Cobb
25.
)
26.
)
27.
)
OK,这就是咱们想要的!
一样的方法还能够{查找一个User的全部Friend},请看下面的部分。。。
3. 不太好理解的hasAndBelongsToMany关联(多对多关联)
咱们的数据表结构以下
01.
--用户表
02.
03.
CREATE
TABLE
IF
NOT
EXISTS `users` (
04.
`id`
int
(11)
NOT
NULL
auto_increment,
05.
`
name
`
varchar
(60)
collate
utf8_unicode_ci
NOT
NULL
,
06.
`username`
varchar
(20)
collate
utf8_unicode_ci
NOT
NULL
,
07.
`
password
`
varchar
(255)
collate
utf8_unicode_ci
NOT
NULL
,
08.
`created` datetime
NOT
NULL
,
09.
PRIMARY
KEY
(`id`)
10.
) ENGINE=MyISAM;
11.
12.
--用户和好友关联表
13.
14.
CREATE
TABLE
IF
NOT
EXISTS `friends_users` (
15.
`id`
bigint
(10)
NOT
NULL
auto_increment,
16.
`user_id`
bigint
(10)
NOT
NULL
,
17.
`friend_id`
bigint
(10)
NOT
NULL
,
18.
PRIMARY
KEY
(`id`)
19.
) ENGINE=MyISAM;
咱们须要创建三个模型类
User模型,对应于users表,文件/app/models/user.php
1.
class
User
extends
AppModel{
2.
var
$name
=
'User'
;
3.
4.
var
$hasAndBelongsToMany
=
array
(
5.
'Friend'
=>
array
(
'with'
=>
'FriendsUser'
)
6.
);
7.
8.
}
Friend模型,也对应users表(Friend和User共享数据),用来和users模型进行多对多关联
文件/app/models/friend.php
1.
class
Friend
extends
AppModel {
2.
var
$name
=
'Friend'
;
3.
var
$useTable
=
'users'
;
4.
var
$hasAndBelongsTo
=
array
(
5.
'User'
=>
array
(
'with'
=>
'FriendsUser'
)
6.
);
7.
}
FriendsUser模型,对应关联表friends_users,文件/app/models/friends_user.php
1.
class
FriendsUser
extends
AppModel {
2.
var
$name
=
'FriendsUser'
;
3.
var
$belongsTo
=
array
(
'Friend'
,
'User'
);
4.
}
好了,定义好模型,咱们要查询User的全部Friend,在控制器中,要这样
01.
class
UsersController
extends
AppController {
02.
var
$name
=
'Users'
;
03.
04.
//这里,咱们要引入这三个模型,若是你有更多的模型,能够一块儿引入
05.
var
$uses
=
array
(
'User'
,
'Friend'
,
'FriendsUser'
);
06.
07.
function
test(){
08.
$conditions
=
array
(
09.
'User.id'
=> 1
10.
);
11.
$contain
=
array
(
'User'
,
'Friend'
);
12.
$fields
=
array
(
13.
'User.id'
,
14.
'User.name'
,
15.
'Friend.id'
,
16.
'Friend.name'
17.
);
18.
$limit
= 5;
19.
20.
//咱们使用了中间表FriendsUser,来查询,compact函数是cakephp提倡的用法
21.
$data
=
$this
->FriendsUser->find(
'all'
,compact(
22.
'conditions'
,
23.
'contain'
,
24.
'fields'
,
25.
'limit'
26.
));
27.
28.
debug(
$data
);
29.
exit
;
30.
}
31.
}
查询的结果,可能相似下面的数据
01.
Array
02.
(
03.
[0] => Array
04.
(
05.
[User] => Array
06.
(
07.
[id] => 1
08.
[name] => Drake Duran
09.
)
10.
11.
[Friend] => Array
12.
(
13.
[id] => 2
14.
[name] => Dane Knowles
15.
)
16.
17.
)
18.
19.
[1] => Array
20.
(
21.
[User] => Array
22.
(
23.
[id] => 1
24.
[name] => Drake Duran
25.
)
26.
27.
[Friend] => Array
28.
(
29.
[id] => 3
30.
[name] => Felix Kelley
31.
)
32.
33.
)
34.
35.
)
能够看到,这正是咱们须要的数据。
总结一下
Cakephp关联表的从表查询,能够借助belongsTo关联来查询,只要咱们作好模型的相互关联,查询是没有问题的!