query.scroll()和query.setFirstResult(),query.setMaxResults();

一、说明:query.scroll()和query.setFirstResult(),query.setMaxResults();

  这两种方法都可以取到一定范围内的数据,用来数据分页显示。那么两者区别,以及两者的效率如何? 
  1.scroll是用JDBC2.0的可滚动结果集实现;query.setMaxResults();query.setFirstResult()是数据库SQL语句实现。 
  2.你说是在数据库就分页好呢?还是把结果集都取到内存再分页好呢?(应该是在数据库就分了好些吧,但是如果在内存分页的话,换页的时候是不是更快一些呢?) 
  3.在数据库进行分页是首选的方式。数据库分页实际上是利用数据库本身SQL扩展的功能进行分页,例如MySQL的 limit 0,50这样的SQL语句。不但速度快,而且非常节省内存。不过不   是每种数据库的都有这种分页支持的SQL,例如SQL Server就不支持。 
  4.scroll是利用JDBC2.0的功能做分页的,那么就完全取决于特定数据库的JDBC Driver的实现了。事实上大部分JDBC Driver都是把所有的结果集都一次取到内存,然后再分页的。如果这个结果集非常大,例如几万条,不但程序执行速度会很慢,而且很容易导致out of memory。当然个别JDBC Driver使用了服务器端游标来实现,那么就不会导致这种问题,例如jTDS。 

二、Hibernate可以使用Query.setMaxResults方法简单地设置需要查询的最大结果集。 
  然后Hibernate会自动根据所设置的数据库方言翻译成相应的SQL语句提交给数据库。比如如果数据库是Oracle,SQL Server等,则翻译为类似select ... top 10之类的SQL语句,若是MySQL,则翻译为select ... limit 10之类的SQL。 

三、举例: 
  query.setFirstResult(0),query.setMaxResults(4);相当于MySQL中的limit 0, 4;

代码
public void testQuery() {
  Session session = null;
  try {
    session = HibernateUtils.getSession();
    session.beginTransaction();
    Query query = session.createQuery("from User");
    query.setFirstResult(0);//从第一条记录开始
    query.setMaxResults(4);//取出四条记录
    List userList = query.list();
    for (Iterator iter=userList.iterator(); iter.hasNext();) {
      User user = (User)iter.next();
      System.out.println(user.getId());
      System.out.println(user.getName());
    }
    session.getTransaction().commit();
  }catch(Exception e) {
    e.printStackTrace();
    session.getTransaction().rollback();
  }finally {
    HibernateUtils.closeSession(session);
  }
}


自己测试: 
HQL: 
      String hql =" from NumberBiz biz where biz.numberDepot.status=?" ; 
     Object[] values = {Constants.NUM_STATUS_NOT_AVAILABLE}; 
     NumberBiz numberBiz = (NumberBiz)this.createQuery(session,hql,values).setFirstResult(0).setMaxResults(1).uniqueResult(); 

console view show_sql: 

    select 
        * 
    from 
        ( select 
            numberbiz0_.id as id83_, 
            numberbiz0_.create_date as create2_83_, 
            numberbiz0_.create_by as create3_83_, 
            numberbiz0_.last_update_date as last4_83_, 
            numberbiz0_.last_update_by as last5_83_, 
            numberbiz0_.deleted as deleted83_, 
            numberbiz0_.addon_services as addon7_83_, 
            numberbiz0_.first_three_digits as first8_83_, 
            numberbiz0_.is_recommended as is9_83_, 
            numberbiz0_.last_four_digits as last10_83_, 
            numberbiz0_.middle_four_digits as middle11_83_, 
            numberbiz0_.minimum_expenses_per_month as minimum12_83_, 
            numberbiz0_.num_type as num13_83_, 
            numberbiz0_.num as num83_, 
            numberbiz0_.number_biz_group_id as number19_83_, 
            numberbiz0_.number_brands as number15_83_, 
            numberbiz0_.number_depot_id as number20_83_, 
            numberbiz0_.number_packages as number16_83_, 
            numberbiz0_.pre_pay as pre17_83_, 
            numberbiz0_.price as price83_ 
        from 
            number_biz numberbiz0_, 
            number_depot numberdepo1_ 
        where 
            numberbiz0_.number_depot_id=numberdepo1_.id 
            and numberdepo1_.status=? 
            ) 
    where 
        rownum <= ? 
### Java 分页查询实现方法 #### 使用 MyBatis 实现分页查询 在 MyBatis 中,可以通过 `RowBounds` 类来轻松实现分页功能。此对象接受两个参数:偏移量每页记录数。 ```java // 创建 RowBounds 对象 (offset, limit) RowBounds rowBounds = new RowBounds(pageNum * pageSize, pageSize); // 执行带分页的查询 List<User> users = sqlSession.selectList("selectUsers", null, rowBounds); ``` 对于更复杂的场景,推荐使用插件 PageHelper[^3]。 #### 基于 Hibernate 的分页解决方案 当采用 Hibernate 进行开发时,则可以利用其内置 API 完成分页逻辑: ```java Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); Query query = session.createQuery(hqlString); query.setFirstResult((currentPage - 1) * pageSize); // 设置起始位置 query.setMaxResults(pageSize); // 设定最大返回条目数量 List results = query.list(); // 获取结果集 tx.commit(); session.close(); ``` 上述代码片段展示了如何通过设置查询的第一项索引(`setFirstResult`) 限制获取的最大数目 (`setMaxResults`) 来完成分页操作[^1]。 #### Elasticsearch 分页机制 Elasticsearch 提供了两种主要的方式来进行深分页——from/size 参数组合与 scroll API 。为了优化性能并减少内存占用,建议仅请求必要的字段 `_source`, `_id` 及排序依据 `_score`. ```json GET /_search?scroll=1m { "size": 10, "_source": ["title"], "sort": [ {"date": "desc"} ] } ``` 这种方法适用于大数据量情况下的高效检索需求[^4].
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值