求助:hibernate 多对多 多对一 多表连接查询问题。
问题描述:每个Article可以有多个Tag,而每个Tag可以被多个Article使用,二者之间是多对多关系。然后每个Tag属于一个TagClass,而者之间是多对一关系。
现在我怎样用hql把所有属于一个TagClass的Article搜索出来?(严格的应该说是使用了该tagClass下的Tag的所有Article)。
代码演示:
public class Article
{
Long id;
String title;
.......
Set<Tag> tags = new HashSet<Tag>();
........
}
public class Tag
{
Long id;
String tagTitle;
TagClass tagClass;
........
Set<Article> arts = new HashSet<Article>();
........
}
public class TagClass
{
Long id;
String className;
.........
Set<Tag> tags = new HashSet<Tag>();
..........
}
在DAO层要实现的方法。
public List<Article> findArticleByTagClass(TagClass tagClass);
莫非我非得建立一个Article 到TagClass之间的多对一关系?这样是在不便于管理啊。比方修改了Tag所属的TagClass,还得修改Article和TagClass的对应关系。
问题描述完毕,请高手赐教。
问题点数:100、回复次数:12Top
1 楼Jolestar(叶明)回复于 2006-11-02 11:43:27 得分 0
还有一个问题。也一并提出。
如果我要解除Article和Tag之间的关联,是否非得加载Article的tags Set,然后从Set中remove,然后再update?
有没有办法直接将而者关联表中的字段删除,而不用加载。hql怎么写?Top
2 楼hbwhwang(【生病了,好好休息中...】)回复于 2006-11-02 13:04:03 得分 15
对于Hibernate不熟练的使用者,不要滥用关联关系,里面有太多你无法控制的东西。
最好老老实实地跟表字段建一样的属性。比如Tag定义一个字段tagclassid,存放TagClass的ID值而不是对象。
public List<Article> findArticleByTagClass(TagClass tagClass);
实现这个方法的时候可以这样:
select a from Article a,TagClass tc,Tag t where t.tagclassid=tc.id and
tc.id=:tagclass.id
Top
3 楼Jolestar(叶明)回复于 2006-11-02 18:41:01 得分 0
老大,这个sql语句会把所有的Article都搜索出来吧。因为你在where中没有对article做限制,更本没有用到Article到Tag的多对多映射表。
这个问题我是这样解决的。
Criteria criteria = this.getSession().createCriteria(Article.class)
.createAlias("tags","t")
.add(Expression.eq("t.tagClass",tagClass));
return criteria.list();
用hibernate时,老感觉以前那种用直接用sql的思维改不过来,只要换一下思维,用面对对象的方式去思考,才能真正体会到hibernate的好处。Top
4 楼hbwhwang(【生病了,好好休息中...】)回复于 2006-11-02 19:14:51 得分 15
sorry,写错了。
我不对你用relationship mapping发表意见。我只说说如果我会怎么做。
表:
article(id)
tag(id,tagclassid)
tagclass(id)
再加一个表述article与tag的关系表:articetag(articleid,tagid)
做4个POJO,对应4个表
select a from Article a,TagClass tc,Tag t,ArticlTag at
where
at.articleid=a.id and at.tagid=t.id and
t.tagclassid=tc.id and
tc.id=:tagclass.id
你可能认为写这个HQL麻烦,
不过我要告诉你,你用这点麻烦换取了更大灵活性和更好的控制性,是非常值得的。
Top
5 楼hehaorome(石沉大海)回复于 2006-11-03 17:03:15 得分 15
帮顶Top
6 楼sun113(我是一棵树!)回复于 2006-11-04 15:28:33 得分 10
Criteria criteria = this.getSession().createCriteria(Article.class)
.createAlias("tags","t")
.add(Expression.eq("t.tagClass",tagClass));
return criteria.list();
请搂主帮忙解释下,
createAlias("tags","t")
Expression.eq("t.tagClass",tagClass)
怎么理解阿,尤其是t.tagClass
t值得就是那个set是吗?可是这个set怎么有了tagClass属性了?
请帮忙,我这块实在理解不了
Top
7 楼Jolestar(叶明)回复于 2006-11-06 16:43:11 得分 0
createAlias创建了tags的别名t。
这里的t是set中一个个具体的tag的代称。所以有tagClass属性了。Top
8 楼Jolestar(叶明)回复于 2006-11-06 16:44:39 得分 0
有没人说明一下后一个问题?
要结贴了。Top
9 楼hbwhwang(【生病了,好好休息中...】)回复于 2006-11-06 19:51:31 得分 20
第二个问题是:
如果我要解除Article和Tag之间的关联,是否非得加载Article的tags Set,然后从Set中remove,然后再update?
有没有办法直接将而者关联表中的字段删除,而不用加载。hql怎么写?
======
答案:不用这么麻烦。简单点,就用Native SQL,自己写个SQL,想怎么删就怎么删!
Hibernate就是个工具而已,不要被一个工具束缚了自己的思想!Top
10 楼Jolestar(叶明)回复于 2006-11-06 20:17:17 得分 0
ok。偶也是这么想地。Top
11 楼hbwhwang(【生病了,好好休息中...】)回复于 2006-11-06 20:36:44 得分 15
我建议你不要用关系映射,这玩意真不好掌握,象个泥鳅。
也不是说无法掌握,而是花太多的时间去掌握不值得。
Top
12 楼honeyego(像BUG一样钻进代码最深处)回复于 2006-11-08 15:40:34 得分 10
我现在就是被关系映射搞得晕头转向
晕死啊,看了好久,什么都没搞出来
谢谢hbwhwang的经验之谈Top




