我测试了,数据量几千条时,查询前三四页勉强凑合(还是有点慢),到第四、五页的时候再点下一页就没反应了,数据量几万条以上时查询时间很慢很慢(几分钟以上,没数据显示,最后报错)
报错:java.lang.OutOfMemoryErrorJava 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>

解决方案 »

  1.   

    // query.setMaxResults(100000); 
    要设置这么大干嘛呢?一个页面中需要显示这么多条数据吗?把第二个参数设置小一点就快了。100条已经很多了。
      

  2.   

    query.setMaxResults(100000); 如果我设置成10的话就只能查询10条数据啊,我页面设置的是每页显示10 条数据
    <logic:iterate id="guestBook" name="list" length="10" offset="${pageNum*10}"> 
      

  3.   

    一页显示10条  max为什么不设置为10,而是10000呢,你又不是结果集分页。
      

  4.   

    pageNum 根本没传到hibernate 中去,不知道你想做什么。setFirst 和 setMax都应该是变量的啊。
      

  5.   


    点下一页的时候重新发送一个请求,重新从数据库中查询,
    int page = Integer.parsetInt(request.getParameter("page"));
    int pagesize = 10;
    query.setFirstResult((page-1)*pagesize); 
    query.setMaxResults(10); 
      

  6.   

    思路:1.查出记录的总数
    采用"SELECT COUNT(*) FROM guestbook"得到总数,而不是查出全部数据再计算总数,因为全部查出来后数据量大,栈空间根本就不够,所以报Java heap space错误。
          2.query分页用法
          Query q = session.createQuery("from GuestBook order by id desc");
         q.setFirstResult(startNum);
         q.setMaxResults(countNum);
        这样得到的数据就是你想要的,startNum表示是第几条记录开始,countNum是指从开始记录起往后取countNum条数据。可参考zhoupuyue的。
          
      

  7.   

    /**
     * 查找数据的数量*/
    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();
    }
                    //要求返回一个整型。返回?
    }
      

  8.   

    不好意思,上面我写错了,现在改过来了,现在的问题是:
    在Action中:
    List list = this.guestBookBiz.getAllGuestBooks();
    int size = list.size();
    System.out.println("listsize:"+size);
    int count = size%pageNum==0?size/pageNum:size/pageNum+1;//分页
    //报错:java.lang.ArithmeticException: / by zero/** 
    * 查找数据的数量*/ 
    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(); 

                    //要求返回一个整型。返回? 
    }
      

  9.   


    public int getAllGuestBooksCount(int firstResult){ 
    Session session = this.getSession(); 
    int records = 0;
    Transaction tran = null; 
    String sql = "select count(*) from GuestBook"; 
    try { 
    tran = session.beginTransaction(); 
    records = ((Long)session.createQuery(sql).uniqueResult()).intValue();  
    } catch (HibernateException e) { 
    // TODO 自动生成 catch 块 
    e.printStackTrace(); 

    return records;            //要求返回一个整型。返回? 
    }
      

  10.   

    晕 实际工作中没有哪个项目中一页显示上万条数据,如果确实有那样的需求(估计不太可能),有如下优化方法:
    1.楼上说的建立索引(一般是不经常更新的数据)
    2.把JVM内存设的足够大(有点霸蛮)
    3.用JDBC
    如果还有的话,高手补充
      

  11.   

    OutOfMemoryError内存溢出啊hibernate分页感觉不太好
      

  12.   

    内在溢出了.不要怪HIBERNATE,而是你的做法很有问题.
      

  13.   

    不要用结果集或session分页。一个页显示多少就取多少条。
      

  14.   

    楼主,你查询结果集,你session关了没?
    session不关,不慢才怪
      

  15.   

    i服了you!
      

  16.   

    这不是hiberbate分页好不    你是把数据都查询出来想丢页面上去分页。
    哪是hiberbate分页啊。       hibernate分页是你每次点下一次上一次的时候把要查询的起始位置和大小传进去   只查每页要显示的数据   
    数据量少的时候可以采用页面分页  但是当数据量大的时候那肯定是数据库分页啊   
    你一次查10000条数据内存不溢出才怪。  
    数据库分页 注意使用q.setFirstResult(startNum); q.setMaxResults(countNum); 
      

  17.   

    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;
     }
      

  18.   

    query.setFirstResult(0);
    // query.setMaxResults(100000) 在这里做个文章。   如果一页只显示10条 max改为10    显示哪10条 就从哪开始
      

  19.   

    DAO类代码(可以查询前10 条数据,但下一页没数据了,再点就没反应了):
    /*** 查找全部*/
    public List getAllGuestBooks(int firstResult){
    Session session = this.getSession();
    Query query = session.createQuery("from GuestBook order by id desc");
    query.setFirstResult(firstResult);
    query.setMaxResults(10);
    List list = query.list();
    //Iterator it = list.iterator();
    return list;
    }
    Action中代码片段:
    String pageIndex = request.getParameter("pageIndex");//得到页的下标
    int pageNum = Integer.parseInt(pageIndex);
    List list = this.guestBookBiz.getAllGuestBooks((pageNum-1)*10);
    问题:只能查询前10 条数据
    首页下标为0,从0开始显示,这没错
    但第2页下标为1,(1-1)*10=0,怎么显示?我设置成pageNum*10也没用
      

  20.   

    报错!
    com.microsoft.sqlserver.jdbc.SQLServerException: 只进 ResultSet 不支持请求的操作。
      

  21.   


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

  22.   

    List list = this.guestBookBiz.getAllGuestBooks((pageNum-1)*10); 第一页下标pageNum为0,从第0个开始显示,
    但第2页下标pageNum为1,(1-1)*10,怎么解决
      

  23.   

    第1页下标 pageNum为0,(0-1)*10 ???
    第2页下标 pageNum为1,(1-1)*10 ???
      

  24.   

    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)
    为什么关了网页第二次登陆就进不了显示数据的网页了呢?
      

  25.   

    建议 看看 分页原理。先抛弃hibernate,自己写写,体会下,分页到底是个什么东西。然后在看看bibernate,这个应该不是问题。
      

  26.   

    /**
     * 分页查询
     * 使用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;
    }