在Hibernate中有个方法是可以实现分页的
public List<LcmCase> getPageCase(PageBean pagebean,String hqlString){
session=getSessionFactory().getCurrentSession();
Query query=session.createQuery(hqlString);
query.setFirstResult(pagebean.getPagesize()*(pagebean.getPageindex()-1));
query.setMaxResults(pagebean.getPagesize());
List<LcmCase> pagecaseList=query.list(); 
                  return  pagecaseList;
这个分页直接返回了一个封装了实体的集合,调用的时候很方便。但是却被师傅否定
具体什么不好,他要我好好想想,,惭愧,我实在是想不出来
如果不用这方法,那么就只有用存储过程实现了
用存储过程,那么就不能避免去封装实体对象,如果一张表有几十个字段,一个一个字段的封装
那不是要抓狂了!!而且还不通用
前辈们,
首先用hibernate实现的分页到底有什么弊端?
还有 如果用存储过程来实现,那么对于那些属性的封装该用什么方法来解决?

解决方案 »

  1.   

    我的老师建议是直接使用Hibernate里面的封装功能:
    this.getHibernateTemplate().find(sql);进行分页(不过我没用)
    但是你的程序好奇怪,你没有用Spring吗?
    如果你有Spring和Hibernate整合,获取连接应该不是:
    session=getSessionFactory().getCurrentSession(); 
    而是:
    session = this.getSession();就好啦我最近也是做了项目也是用ssh的,我把你的代码改成:
       
        public List <LcmCase> getPageCase(int pageNum,int item,String sql){  Query query =  this.getSession().createQuery(sql)
                   .setFirstResult((pageNum-1)*item)
                   .setMaxResults(item);
       
         List<LcmCase> list = query.list();
         
         if(list > 0){
          return list;
         }else{
           return 0;
         }
          
         }不踩我哈,我也是个小菜鸟!
      

  2.   

    那个session = this.getSession();是在当前这个操作类是继承了HibernateDaoSupport才能这样写,不然就是session = HibernateSessionFactory.getSession();
      

  3.   

    不知道hib的具体实现,本人一般都是针对不同数据库,利用数据库本身的分页关键字来做,比如limit(postgres)、row_number()分析函数(oracle)等等来做。
      

  4.   

    而且你说不用这个,只能用存储过程,虽然本人不懂hib没用过,但本人不同意。你完全可以用hib支持原生sql的对象映射,利用hib的映射来做,只不过分页sql你自己写而已。
      

  5.   

    在网上看到个方法,高手们给点意见
    这方法怎么样,
    存储过程是SQL2005的相信你们都知道,我就不贴了Hibernate的配置文件:
        <hibernate-mapping>
        <class name="com.mengya.entity.TDepart" table="t_depart" schema="dbo" catalog="oaproject">
            <id name="DId" type="java.lang.Integer">
                <column name="d_id" />
                <generator class="native" />
            </id>
            <property name="DName" type="java.lang.String">
                <column name="d_name" length="50" />
            </property>
            <property name="DRe" type="java.lang.String">
                <column name="d_re" />
            </property>
            <set name="TEmps" inverse="true">
                <key>
                    <column name="d_id" />
                </key>
                <one-to-many class="com.mengya.entity.TEmp" />
            </set>       
        </class>
        <!--<sql-query>不在<class>内面-->
        <sql-query name="TDepartTure_Page" callable="true">
             <return alias="TDepart" class="com.mengya.entity.TDepart">
              <return-property name="DId" column="d_id"/>
              <return-property name="DName" column="d_name"/>
              <return-property name="DRe" column="d_re"/>
             </return>
             {call Ture_Page(?,?,?,?,?,?,?)}
             <query-param name="PageSize" type="int"/>
          <query-param name="PageIndex" type="int"/>
          <query-param name="Col" type="String"/>
          <query-param name="Table" type="String"/>
          <query-param name="Where" type="String"/>
          <query-param name="OKey" type="String"/>
          <query-param name="Order" type="String"/>      
            </sql-query>
    </hibernate-mapping>    
     调用存储过程:
        ......
    /*
      * 分页查询所有部门信息
      */
     public List getPageDepart(final int pagesize,final int pageindex){
      List pagelist=null;
      try {   //这里我使用的Hibernate的getHibernateTemplate()方法也要可直接得到session
       pagelist=getHibernateTemplate().executeFind(new HibernateCallback(){    public Object doInHibernate(Session session) throws HibernateException, SQLException {
         Query query=session.getNamedQuery("TDepartTure_Page");
         query.setInteger(0, pagesize);
         query.setInteger(1, pageindex);
         query.setString(2, "d_id,d_name,d_re");
         query.setString(3, "t_depart");
         query.setString(4, "");
         query.setString(5, "d_id");
         query.setString(6, "desc");
         return query.list();
        }
        
       });
      } catch (RuntimeException e) {
       e.printStackTrace();
       throw e;
      }
      return pagelist;
     }
      我不明白的就是,他这里怎么两个方法套在一起用了?
      

  6.   

    new HibernateCallback(){...}其实是匿名内部类,而这个匿名内部类必须实现doInHibernate(...)方法
      

  7.   

    两个方法套一起,这是spring封装的一个模板方法,getHibernateTemplate().executeFind(new HibernateCallback()好像就是说不用自己再去拿session了,spring自动帮我们开启和关闭了,我也是刚接触这个模板方法没多久,也知道这些;还有LZ师傅意思会不会不是叫你用什么过程呢,因为我也觉得lz只用list搞分页不太好,我做分页都是建一个Page对象,而Page对象里有对象的集合,还有其他当前页码,总页码,下一页,上一页等方法,代码如下public class Page {

     /* 当前页号 页数从0开始。即 第一页 */  
        private int currentPage = 1;  
      
        /* 总页数 */  
        private int totalPage;  
      
    //    /* 是否有首页*/
    //    private boolean hasFirstPage = false;
    //    
        /* 是否有上一页 */  
        private boolean hasPrePage = false;  
      
        /* 是否有下一页 */  
        private boolean hasNextPage = false;  
      
    //    /* 是否有末页 */
    //    private boolean hasLastPage = true;
    //    
        
        /* 当前页记录开始索引 */  
        private int startIndex;  
      
        /* 记录总数 */  
        private int totalRows;  
      
        /* 每页记录数默认为10 */  
        private int pageSize = 10;    /*对象记录集*/
        private List result;
        
        public Page(){
        
        }
        
        public Page(int currentPage,int totalRows,int pageSize){     this.currentPage = currentPage;     //总记录数
         this.totalRows = totalRows;
        
         //设置页面记录数
         this.setPageSize(pageSize);
        
         //设置总页数 总页数为0 则为第一页
        
         this.totalPage = totalRows/pageSize == 0? 1 : totalRows/pageSize ;
         if(totalRows/pageSize>0){
         //有余数总数加1
             this.totalPage = totalRows%pageSize > 0  ? this.totalPage + 1 : this.totalPage;
         }
        
        
         if(currentPage>1){
         this.hasPrePage = true;
         }else {
         this.hasPrePage = false;
         }
        
         if(currentPage<this.totalPage){
         this.hasNextPage = true;
         }else{
         this.hasNextPage = false;
         }
        
        } 
    public int getCurrentPage() {
    return currentPage;
    } public void setCurrentPage(int currentPage) {
    this.currentPage = currentPage;
    } public boolean isHasNextPage() {
    return hasNextPage;
    } public void setHasNextPage(boolean hasNextPage) {
    this.hasNextPage = hasNextPage;
    } public boolean isHasPrePage() {
    return hasPrePage;
    } public void setHasPrePage(boolean hasPrePage) {
    this.hasPrePage = hasPrePage;
    } public int getPageSize() {
    return pageSize;
    } public void setPageSize(int pageSize) {
    this.pageSize = pageSize;
    } public int getStartIndex() {
    return startIndex;
    } public void setStartIndex(int startIndex) {
    this.startIndex = startIndex;
    } public int getTotalPage() {
    return totalPage;
    } public void setTotalPage(int totalPage) {
    this.totalPage = totalPage;
    } public int getTotalRows() {
    return totalRows;
    } public void setTotalRows(int totalRows) {
    this.totalRows = totalRows;
    } public List getResult() {
    return result;
    } public void setResult(List result) {
    this.result = result;
    }  
    }
      

  8.   

    用过HIBERNATE分页 ,但是还没用过PAGEBEAN封装过的这种分页,你的PAGEBEAN里是如何定义? 需要先查库初始化一下PAGEBEAN吗? 然后在传递参数过来再次  查询?可能你这个封装好的分页方便是方便  但是要进行2次查库吧? 不知道我说的对不对,还没接触过PAGEBEAN这样的封装查询  猜了个大概 如果有空贴个原理及代码出来看看
      

  9.   

    贴下pageBean的原理//持久层调用的查找分页的公共方法
    public Page getAllObjects(final int currentPage, final int pageSize , final String sql) {


    return (Page)this.getHibernateTemplate().execute(new HibernateCallback(){ public Object doInHibernate(Session session) throws HibernateException, SQLException {
    // TODO 自动生成方法存根
    Page page = null;
    Query q = session.createQuery(sql);
    int total = q.list().size(); page = new Page(currentPage,total,pageSize);

    //分页  当前页数 乘 每页分页记录数;
    int firstResult = (currentPage-1)*pageSize == 0 ? 0 : (currentPage-1)*pageSize ;

    q.setFirstResult(firstResult);
    q.setMaxResults(pageSize);
    page.setResult(q.list()); return page;
    }});
    }

    //比如说查找EMP对象,则方法实现如下:
    public Page getAllObjects(final int currentPage, final int pageSize)throws Exception {

    String sql = "from Emp order by empno ";

     return super.getAllObjects(currentPage, pageSize, sql); }//web层方面
    Page page = empManager.getAllQueryObject(condition, currentPage, pageSize);
    request.setAttribute("page", page);//jsp页面方面使用的jstl,使用其他sturts标签或者jsp也行  <c:forEach var="emp" items="${page.result}" varStatus="index">
    <tr>
    <td>${index.count+(page.currentPage-1)*page.pageSize }</td>
    <td>${emp.empno }</td>
    <td>${emp.ename}</td>
    <td>${emp.job}</td>
    <td>${emp.mgr}</td>
    </tr>
    </c:forEach> <td  align="right" style="font-size:10pt;" colspan="9">
        第${page.currentPage }页/共${page.totalPage }页&nbsp;&nbsp;
        <c:choose>
         <c:when test="${page.hasPrePage}">
         <a href="javascript:jump('toFirst');">首页</a>|
         <a href="javascript:jump('toPrePage');">上一页</a>|
         </c:when>
         <c:otherwise>首页|上一页|</c:otherwise>
        </c:choose> 
        <c:choose>
         <c:when test="${page.hasNextPage}">
         <a href="javascript:jump('toNextPage');">下一页</a>|
         <a href="javascript:jump('toLastPage');">末页</a>
         </c:when>
         <c:otherwise>下一页|末页</c:otherwise>
        </c:choose>
    有了pagebean对象,总页码,当前页,是否存在上一页下一页问题都解决了,如果还有新的什么问题,自己还可以往pageBean添加
      

  10.   

    恩,,谢谢各位的解答,,
    用Hibernate的分页是不是效率不好呢?
    我现在还是改为用存储过程。连接是用JDBC的那种形式
    最后返回的结果集通过反射的原理来封装对象