Hibernate分页查询数据量几万条以上的时候,狂慢!没反应最后报错,怎样解决?

sw4433 2009-12-27 08:05:34
我测试了,数据量几千条时,查询前三四页勉强凑合(还是有点慢),到第四、五页的时候再点下一页就没反应了,数据量几万条以上时查询时间很慢很慢(几分钟以上,没数据显示,最后报错)
报错:java.lang.OutOfMemoryError: Java heap space
SSH,Server2005,Eclipse,tomcat
DAO类代码
public List getAllGuestBooks(){
return getHibernateTemplate().find("from GuestBook order by id desc");
//用下面方法查询速度依然很慢
// Session session = this.getSession();
// Query query = session.createQuery("from GuestBook");
// query.setFirstResult(0);
// query.setMaxResults(100000);
// List list = query.list();
// //Iterator it = list.iterator();
// return list;
}
调用上面方法
/**
* 查找全部记录*/
public List getAllGuestBooks(){
return this.guestBookDAO.getAllGuestBooks();
}
/**
* 分页显示数据 * retuen 页数
* pageNum 每页显示数量*/
public int pageCount(int pageNum){
int count = this.getAllGuestBooks().size();
return count%pageNum==0?count/pageNum:count/pageNum+1;
}

Action调用:
/**
* 登陆后显示数据
* */
public ActionForward admin(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
DynaActionForm guestBookForm = (DynaActionForm) form;// TODO Auto-generated method stub
HttpSession session = request.getSession();
if(LoginAction.validate(request)==false){
return mapping.findForward("guestbook.admin.login");
}
System.out.println("admin");
//得到页的下标
String pageIndex = request.getParameter("pageIndex"); int pageNum = 0;
if(pageIndex == "" || pageIndex==null){
pageNum = 0;
}else{
pageNum = Integer.parseInt(pageIndex);
}
int count = this.guestBookBiz.pageCount(10);//页数

session.setAttribute("pageNum", pageIndex);
session.setAttribute("count", String.valueOf(count));

List list = this.guestBookBiz.getAllGuestBooks();
request.setAttribute("list", list); request.setAttribute("listSize", String.valueOf(list.size()));
return mapping.findForward("guestbook.admin");
}

jsp页面:
<logic:equal value="0" name="pageNum">
首页
</logic:equal>

<logic:notEqual value="0" name="pageNum">
<a href="${pageContext.request.contextPath }/guestBook.do?method=admin&pageIndex=0">首页</a>
</logic:notEqual>

<logic:equal value="0" name="pageNum">
上一页
</logic:equal>

<logic:notEqual value="0" name="pageNum">
<a href="${pageContext.request.contextPath }/guestBook.do?method=admin&pageIndex=${pageNum-1 }">上一页</a>
</logic:notEqual>

<logic:equal value="${count-1}" name="pageNum">
下一页
</logic:equal>

<logic:notEqual value="${count-1}" name="pageNum">
<a href="${pageContext.request.contextPath }/guestBook.do?method=admin&pageIndex=${pageNum+1 }">下一页</a>
</logic:notEqual>

<logic:notEqual value="${count-1}" name="pageNum">
<a href="${pageContext.request.contextPath }/guestBook.do?method=admin&pageIndex=${count-1 }">尾页</a>
</logic:notEqual>
<logic:equal value="${count-1}" name="pageNum">尾页</logic:equal>
每行显示10条
<logic:iterate id="guestBook" name="list" length="10" offset="${pageNum*10}">
<table>
<tr>
<td>
${guestBook.name} ${guestBook.time}说: ${guestBook.title}</td>
<td>${guestBook.email} td>
<td>${guestBook.url} /td>
</tr>
<tr>
<td colspan="3">${guestBook.context} </td>
</tr>
</table>
</logic:iterate>
...全文
1578 38 打赏 收藏 转发到动态 举报
写回复
用AI写文章
38 条回复
切换为时间正序
请发表友善的回复…
发表回复
dingherry 2011-11-22
  • 打赏
  • 举报
回复
/**
* 分页查询
* 使用Spring框架中HibernateTemplate模板,调用Hibernate中分页的方法
* @param hql 查询的条件
* @param offset 开始记录
* @param length 一次查询几条记录
* @return List
*/
public List queryForPage(final String hql, final int offset, final int length) {
List list = getHibernateTemplate().executeFind(new HibernateCallback() {
public Object doInHibernate(Session session) throws HibernateException, SQLException {
Query query = session.createQuery(hql);
query.setFirstResult(offset);
query.setMaxResults(length);
List list = query.list();
return list;
}
});
return list;
}
b47248054 2009-12-28
  • 打赏
  • 举报
回复
建议 看看 分页原理。先抛弃hibernate,自己写写,体会下,分页到底是个什么东西。然后在看看bibernate,这个应该不是问题。
sw4433 2009-12-28
  • 打赏
  • 举报
回复
有什么好的方法?
sw4433 2009-12-28
  • 打赏
  • 举报
回复
[Quote=引用 28 楼 crazylaa 的回复:]
引用 27 楼 sw4433 的回复:
报错!
com.microsoft.sqlserver.jdbc.SQLServerException: 只进ResultSet不支持请求的操作。


