不能否認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關聯來查詢,只要咱們作好模型的相互關聯,查詢是沒有問題的!