Chinaunix
标题:
Cakephp中用join进行多对多关联查询
[打印本页]
作者:
sbguh
时间:
2009-11-05 14:09
标题:
Cakephp中用join进行多对多关联查询
我今天要说的是对hasAndBelongsToMany关联模式进行筛选查询,如一篇文章有很多个tag,而一个tag同时也会对应很多篇文章,这就属于典型的多对多hasAndBelongsToMany关联模式,那么如果我想查询某一个tag所对应的所有的文章呢?这样的查询在cakephp应该怎么去写呢?
情景:
一个articles表对应(Article) --字段假设是(id,title,content)
一个tags表对应(Tag) - 字段假设是(id,name)
这两个表属于多对多关系
Article中定义
var $hasAndBelongsToMany = array(
'Tag' => array(
'className' => 'Tag',
'joinTable' => 'tags_articles',
'foreignKey' => 'article_id',
'associationForeignKey' => 'tag_id',
)
);
复制代码
Tag模型中定义
var $hasAndBelongsToMany = array(
'Article' => array(
'className' => 'Article',
'joinTable' => 'tags_articles',
'foreignKey' => 'tag_id',
'associationForeignKey' => 'article_id',
)
);
复制代码
由此可见两个model表都是通过第三个表tags_articles进行关联
tags_articles字段假设是(tag_id , article_id)
现在假设我有这样的一个需求:我要得到tag中name='test'所有的文章(article)
如果我们这样写$this->Article->find('all',array('conditions'=>array('Tag.name'=>'test'))),那么系统执行的时候会出现一个错误'Unknown column 'Tag.name' in 'where clause'',因为这种直接写条件的查询方式目前据我所知还只适合hasOne和belongsTo的关联模式,对hasMany和hasAndBelongsToMany关联模式还是不支持的
我不知道别人都是怎么做这个查询的,不过我见过有人是这样做的,先根据name在tags表里面查询到这个tag的id,然后通过这个ID去tags_articles表中查询到所有关联此tag_id的article_id,然后再根据取得的article_id在Article表中进行查询,最后才查询到所要的值。
但是我一直觉得这样太过于麻烦了,要做好几次查询,最好我查资料想到了一个似乎比较好的方法,大家看我最后写的查询语句
$this->Article->find('all',array(
'conditions' => array('Tag.name'=>'test'),
'joins'=>array(array(
'table'=>'tags_articles',
'alias'=>'TagsArticle',
'type'=>'left',
'conditions'=> array('Article.id = TagsArticle.article_id'),
),
array(
'table'=>'tags',
'alias'=>'Tag',
'type'=>'left',
'conditions'=> array('Tag.id = TagsArticle.tag_id'),
)
)
))
复制代码
大家可以试试我这种方法,当然这并不一定是个好方法,呵呵,大家如果有更好的方法希望共享共享哦, 最后大家可以访问我的网站一起交流学习
http://www.shopokey.com
作者:
bs
时间:
2009-11-05 19:17
ORM的难处在于对复杂sql的处理是否高效、优化,这个很重要
作者:
shopokey
时间:
2009-11-05 20:52
cakephp在处理关联的时候如果不正确处理,会造成浪费很大资源,把很多没有用的数据一起取出来作为数组,在这点上我还是觉得django做的好,它只是把关联的地方作为对象返回来,而不是直接把所有关联的数据取出来
作者:
yangchaohi
时间:
2009-11-05 22:25
cakephp不了解,学习了,ORM用的比较少,自己手写比较多~
欢迎光临 Chinaunix (http://bbs.chinaunix.net/)
Powered by Discuz! X3.2