hibernate分页实现

    技术2025-06-22  19

    解决项目中一问题时, 由于涉及到Hibernate的分页功能, 于是打草兔子地研究了下Hibernate分页功能的实现。

     

    我们先来看用Hibernate来实现分页的代码片段:

           Criteria c = session.createCriteria(Area.class);

          

           c.setFirstResult(10);

           c.setMaxResults(20);

          

           List list = c.list();

     

    上面c.list()执行后,就看到了满足条件的十条记录,即第1120这十条。

     

    那么在Hibernate内部这是怎么实现的呢?

     

    截下了Hibernate生成的sql(如何截,请见另一篇博文:Hibernate初始化时如何生成SQL语句?),它是这样的:

        select a.* from

     

    (

      select row_.*, rownum rownum_ from

      ( select this_.id as id0_0_, this_.ALIAS_ID as ALIAS2_0_0_, this_.COMM as COMM0_0_, this_.CREATE_TIME as CREATE4_0_0_, this_.NAME as NAME0_0_ from AREA this_ ) row_

      where rownum <= 20

    )  a

     

    where a.rownum_ > 10

        注:为了下文说明方便,上面sql是我又加了些东东,如a和参数(1020)。

    那么这个sql是怎么生成的呢?

    Debug过程中,经历了超人般的跨越后,最终在org.hibernate.dialect.Oracle9Dialect中的getLimitString方法中,看到了整个sql的组装过程。

     

     

    源码就不粘在这了, 看它的原理,发现它巧妙地利用了Oracle数据中的伪列rownum  

     

    这里的sql有两个临时表 row_ a

    l  第一个表row_里包含了满足条件的所有结果, 可能是1000条。

    l  第二个表a,这里利用Oracle的伪列rownum 取前20条, 并把这个伪列rownum(临时值)作为表a的一个真正存在的列保存下来, 这样就能光明正大地用a.rownum_ > 10过滤条件了。

     

     

    至此,解释并记录完毕, 收队!

    在数据库中用来数据库分页的几点:

    oracle可以用伪列rownum来记录记录的行数 ;

    mysql可以用limit来区分记录从第几条到第几条的记录 ;

    sqlserver可以用top来区分记录的行数 ;

     

    最新回复(0)