你的结果集是Forward_only的,但你在程序里面试图前后双向滚动,比如rs.last()之后又想rs.beforeFirst().
[/Quote]

具体怎么操作啊?
sw4433 2009-12-28
  • 打赏
  • 举报
回复
int firstResult = 0;
if(pageNum == 0){
firstResult = 1;
}else{
firstResult = (pageNum+1) * 10;
}
List list = this.guestBookBiz.getAllGuestBooks(firstResult);

我改了,但只能显示第一页,点击下一页尾页没反应,关了网页再输入用户名密码登陆就一直停留在登陆界面,不知道怎么回事,而且也不进入Action了(我在action里面System.out.println("1234567890");没显示,应该没进入Action)
为什么关了网页第二次登陆就进不了显示数据的网页了呢?
luffyke 2009-12-28
  • 打赏
  • 举报
回复
建立下索引,设置下缓存!!!!!!
wenchao_222 2009-12-28
  • 打赏
  • 举报
回复
query.setFirstResult(0);
// query.setMaxResults(100000)

在这里做个文章。 如果一页只显示10条 max改为10 显示哪10条 就从哪开始


crazylaa 2009-12-28
  • 打赏
  • 举报
回复
[Quote=引用 32 楼 sw4433 的回复:]
第1页下标pageNum为0,(0-1)*10 ???
第2页下标pageNum为1,(1-1)*10 ???

[/Quote]

-应为+吧
wenjjing2lianee 2009-12-28
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 zhoupuyue 的回复:]
Java code
点下一页的时候重新发送一个请求,重新从数据库中查询,int page= Integer.parsetInt(request.getParameter("page"));int pagesize=10;
query.setFirstResult((page-1)*pagesize);
query.setMaxResults(10);
[/Quote]

支持一下
扁鵲東南飛 2009-12-28
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 sw4433 的回复:]
关键是我设置成10的话页面只能显示10 条数据,后面的数据就没了,设置大了就显示不了,郁闷!
[/Quote]
lz,你注意下你的那个设置问题,你设置10,说明的是每页查询出来的数,
但是要显示的不是在你和你设置的10是一个概念。
你查询的要把全部的都查询出来。你再仔细看看吧。

// query.setFirstResult(0);
// query.setMaxResults(100000);
这里面不应该设置整数吧,应该是你传递过来的变量?


public int getAllGuestBooksCount(int firstResult){
Session session = this.getSession();
Transaction tran = null;
String sql = "select count(*) from GuestBook";
try {
tran = session.beginTransaction();
Query query = session.createQuery(sql);
query.//?这里怎么写?
tran.commit();
} catch (HibernateException e) {
// TODO 自动生成 catch 块
e.printStackTrace();
}


// list = query.list();
别返回int 了。返回 个List 吧
public List getAllGuestBooksCount(int firstResult){

list = query.list(); //--- query.//?这里怎么写?

return list;
}


jbt202 2009-12-28
  • 打赏
  • 举报
回复
这不是hiberbate分页好不。。。 你是把数据都查询出来想丢页面上去分页。
哪是hiberbate分页啊。 hibernate分页是你每次点下一次上一次的时候把要查询的起始位置和大小传进去 只查每页要显示的数据
数据量少的时候可以采用页面分页 但是当数据量大的时候那肯定是数据库分页啊
你一次查10000条数据内存不溢出才怪。
数据库分页 注意使用q.setFirstResult(startNum); q.setMaxResults(countNum);
li445970924 2009-12-28
  • 打赏
  • 举报
回复
查询缓存
sw4433 2009-12-28
  • 打赏
  • 举报
回复
第1页下标 pageNum为0,(0-1)*10 ???
第2页下标 pageNum为1,(1-1)*10 ???
sw4433 2009-12-28
  • 打赏
  • 举报
回复
List list = this.guestBookBiz.getAllGuestBooks((pageNum-1)*10); 

第一页下标pageNum为0,从第0个开始显示,
但第2页下标pageNum为1,(1-1)*10,怎么解决
sw4433 2009-12-28
  • 打赏
  • 举报
回复
[Quote=引用 29 楼 deng1234 的回复:]
排序字段建索引。
[/Quote]

怎样 操作?
timeriver_wang 2009-12-28
  • 打赏
  • 举报
回复
i服了you!
deng1234 2009-12-28
  • 打赏
  • 举报
回复
排序字段建索引。
crazylaa 2009-12-28
  • 打赏
  • 举报
回复
[Quote=引用 27 楼 sw4433 的回复:]
报错!
com.microsoft.sqlserver.jdbc.SQLServerException: 只进ResultSet不支持请求的操作。
[/Quote]

你的结果集是Forward_only的,但你在程序里面试图前后双向滚动,比如rs.last()之后又想rs.beforeFirst().
sw4433 2009-12-28
  • 打赏
  • 举报
回复
报错!
com.microsoft.sqlserver.jdbc.SQLServerException: 只进 ResultSet 不支持请求的操作。
水中影子 2009-12-28
  • 打赏
  • 举报
回复
楼主,你查询结果集,你session关了没?
session不关,不慢才怪
加载更多回复(18)

81,094

社区成员

发帖
与我相关
我的任务
社区描述
Java Web 开发
社区管理员
  • Web 开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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