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的数据的。

实在不知道为什么,请高手指教。
非常感谢。
...全文
4240 17 打赏 收藏 转发到动态 举报
写回复
用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;
}

请教高手,万分感谢。
内容概要:本文围绕基于CNN-BiLSTM-Attention混合神经网络模型的电力负荷预测展开研究,提出一种结合卷积神经网络(CNN)、双向长短期记忆网络(BiLSTM)与注意力机制(Attention)的深度学习框架,并通过Python代码实现高精度的短期与超短期负荷预测。该模型充分利用CNN对局部特征的提取能力,捕捉负荷数据中的周期性与趋势性模式;借助BiLSTM对时间序列前后向依赖关系的建模能力,增强对动态变化的感知;并通过Attention机制自适应地聚焦关键历史时刻,提升预测准确性。文中详细阐述了数据预处理、模型结构设计、训练流程及超参数调优方法,并在真实负荷数据集上进行了实验验证,结果表明该混合模型相比传统单一模型和其他基准模型具有更优的预测性能,尤其在应对非线性、非平稳负荷波动方面表现突出。; 适合人群:具备一定Python编程能力和机器学习基础,从事电力系统分析、能源管理、智能电网或时序预测相关工作的科研人员、工程师及高校研究生。; 使用场景及目标:①应用于电网调度、电力市场出清、需求响应管理等场景下的精细化负荷预测;②为研究人员提供一套完整的、可复现的深度学习负荷预测代码框架,推动AI技术在能源领域的落地应用;③帮助理解CNN、BiLSTM与Attention模块之间的协同机制及其在时序建模中的集成方式。; 阅读建议:建议读者结合所提供的Python代码进行动手实践,重点掌握数据归一化、滑动窗口构造、模型搭建与训练技巧,并尝试在不同地区、不同季节的负荷数据上进行迁移测试,以深入理解模型泛化能力与调参策略。

67,535

社区成员

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

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