`
volunteer521
  • 浏览: 205694 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

【整理】Hibernate分页原理简单分析

阅读更多

【背景说明】

面试时曾被问得不知所以然,故收集整理之。

 

【使用概览】整理自:Hibernate分页查询经典实例总结

通常使用的Hibernate查询是三种:hql查询,QBC查询和QBE查询。 

 

1QBEQurey By Example)检索方式

 

      QBE是最简单的,但是功能也是最弱的,QBE的功能不是特别强大,仅在某些场合下有用。一个典型的使用场合就是在查询窗口中让用户输入一系列的查询条件,然后返回匹配的对象。QBE只支持=like比较运算符,无法不大区间值,及其或的匹配。在这种情况下,还是采用HQL检索方式或QBC检索方式。
 

2QBCQurey By Criteria)检索方式 

      
采用HQL检索方式时,在应用程序中需要定义基于字符串形式的HQL查询语句。QBC API提供了检索对象的另一种方式,它主要由Criteria接口、Criterion接口和Restrictions接口组成,它支持在运行时动态生成 查询语句。比较常见的是两种传参方式:一种是用map传参,另一种是用Criterion…不定参数传参。

 

 

3、HQLHibernate Query Language检索方式 

      HQL
是面向对象的查询语言,它和SQL查询语言有些相识。在Hibernate提供的各种检索方式中,HQL是使用最广的一种检索方式。

 

 

------------------------------------------------------------华丽的分割线---------------------------------------------------

 

 

【原理分析】整理自:关于java中的Hibernate分页管理简单分析

      以下向大家介绍Hibernate分页,Hibernate中,通过对不同数据库的统一接口设计,实现了透明化、通用化的分页实现机制。

 

      通过Criteria.setFirstResult和Criteria.setFetchSize方法设定分页范围,如: 

Criteria criteria = session.createCriteria(TUser.class);
criteria.add(Expression.eq("age", "20"));  //从检索结果中获取第100条记录开始的20条记录
criteria.setFirstResult(100);
criteria.setFetchSize(20);

 

      通过Query.setFirstResult和Query.setMaxResults方法也可以设定分页范围,如: 

Query query = session.createQuery("from TUser");
query.setFirstResult(100);
query.setMaxResults(20);  // query.setFetchSize(20);
List list = query.list();

 

      Hibernate中,抽象类org.hibernate.dialect.Dialect指定了所有底层数据库的对外统一接口,通过针对不同数据库提供相应的Dialect实现,数据库之间的差异性得以消除,从而为上层机制提供了透明的、数据库无关的存储层基础。对于分页机制而言,Dialect中定义了一个方法如下: 

/**    * Add a LIMIT clause to the given SQL SELECT    *    * @return the modified SQL    */
  public String getLimitString(String querySelect, boolean hasOffset))
  {    
    throw new UnsupportedOperationException( "paged queries not supported" ); 
  }

  public String getLimitString(String querySelect, int offset, int limit)
  {    
    return getLimitString( querySelect, offset>0 );   
  }

 

      此方法用于在现有Select语句基础上,根据各个数据库自身特性,构造对应的记录返回限定子句。如MySQL中对应的记录限定子句为Limit,Oracle中,通过rownum子句实现。

 

      MySQLDialect中的getLimitString实现:

  public String getLimitString(String sql, boolean hasOffset)
  {    
    return new StringBuffer( sql.length()+20 ).append(sql).append( hasOffset ? " limit ?, ?" : " limit ?").toString();   
  }

      MySQLDialect.getLimitString方法的实现实际上是在给定的Select语句后追加MySQL所提供的专有SQL子句limit来实现。

 

      Oracle9Dialect中的getLimitString实现: 

  public String getLimitString(String sql, boolean hasOffset)
  {
    sqlsql = sql.trim();
    boolean isForUpdate = false;
    if ( sql.toLowerCase().endsWith(" for update") )
    {
      sqlsql = sql.substring( 0, sql.length()-11 );
      isForUpdate = true;
    }
    
    StringBuffer pagingSelect = new StringBuffer( sql.length()+100 );
    if (hasOffset)
    {
      pagingSelect.append("select * from ( select row_.*, rownum rownum_ from ( ");
    }
    else
    {
      pagingSelect.append("select * from ( ");    
    }
    
    pagingSelect.append(sql);
    if (hasOffset)
    {
      pagingSelect.append(" ) row_ where rownum <= ?) where rownum_ > ?");
    }
    else
    {
      pagingSelect.append(" ) where rownum <= ?");
    }
    
    if ( isForUpdate )
    {
      pagingSelect.append( " for update" );
    }
    
    return pagingSelect.toString();
  }

      通过Oracle特有的rownum子句来实现数据部分的读取。

 

      SQLServerDialect中的getLimitString实现:

  public String getLimitString(String querySelect, int offset, int limit)
  {
    if ( offset > 0 )
    {
      throw new UnsupportedOperationException( "sql server has no offset" );
    }
    
    return new StringBuffer( querySelect.length()+8 ).append(querySelect).insert( getAfterSelectInsertPoint(querySelect), " top " + limit ).toString();
  }

       通过SQLServer特有的top子句实现。

 

      HSQLDialect中的getLimitString实现:

  public String getLimitString(String sql, boolean hasOffset)
  {
    return new StringBuffer( sql.length() + 10 ).append( sql ).insert( sql.toLowerCase().indexOf( "select" ) + 6, hasOffset ? " limit ? ?" : " top ?" ).toString();   
  }

 

      大多数主流数据库都提供了数据部分读取机制,而对于某些没有提供相应机制的数据库而言,Hibernate也通过其他途径实现了分页,如通过Scrollable ResultSet,如果JDBC不支持Scrollable ResultSet,Hibernate也会通过ResultSet的next方法进行记录定位。Hibernate通过底层对分页机制的良好封装,使得开发人员无需关心数据分页的细节实现,将数据逻辑和存储逻辑分离开来,在提高生产效率的同时,也大大加强了系统在不同数据库平台之间的可移植性。

 

 

好了,hibernate的分页原理整理到这,欢迎补充:)睡觉~~

 

PS:还有一个网上转载比较多的是robbin的老帖子Hibernate实现分页查询的原理分析,有兴趣的可以看看:)

 

分享到:
评论

相关推荐

    Hibernate入门.rar

    【Hibernate入门】是一个针对初学者精心整理的教程资源包,旨在帮助新手快速理解并掌握Java持久化框架Hibernate的核心概念和使用方法。这个压缩包包含了所有你需要开始Hibernate学习的基础材料。 Hibernate是一个...

    MyBatis常见实用面试题整理.docx

    - **分页插件原理**:通过实现Mybatis提供的接口,编写自定义插件,并在插件的拦截方法中拦截待执行的SQL语句,然后修改SQL语句以实现分页功能。例如,将`SELECT * FROM student`重写为`SELECT t.* FROM (SELECT * ...

    1000道 互联网Java架构师面试题.pdf和JAVA核心知识整理.zip

    分页插件的原理是什么? 11、Mybatis 是如何将 sql 执行结果封装为目标对象并返回的?都有哪些映射形式? 12、如何执行批量插入? 13、如何获取自动生成的(主)键值? 14、在 mapper 中如何传递多个参数? 15、...

    ssh面试题 txt文档

    根据提供的文件信息,我们可以整理出以下关于SSH(Struts + Spring + Hibernate)框架的重要知识点: ### 1. Hibernate 的基本操作流程 - **获取配置文件**:首先需要加载配置文件,通常为`hibernate.cfg.xml`。 -...

    struts2整理文档

    分页原理简介** - **核心概念**: - 分页处理的关键在于如何确定每页显示的数据数量以及如何根据用户请求加载相应的数据。 - 常见的分页属性包括:`pagesize`(每页显示的数据条数)、`currentpageNo`(当前页码...

    Java学习笔记-个人整理的

    {1.4.1.1}浮点数原理}{24}{subsubsection.1.4.1.1} {1.4.2}格式化输出浮点数}{24}{subsection.1.4.2} {1.4.3}\texttt {char}}{24}{subsection.1.4.3} {1.4.4}转义字符}{25}{subsection.1.4.4} {1.4.5}Boolean ...

    Java开发面试题整理含答案(计网、Java、操作系统、数据库、框架)

    面试时,面试官可能会让你编写复杂的SQL查询,分析查询效率,或者讨论数据库设计模式,如范式理论和数据库优化策略。 五、框架 Java开发中常见的框架有Spring、MyBatis、Hibernate等,掌握它们的核心功能和使用方法...

    自整理Java关于基础和框架的面试题

    ### 自整理Java关于基础和框架的面试题 #### 基础知识点 ##### JDK常用的包 - **java.lang**: 包含所有基本类,如`String`、`Math`等。 - **java.util**: 提供集合框架、日期/时间设施、事件模型、杂项实用程序类...

    全套Java、Android、HTML5前端视频教程

    以上是根据所提供的文件信息整理出的主要知识点概览,这些教程覆盖了从Java基础到Java Web再到Java EE等多个层面的技术内容,适合不同水平的学习者进行学习和参考。通过这些教程的学习,不仅可以掌握Java编程的基础...

    2021最新Java程序员面试题

    - 分页原理:通过拦截器来实现分页查询。 - 结果封装:通过映射器文件中的resultMap进行结果封装。 - 批量插入:使用foreach标签。 - 获取自动生成的键值:使用useGeneratedKeys和keyProperty。 - 传递多个参数...

    基于J2EE框架的个人博客系统项目毕业设计论文(源码和论文)

    而越来越多专业知识的 Blog 的出现,让我们看到了 Blog 更多所蕴涵的巨大的信息价值:不同的 Blog 选择不同的内容,收集和整理成为很多人关注的专业 Blog ——目前越来越多的人获取信息的来源是一些固定的 Blog 。...

    java学习资源连接

    - **简介**: 分享了一个使用Hibernate、Spring和Struts2进行整合开发的分页显示方案。 - **特点**: 实战性强,适合进行Web应用开发的开发者。 - **Java视频教程与书籍** - **传智播客Java视频教程** - **来源*...

    心得.rar心得.rar

    这些文档可能是作者在学习或实践中整理的笔记,涵盖了从基础到进阶的Java知识,以及一些程序员的生活习惯和工具使用经验。 【标签】"心得.rar"进一步确认了这是一个关于Java技术的学习资料集合。 根据【压缩包子...

    新闻管理系统

    新闻管理系统是一种基于软件工程原理构建的信息发布和管理平台,它主要负责收集、整理、存储、检索和发布新闻信息。在本系统中,我们采用的是MVC(Model-View-Controller)设计模式,这是一种广泛用于Web应用程序...

    1000道互联网Java工程师面试题485页.pdf

    该文档整理了大量知识点和面试题,适合准备面试的Java工程师深入学习和复习。 ### MyBatis知识点总结 1. **MyBatis概念**:MyBatis是一个优秀的持久层框架,它支持定制化SQL、存储过程以及高级映射。 2. **...

    1000道 互联网Java工程师面试题 485页_PDF密码解除.pdf

    以下是按照文件内容整理出的知识点: ### MyBatis知识点 1. **MyBatis概述**: MyBatis 是一个支持定制化 SQL、存储过程以及高级映射的持久层框架。它避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。 ...

Global site tag (gtag.js) - Google Analytics