hibernate 分页

例如:
从第2万条开始取出100条记录

      代码:
      Query q = session.createQuery("from Cat as c");
      q.setFirstResult(20000);
      q.setMaxResults(100);
      List l = q.list();


那么Hibernate底层如何实现分页的呢?实际上Hibernate的查询定义在
net.sf.hibernate.loader.Loader这个类里面,仔细阅读该类代码,就可以把问题彻底
搞清楚。

Hibernate2.0.3的Loader源代码第480行以下:

      代码:
      if (useLimit) sql = dialect.getLimitString(sql);
      PreparedStatement st = session.getBatcher().prepareQueryStatement(sql,
scrollable);

 

如果相应的数据库定义了限定查询记录的sql语句,那么直接使用特定数据库的sql语
句。

然后来看net.sf.hibernate.dialect.MySQLDialect:

      代码:
      public boolean supportsLimit() {
        return true;
      }
      public String getLimitString(String sql) {
        StringBuffer pagingSelect = new StringBuffer(100);
        pagingSelect.append(sql);
        pagingSelect.append(" limit ?, ?");
        return pagingSelect.toString();
      }


这是MySQL的专用分页语句,再来看net.sf.hibernate.dialect.Oracle9Dialect:

      代码:
      public boolean supportsLimit() {
        return true;
      }

      public String getLimitString(String sql) {
        StringBuffer pagingSelect = new StringBuffer(100);
        pagingSelect.append("select * from ( select row_.*, rownum rownum_
from ( ");
        pagingSelect.append(sql);
        pagingSelect.append(" ) row_ where rownum <= ?) where rownum_ > ?");
        return pagingSelect.toString();
      }


Oracle采用嵌套3层的查询语句结合rownum来实现分页,这在Oracle上是最快的方式,
如果只是一层或者两层的查询语句的rownum不能支持order by。

除此之外,Interbase,PostgreSQL,HSQL也支持分页的sql语句,在相应的Dialect里
面,大家自行参考。

如果数据库不支持分页的SQL语句,那么根据在配置文件里面
#hibernate.jdbc.use_scrollable_resultset true
默认是true,如果你不指定为false,那么Hibernate会使用JDBC2.0的scrollable
result来实现分页,看Loader第430行以下:


      代码:
      if ( session.getFactory().useScrollableResultSets() ) {
        // we can go straight to the first required row
        rs.absolute(firstRow);
      }
      else {
        // we need to step through the rows one row at a time (slow)
        for ( int m=0; m<firstRow; m++ ) rs.next();
      }

 

如果支持scrollable result,使用ResultSet的absolute方法直接移到查询起点,如果
不支持的话,使用循环语句,rs.next一点点的移过去。

可见使用Hibernate,在进行查询分页的操作上,是具有非常大的灵活性,Hibernate会
首先尝试用特定数据库的分页sql,如果没用,再尝试Scrollable,如果不行,最后采
用rset.next()移动的办法。

在查询分页代码中使用Hibernate的一大好处是,既兼顾了查询分页的性能,同时又保
证了代码在不同的数据库之间的可移植性。

 

 


==============================================
使用Spring JDBC包装基本的CRUD操作
想起来Spring的JDBC还不错,就拿起来研究了一下,顺便也写了个小例子,希望对初学者有点用处

主要注意以下几点:
1. 对于一些特定的小项目中,很多的工作量都在增删改上,而这些代码当然是惊人地相似,所以对5个简单的
方法抽象了一下,以达到共用的目的
2. 主要文件:applicationContext.xml, BaseDAO.java, BaseDAOImp.java, DAORowMapper.java
3. 在BaseDAOImp.java里有一个Main方法可以做测试
4. DB中只要一个表,表名:users, 三个列:id(int,主键),name(varchar), email(varchar)

这只是一个初稿,后面再做修改再与大家分享

继续阅读 "使用Spring JDBC包装基本的CRUD操作" ?

Posted by kevinwu 03:40 PM | 全文 | 评论 (0) | SPRING(24)

April 12, 2007
Spring+Hibernate 复杂查询分页
/**分页包装类

很简单 :)

*/

package com.xing.cms.model.util;

public class Pager {
 private int totalPages = 0;
 private int totalObjects = 0;
 private int pageNumber = 1;
 private int pageSize = 3;
 private boolean pageAble = true;
 
 private int firstResult;
 

 public void calc(){
  totalPages =  totalObjects % pageSize == 0 ? totalObjects
    / pageSize : totalObjects / pageSize + 1;
 
  firstResult = (pageNumber - 1) * pageSize;
 }
 
 public boolean isPageAble() {
  return pageAble;
 }

 public void setPageAble(boolean pageAble) {
  this.pageAble = pageAble;
 }

 public int getTotalObjects() {
  return totalObjects;
 }

 public void setTotalObjects(int param) {
  this.totalObjects = param;
 }

 public int getTotalPages() {
  return totalPages;
 }

 public void setTotalPages(int param) {
  this.totalPages = param;
 }

 public int getPageNumber() {
  return pageNumber;
 }

 public void setPageNumber(int pageNumber) {
  this.pageNumber = pageNumber;
 }

 public int getPageSize() {
  return pageSize;
 }

 public void setPageSize(int pageSize) {
  this.pageSize = pageSize;
 }
 
 public String toString(){
  return("/ntotalPages:" + totalPages +
  "/ntotalObjects:" + totalObjects +
  "/npageNumber:" + pageNumber +
  "/npageSize:" + pageSize +
  "/npageAble:" + pageAble +
  "/nfirstResult:" + firstResult);
 }

 public int getFirstResult() {
  return firstResult;
 }

 public void setFirstResult(int firstResult) {
  this.firstResult = firstResult;
 }
}

/*UserDao 接口*/

package com.xing.cms.model.dao;

import java.util.List;

import com.xing.cms.model.businessobject.User;
import com.xing.cms.model.util.Pager;

public interface UserDao {
 public abstract boolean save(User model);
 public abstract boolean update(User model);
 public abstract User get(int id);
 public abstract boolean delete(int id);
 public abstract void truncate();
 public abstract boolean delete(int[] id);
 public abstract List<User> find(String[][] searchPara,Pager pager);
 public abstract List<User> find(String[][] searchPara);
}

/*UserDao实现*/

package com.xing.cms.model.dao.impl;

import java.sql.SQLException;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Hibernate;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
//import org.hibernate.criterion.Expression;
import org.hibernate.criterion.Restrictions;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.xing.cms.model.businessobject.User;
import com.xing.cms.model.dao.UserDao;
import com.xing.cms.model.util.GeneralTool;
import com.xing.cms.model.util.Pager;

public class UserDaoImpl extends HibernateDaoSupport implements UserDao {

 private JdbcTemplate jdbcTemplate;// Spring Injection

 public UserDaoImpl() {
  super();
 }

 public JdbcTemplate getJdbcTemplate() {
  return jdbcTemplate;
 }

 public void setJdbcTemplate(JdbcTemplate param) {
  this.jdbcTemplate = param;
 }

 @SuppressWarnings("unchecked")
 public List<User> find(final String[][] searchPara, final Pager pager) {

  return (List<User>) this.getHibernateTemplate().execute(
    new HibernateCallback() {
     public Object doInHibernate(Session session)
       throws SQLException, HibernateException {
      Criteria ca_count = null;
    
      if(pager.isPageAble())
       ca_count = session.createCriteria(User.class);//不能避免,需要查询两次数据库,这个获取总数
    
      Criteria ca = session.createCriteria(User.class);

      if(searchPara != null){
       ca.setProjection(null);
      for (int i = 0; i < searchPara.length; i++) {

       if (searchPara[i][1].equalsIgnoreCase("=")) {
        if(pager.isPageAble())
         ca_count.add(Restrictions.eq(searchPara[i][0], searchPara[i][2]));
        ca.add(Restrictions.eq(searchPara[i][0], searchPara[i][2]));
       } else if (searchPara[i][1].equalsIgnoreCase("like")) {      
        if(pager.isPageAble())
         ca_count.add(Restrictions.like(searchPara[i][0], searchPara[i][2],MatchMode.ANYWHERE));
        ca.add(Restrictions.like(searchPara[i][0], searchPara[i][2],MatchMode.ANYWHERE));
      
       }

      }
      }
 
      List ret_list;

      if (pager.isPageAble()) {

       pager.setTotalObjects(((Integer) (ca_count
         .setProjection(Projections.rowCount())
         .uniqueResult())).intValue()); //获取Count

 
       pager.calc();
     
       ca.addOrder(Order.desc("UID"));
       ca.setFirstResult(pager.getFirstResult());
       ca.setMaxResults(pager.getPageSize());
       ret_list = ca.list();
 
      } else {
       ca.addOrder(Order.desc("UID"));
       ret_list = ca.list();
     
      }

      return ret_list;
     }
    });
 }

// ......其它方法略去

/*测试类*/

package test;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.test.AbstractTransactionalDataSourceSpringContextTests;
import com.xing.cms.model.businessobject.User;
import com.xing.cms.model.dao.DocumentDao;
import com.xing.cms.model.dao.UserDao;
import com.xing.cms.model.util.HtmlGenerator;
import com.xing.cms.model.util.Pager;
import com.xing.cms.model.util.UtilXml;
import com.xing.cms.action.UserAction;

public class TestSpring extends AbstractTransactionalDataSourceSpringContextTests
{
 private Log logger = LogFactory.getLog(TestSpring.class);

 public String[] getConfigLocations() {
  String[] config = new String[]{"applicationContext.xml"};
  return config;
 }


 public void testUserAction() throws Exception{
 
  UserDao dao = (UserDao)applicationContext.getBean("userDao");
  assertTrue(dao!=null);
  User user = (User)applicationContext.getBean("user");
  assertTrue(user!=null);
  Pager pager = (Pager)applicationContext.getBean("pager");
  assertTrue(pager!=null);
  UserAction action = (UserAction)applicationContext.getBean("userAction");
  assertTrue(action!=null);
 
  //clear all first
  dao.truncate();
 
  //super.setComplete();
 
  //add
  for(int i=0;i<20;i++)
  {
   User u = new User();
   u.setGID(1);
   u.setUsername("xzw_"+i);
   u.setPassword("abcd");
   dao.save(u);
  }
 
 
 
  //no pager
 
  /*
  assertEquals(0,dao.find(
    new String[][]{
      new String[]{"username","=","xzw"}
    }
  ).size());
  assertEquals(20,dao.find(null).size());
  */
 
  //with pager
  //action.getPager().setPageSize(9);
  //10 11 12 ... 19 + 1 = 11
 
  /*分页,取第一页,前4 条,应该返回4*/
  action.getPager().setPageSize(4);
  assertEquals(4,dao.find(new String[][]{
    new String[]{"username","like","xzw_1"}
  },action.getPager()).size());

  /*不分页,则取全部的,应该返回20*/
  action.getPager().setPageAble(false);
  action.getPager().setPageSize(4);
  assertEquals(11,dao.find(new String[][]{
    new String[]{"username","like","xzw_1"}
  },action.getPager()).size());

 }
}

Posted by kevinwu 11:33 PM | 全文 | 评论 (0) | SPRING(24)

Spring+hibernate分页查询
/**
     * TOP查询
     *  @param  sql String
     *  @param  top int
     *  @return  List
      */
     public  List findTop(String sql,  int  top) {
      HibernateTemplate ht  =   this .getHibernateTemplate();
      ht.setMaxResults(top);
       return  ht.find(sql);
    }

     /**
     * 分页查询
     *  @param  sql String
     *  @param  firstRow int
     *  @param  maxRow int
     *  @return  List
      */
     public  List findPage( final  String sql, final   int  firstRow, final   int  maxRow) {
       return   this .getHibernateTemplate().executeFind( new  HibernateCallback(){
             public  Object doInHibernate(Session session)  throws  SQLException,
                    HibernateException {
               Query q  =  session.createQuery(sql);
               q.setFirstResult(firstRow);
               q.setMaxResults(maxRow);
                return  q.list();
               }
        });     
    }

模板实现分页:
public   List find(  final   String hsql,   final     int   firstRow,   final     int   maxRow)   throws         Exception {
   return  getHibernateTemplate().executeFind( new  HibernateCallback() {
     public  Object doInHibernate(Session s)  throws  HibernateException, SQLException {
           Query query  =  s.createQuery(hsql);
           query.setFirstResult(firstRow);
           query.setMaxResults(maxRow);
           List list  =  query.list();
           return  list;
           }
     });
}

Posted by kevinwu 11:31 PM | 全文 | 评论 (0) | SPRING(24)

hibernate+spring的一个简单分页实现
Spring DAO的编写:
利用hibernate提供的Query的setFirstResult和setMaxResults方法进行数据分页,程序中以我建立的用户表为例,query的分页机制是以跳指针的方式进行数据读取,这样极大的提高的数据分页程序的响应速度
//分页主程序
       public List getUsersPage(int firstResults,int maxResults){
              try {
                     Session session=this.getSession();
                     Query query=session.createQuery("from SYSUSERS sysusers order by sysusers.username asc");
                     query.setFirstResult(firstResults);
                     query.setMaxResults(maxResults);
                     return query.list();
              } catch (HibernateException e) {
                     // TODO 自动生成 catch 块
                     e.printStackTrace();
              }
              finally{
                     try {
                            session.close();
                     } catch (HibernateException e) {
                            // TODO 自动生成 catch 块
                            e.printStackTrace();
                     }
              }
              return null;
       }
       //显示分页总页数
       public String getPageCount(int maxResults){
              String pageCount="0";
              try {
                     session=this.getSession();
                     Query query=session.createQuery("select count(sysusers.id) from SYSUSERS sysusers");
                     int Count=((Integer)query.list().get(0)).intValue();
                     if(Count%maxResults>0){
                            pageCount=String.valueOf(Count/maxResults+1);
                     }
                     else{
                            pageCount=String.valueOf(Count/maxResults);
                     }
                     return String.valueOf(pageCount);
              } catch (HibernateException e) {
                     // TODO 自动生成 catch 块
                     e.printStackTrace();
              }
              finally{
                     try {
                            session.close();
                     } catch (HibernateException e) {
                            // TODO 自动生成 catch 块
                            e.printStackTrace();
                     }
              }
              return pageCount;
       }
       //显示总记录数
       public String getTotalMark(){
              String totalMark="0";
              try {
                     session=this.getSession();
                     Query query=session.createQuery("select count(sysusers.id) from SYSUSERS sysusers");
                     int Count=((Integer)query.list().get(0)).intValue();
                     totalMark=String.valueOf(Count);
                     return totalMark;
              } catch (HibernateException e) {
                     // TODO 自动生成 catch 块
                     e.printStackTrace();
              }
              finally{
                     try {
                            session.close();
                     } catch (HibernateException e) {
                            // TODO 自动生成 catch 块
                            e.printStackTrace();
                     }
              }
              return totalMark;
       }
 
写完spring的dao之后定义相应的接口,这里不在复述
在这个dao写好之后,就可以在相应的表示层中进行方法调用,达到分页的目的 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Hibernate分页是指在使用Hibernate进行数据库查询时,将查询结果按照一定的规则进行分页显示的操作。有几种常见的方法可以实现Hibernate分页。 一种常见的方法是使用HQL(Hibernate Query Language)和setFirstResult、setMaxResults API进行分页。通过设置setFirstResult方法指定查询结果的起始位置,通过setMaxResults方法指定每页显示的记录数,从而实现分页效果。例如,使用HQL查询语句"From Foo",然后使用setFirstResult(0)和setMaxResults(10)方法,可以获取第一页的10条记录。\[1\] 另一种方法是使用ScrollableResults API进行分页。ScrollableResults API提供了对查询结果集的滚动访问,可以通过设置setFirstResult方法和next方法来实现分页效果。具体的实现方式可以参考Hibernate的官方文档。\[1\] 在Hibernate中进行分页的最简单和最常见的方法是使用HQL。通过创建一个Query对象,设置查询语句和分页参数,然后调用list方法获取查询结果的列表。例如,使用HQL查询语句"From Foo",然后使用setFirstResult(0)和setMaxResults(10)方法,可以获取第一页的10条记录。\[3\] 总之,Hibernate提供了多种方法来实现分页功能,开发人员可以根据具体的需求选择合适的方法来进行分页操作。 #### 引用[.reference_title] - *1* *2* *3* [Hibernate 分页](https://blog.csdn.net/allway2/article/details/128102203)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值