• Main navigation
登入區塊
帳號:

密碼:

記住我



忘記密碼?

現在註冊!
網站資訊區塊
站務管理者

kiang
 

tokimeki
 

sam0228
 

morris
 

shiang
 

SoltyRain
 

廣告





Cakephp多表关联的从表查询笔记
Just popping in
註冊日期:
2009/5/12 8:55
文章: 10
不可否认Cakephp对于查询的封装是有限制的,但是通过利用Cakephp的语法规则,可以很好的弥补这一点。

我们在应用中遇到的问题:

{查询Note的ID小于10的所有User,User表和Note表是一对多关联}

我们通常的做法是

$users 
$this->User->find('all',array(
    
'conditions' => array(
        
'Note.id <' => 10
    
)
));

注意:这种做法是错误的。

原因是:

Cakephp对于hasMany的关联,会生成下列的语句

SELECT 
`User`.`id`, `User`.`name`, `User`.`username`, `User`.`password`, `User`.`createdFROM `users` AS `UserWHERE `Note`.`id` < 10

可以看到,Note表并没有被Join到查询中,所以,MySql会提示

Unknown column 
'Note.id' in 'where clause'

我们应该怎样查询条件从属于关联表的记录呢?

简单介绍一下Cakephp的四种关联模式对应的从属关联条件的方法。

1. 最简单的hasOne和belongsTo关联

这类的关联我们可以直接写关联表的条件,而不会出现Unknow column的错误。

2. 稍稍复杂的hasMany关联(一对多关联)

就像你在上面看见的,hasMany关联是不能直接实现上述的查询条件的,但是我们可以变通一下,我们可以把hasMany关联查询转换为belongsTo关联查询,按照上面的条件,我们再试一试

$users 
$this->User->Note->find('all',array(
    
'conditions' => array(
        
'Note.id <' => 10
    
),
    
'contain' => array('User'),
    
'fields' => array(
        
'Note.id',
        
'User.id',
        
'User.name'
    
)
));

这次得到的结果类似于下面的数据

Array
(
    [
0] => Array
        (
            [
Note] => Array
                (
                    [
id] => 1
                
)
            [
User] => Array
                (
                    [
id] => 54
                    
[name] => Cole Cox
                
)
        )
    [
1] => Array
        (
            [
Note] => Array
                (
                    [
id] => 2
                
)
            [
User] => Array
                (
                    [
id] => 81
                    
[name] => Vincent Cobb
                
)
        )
)

OK,这就是我们想要的!

同样的方法还可以{查找一个User的所有Friend},请看下面的部分。。。

3. 不太好理解的hasAndBelongsToMany关联(多对多关联)

我们的数据表结构如下

--用户表

CREATE TABLE 
IF NOT EXISTS `users` (
  `
idint(11NOT NULL auto_increment,
  `
namevarchar(60collate utf8_unicode_ci NOT NULL,
  `
usernamevarchar(20collate utf8_unicode_ci NOT NULL,
  `
passwordvarchar(255collate utf8_unicode_ci NOT NULL,
  `
createddatetime NOT NULL,
  
PRIMARY KEY  (`id`)
ENGINE=MyISAM;

--
用户和好友关联表

CREATE TABLE 
IF NOT EXISTS `friends_users` (
  `
idbigint(10NOT NULL auto_increment,
  `
user_idbigint(10NOT NULL,
  `
friend_idbigint(10NOT NULL,
  
PRIMARY KEY  (`id`)
ENGINE=MyISAM;

我们需要建立三个模型类

User模型,对应于users表,文件/app/models/user.php

class User extends AppModel{
    var 
$name 'User';

    var 
$hasAndBelongsToMany = array(
        
'Friend' => array('with' => 'FriendsUser')
    );

}

Friend模型,也对应users表(Friend和User共享数据),用来和users模型进行多对多关联

文件/app/models/friend.php

class Friend extends AppModel {
    var 
$name 'Friend';
    var 
$useTable 'users';
    var 
$hasAndBelongsTo = array(
        
'User' => array('with' => 'FriendsUser')
    );
}

FriendsUser模型,对应关联表friends_users,文件/app/models/friends_user.php

class FriendsUser extends AppModel {
    var 
$name 'FriendsUser';
    var 
$belongsTo = array('Friend','User');
}

好了,定义好模型,我们要查询User的所有Friend,在控制器中,要这样

class UsersController extends AppController {
    var 
$name 'Users';

    
//这里,我们要引入这三个模型,如果你有更多的模型,可以一起引入
    
var $uses = array('User','Friend','FriendsUser');

    function 
test(){
        
$conditions = array(
            
'User.id' => 1
        
);
        
$contain = array('User','Friend');
        
$fields = array(
            
'User.id',
            
'User.name',
            
'Friend.id',
            
'Friend.name'
        
);
        
$limit 5;

        
//我们使用了中间表FriendsUser,来查询,compact函数是cakephp提倡的用法
        
$data $this->FriendsUser->find('all',compact(
            
'conditions',
            
'contain',
            
'fields',
            
'limit'
        
));

        
debug($data);
        exit;
    }
}

查询的结果,可能类似下面的数据

Array
(
    [
0] => Array
        (
            [
User] => Array
                (
                    [
id] => 1
                    
[name] => Drake Duran
                
)

            [
Friend] => Array
                (
                    [
id] => 2
                    
[name] => Dane Knowles
                
)

        )

    [
1] => Array
        (
            [
User] => Array
                (
                    [
id] => 1
                    
[name] => Drake Duran
                
)

            [
Friend] => Array
                (
                    [
id] => 3
                    
[name] => Felix Kelley
                
)

        )

)

可以看到,这正是我们需要的数据。

总结一下

Cakephp关联表的从表查询,可以借助belongsTo关联来查询,只要我们做好模型的相互关联,查询是没有问题的!
原文地址为:http://www.thinkly.cn/index.php/archives/187

發表日期:2009/5/20 9:11
應用擴展 工具箱







[進階搜尋]