天行健,君子以自强不息

BlogJava 首页 新随笔 联系 聚合 管理
  12 Posts :: 0 Stories :: 2 Comments :: 0 Trackbacks
由于Hibernate的强大,我们对数据库的操作也省心了不少,但是hibernate自动生成的一系列sql,也许并不是如我们所想象的那样,所以,我们又多了一些本来不要操心的事情。比如在一对多的查询中,就有可能存在查询记录重复的问题。

有如下两个对象:文章和关键字。它们之间的关系,很明显,是一对多的关系,一个文章可以有很多的关键字。

假设有文章atricleA、articleB,articleA有关键字keyword1、keyword2,articleB有关键字keyword3、keyword4。
我们现在想查询含有关键字keyword1或者keyword3的所有文章列表,正确的结果应该是articleA和articleB两条记录。然而,如果使用hibernate不当,有可能你得到的是articleA、articleA、articleB、articleB四条记录,其中两条是重复的。

这是怎么发生的呢?
如果我们这样使用hibernate来实现这个查询:
StringBuffer queryString = new StringBuffer();
queryString.append(
"from ArticleData where keyword=? or keyword=?");

String[] param 
= new String[]{"keyword1","keyword3"};

Query query 
= session.createQuery(queryString );

query.list();

看看hibernate给我们生成的sql语句:
select article_table_.*
from
 articletable article_table_,keywordtable keyword_table1_ ,keywordtable keyword_table2_
where article_table_.id=keyword_table1_.articleid and article_table_.id=keyword_table2_.articleid
          and
 (keyword_table1_.name='keyword1' or keyword_table2_.name='keyword3')
根据这个sql,我们可以得出,满足where约束的有如下几个组合:
articleA   keyword1  keyword1
articleA   keyword1  keyword2
aritcleB   keyword3  keyword3
articleB   keyword3  keyword4
正是我们之前所说得到的错误结果。

仔细分析这个sql,其实问题就出在hibernate生成sql的时候,对同一个表keywordtable查询了两次(在from中出现两次),因此就有了组合的可能性,可以想见,如果再多几个需要查询的关键字,同一个记录重复的次数会更多。

其实,要正确的破解这个问题,我们可以自己写sql语句,使用hibernate同样支持的原生sql查询,不使用hibernate的hql查询。

hibernate在给我们带来很多便利性的同时,也给我们多多少少带来了一些麻烦,而这些问题的定位成本可能也会很高。要使用好工具,就要知道工具的优缺点,尤其是缺点要有足够的风险控制。

革命尚未成功,同志仍需努力!

posted on 2008-04-22 00:14 yill 阅读(3562) 评论(1)  编辑  收藏

Feedback

# re: Hibernate 一对多查询的记录重复问题 2012-04-29 22:57
直接用select distinct 对象名 +后面的一堆就可以了  回复  更多评论
  


只有注册用户登录后才能发表评论。


网站导航: