hibernate的setFirstResult(a),setMaxResults(b)后,不按照一定顺序取值

悟空在此 2009-01-18 04:56:40
用Hibernate分页的时候,当sort的字段里的值基本相等时候,分页的结果会出现数据重复和丢失。
比如没有分页之前顺序是,1,2,3,4,5,6,7,8,9.(其实按照sort字段排序的话,这些数据顺序基本是一样的,就是大部分是不分顺序的。)
分页后就会出现:第一页(1,2,4,),第二页(3,2,5),第三页(7,8,9),其中2重复了,而6丢失了。

仔细分析代码后,发现错误在Query的setFirstResult,setMaxResults里。
代码如下:
Query query = entityManager.get().createQuery(q.toString());
for (String key : params.keySet()) {
query.setParameter(key, params.get(key));
}
List queryListA = query.getResultList(); //此语句用来测试,查出来的结果和数据库里吻合。

query.setFirstResult(first);
query.setMaxResults(count);

List queryListB = query.getResultList(); //此语句用来测试,当执行了setFirstResult,setMaxResults语句后,问题就会出现。如果sort字段是能够按照一定顺序排序的话,分页没有问题,但是如果sort字段值基本相等,则就会出错。
例如:假设没有分页之前,queryListA里得到的值顺序:1,2,3,4,5,6,7,8,9,10。。。。,那么在执行setFirstResult(0),setMaxResults(4)后,queryListB得到的值:2,1,4,3;而并不是1,2,3,4(随着数据库值不同,得到的结果也不一样)

也就是说,setFirstResult(first);setMaxResults(count);后,并不是按照查询出来的结果顺序,从first开始取到count的数据的。

实在不知道为什么,请高手指教。
非常感谢。
...全文
4157 17 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
t150ckh 2010-11-01
  • 打赏
  • 举报
回复
set 是无序的,想要让集合里的值是有序的,最好用TreeMap,键用int类型,这样子取出来的值才会是有序的....
xyy0738 2010-08-10
  • 打赏
  • 举报
回复
解决的办法就象14楼说的那样order by一下,注意order by排序字段里的值要有一个字段的值不重复
gzmabo 2010-01-28
  • 打赏
  • 举报
回复
楼主,你这问题应该解决了吧?能不能说下是怎么解决这个分页查询第二页出现重复数据的,我现在也出现了这个问题,实在不知道解决办法!!!
cs_dn001 2009-05-29
  • 打赏
  • 举报
回复
用order by 就可以了
lq414203 2009-01-25
  • 打赏
  • 举报
回复
List queryListB = query.getResultList().setFirstResult(first).setMaxResults(count).list();
Landor2004 2009-01-19
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 zou_wei_forever 的回复:]
在set标签上设置order-by属性试试!

<set  order-by="数据库中的某个字段 asc或者desc">
</set>
[/Quote]
正解!
或者直接在hql中写order by 语句,注意order by的内容要非空
zou_wei_forever 2009-01-19
  • 打赏
  • 举报
回复
在set标签上设置order-by属性试试!

<set order-by="数据库中的某个字段 asc或者desc">
</set>
zou_wei_forever 2009-01-19
  • 打赏
  • 举报
回复
在set标签上设置order-by属性试试!

<set order-by="数据库中的某个字段">
</set>
悟空在此 2009-01-19
  • 打赏
  • 举报
回复
建议不要把你的数据放到set里面

\----------------------------\

应该放在哪里?怎么实现呢?
fosjos 2009-01-18
  • 打赏
  • 举报
回复
我觉得既然是分页,用不用first和count应该是统一的,如果first<0,也可以设置first=0
不管到第几页语句应该统一
悟空在此 2009-01-18
  • 打赏
  • 举报
回复
sql每次都是一样的。
程序执行到下面这一句的时候,返回的query结果还是一样的。
Query query = entityManager.get().createQuery(q.toString());

从setFirstResult(first);setMaxResults(count);执行后,结果就不一样了。

难道是说,执行完setFirstResult(first);setMaxResults(count);这个语句后,
后面又执行了一次sql查询???
并不是将查询出来的结果,直接从first开始取count条??
a1405 2009-01-18
  • 打赏
  • 举报
回复
if (orderMap != null) {
isFirstClause = true;
for (Map.Entry <String, Boolean> entry : orderMap.entrySet()) {
if (isFirstClause) {
q.append(" order by ");
} else {
q.append(" , ");
}
if (entry.getValue()) {
q.append("obj.").append(entry.getKey()).append(" asc ");
} else {
q.append("obj.").append(entry.getKey()).append(" desc ");
}
isFirstClause = false;
}
}

orderMap != null就是说不是每次都有order by 了
每次排序不一样取的当然不一样。
打印show_sql到后台看看就能明白
fosjos 2009-01-18
  • 打赏
  • 举报
回复
show_sql看看两句sql是否相同
悟空在此 2009-01-18
  • 打赏
  • 举报
回复
for (String key : params.keySet()) {

这里不是将数据放到set里的,是将sort的字段放到qury里的。

查询的数据是放到list里的。


每次查询的顺序都是一样的,但是在
query.setFirstResult(first);
query.setMaxResults(count);
以后,取出来的数据顺序就不一样了。

但是如果sort的字段值是有序的话,顺序还是一样的。
lihan6415151528 2009-01-18
  • 打赏
  • 举报
回复
建议不要把你的数据放到set里面
lihan6415151528 2009-01-18
  • 打赏
  • 举报
回复
很简单for (String key : params.keySet())
set是无序的,所以你那样肯定就是不按照顺序了
悟空在此 2009-01-18
  • 打赏
  • 举报
回复
附加整个查询函数代码:

private Query getQueryByHql(String hql, Map<String, Object> params, int first, int count, LinkedHashMap<String, Boolean> orderMap) {
boolean isFirstClause;
StringBuffer q = new StringBuffer(hql);
if (orderMap != null) {
isFirstClause = true;
for (Map.Entry<String, Boolean> entry : orderMap.entrySet()) {
if (isFirstClause) {
q.append(" order by ");
} else {
q.append(" , ");
}
if (entry.getValue()) {
q.append("obj.").append(entry.getKey()).append(" asc ");
} else {
q.append("obj.").append(entry.getKey()).append(" desc ");
}
isFirstClause = false;
}
}
Query query = entityManager.get().createQuery(q.toString());
for (String key : params.keySet()) {
query.setParameter(key, params.get(key));
}
if (count > 0 && first >= 0) {
query.setFirstResult(first);
query.setMaxResults(count);
}
return query;
}

请教高手,万分感谢。

67,547

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