`
snoopy7713
  • 浏览: 1152316 次
  • 性别: Icon_minigender_2
  • 来自: 火星郊区
博客专栏
Group-logo
OSGi
浏览量:0
社区版块
存档分类
最新评论

Mybatis使用篇之十二:实现物理分页

阅读更多

Mybatis的自带分页方法只是逻辑分页,如果数据量很大,内存会溢出,不知道为什么开源组织不在里面实现类似Hibernate的物理分页处理方法。在不改动Mybatis源代码的情况下,怎么使Mybatis支持物理分页呢?下面我们来看看。

 

(1)新建一个Java类Dialect.java,该类的内容如下:

Java代码  收藏代码
  1. package  org.mybatis.extend.interceptor;  
  2.   
  3. public   abstract   class  Dialect {  
  4.   
  5.     public   static   enum  Type{  
  6.         MYSQL,  
  7.         ORACLE  
  8.     }  
  9.       
  10.     public   abstract  String getLimitString(String sql,  int  skipResults,  int  maxResults);  
  11.       
  12. }  

 

 

(2)新建一个Java类OracleDialect.java,该类继承Dialect 类,具体的内容如下:

Java代码  收藏代码
  1. package  org.mybatis.extend.interceptor;  
  2.   
  3. public   class  OracleDialect  extends  Dialect{  
  4.   
  5.     /* (non-Javadoc)  
  6.      * @see org.mybatis.extend.interceptor.IDialect#getLimitString(java.lang.String, int, int)  
  7.      */   
  8.     @Override   
  9.     public  String getLimitString(String sql,  int  offset,  int  limit) {  
  10.   
  11.         sql = sql.trim();  
  12.         StringBuffer pagingSelect = new  StringBuffer(sql.length() +  100 );  
  13.           
  14.         pagingSelect.append("select * from ( select row_.*, rownum rownum_ from ( " );  
  15.           
  16.         pagingSelect.append(sql);  
  17.           
  18.         pagingSelect.append(" ) row_ ) where rownum_ > " ).append(offset).append( " and rownum_ <= " ).append(offset + limit);  
  19.           
  20.         return  pagingSelect.toString();  
  21.     }  
  22.   
  23. }  

 

(3)新建一个Mybaits的拦截器PaginationInterceptor.java,实现Interceptor接口,该类的内容如下:

Java代码  收藏代码
  1. package  org.mybatis.extend.interceptor;  
  2.   
  3. import  java.sql.Connection;  
  4. import  java.util.Map;  
  5. import  java.util.Properties;  
  6.   
  7. import  org.apache.ibatis.executor.parameter.DefaultParameterHandler;  
  8. import  org.apache.ibatis.executor.statement.StatementHandler;  
  9. import  org.apache.ibatis.mapping.BoundSql;  
  10. import  org.apache.ibatis.plugin.Interceptor;  
  11. import  org.apache.ibatis.plugin.Intercepts;  
  12. import  org.apache.ibatis.plugin.Invocation;  
  13. import  org.apache.ibatis.plugin.Plugin;  
  14. import  org.apache.ibatis.plugin.Signature;  
  15. import  org.apache.ibatis.reflection.MetaObject;  
  16. import  org.apache.ibatis.session.Configuration;  
  17. import  org.apache.ibatis.session.RowBounds;  
  18. import  org.slf4j.Logger;  
  19. import  org.slf4j.LoggerFactory;  
  20.   
  21.   
  22. @Intercepts ({ @Signature (type=StatementHandler. class ,method= "prepare" ,args={Connection. class })})  
  23. public   class  PaginationInterceptor  implements  Interceptor {  
  24.     //日志对象   
  25.     protected   static  Logger log = LoggerFactory.getLogger(PaginationInterceptor. class );  
  26.     /* (non-Javadoc)  
  27.      * @see org.apache.ibatis.plugin.Interceptor#intercept(org.apache.ibatis.plugin.Invocation)  
  28.      */   
  29.     @Override   
  30.     public  Object intercept(Invocation invocation)  throws  Throwable {  
  31.         StatementHandler statementHandler = (StatementHandler)invocation.getTarget();  
  32.         MetaObject metaStatementHandler = MetaObject.forObject(statementHandler);  
  33.           
  34.         RowBounds rowBounds = (RowBounds)metaStatementHandler.getValue("delegate.rowBounds" );  
  35.         if (rowBounds ==  null  || rowBounds == RowBounds.DEFAULT){  
  36.             return  invocation.proceed();  
  37.         }  
  38.           
  39.         DefaultParameterHandler defaultParameterHandler = (DefaultParameterHandler)metaStatementHandler.getValue("delegate.parameterHandler" );  
  40.         Map parameterMap = (Map)defaultParameterHandler.getParameterObject();  
  41.         Object sidx = parameterMap.get("_sidx" );  
  42.         Object sord = parameterMap.get("_sord" );  
  43.           
  44.         String originalSql = (String)metaStatementHandler.getValue("delegate.boundSql.sql" );  
  45.           
  46.         if (sidx !=  null  && sord !=  null ){  
  47.             originalSql = originalSql + " order by "  + sidx +  " "  + sord;  
  48.         }  
  49.           
  50.         Configuration configuration = (Configuration)metaStatementHandler.getValue("delegate.configuration" );  
  51.           
  52.                             Dialect.Type databaseType  = null ;  
  53.         try {  
  54.             databaseType = Dialect.Type.valueOf(configuration.getVariables().getProperty("dialect" ).toUpperCase());  
  55.         } catch (Exception e){  
  56.             //ignore   
  57.         }  
  58.         if (databaseType ==  null ){  
  59.             throw   new  RuntimeException( "the value of the dialect property in configuration.xml is not defined : "  + configuration.getVariables().getProperty( "dialect" ));  
  60.         }  
  61.         Dialect dialect = null ;  
  62.         switch (databaseType){  
  63.             case  ORACLE:  
  64.                 dialect = new  OracleDialect();  
  65.                 break ;  
  66.             case  MYSQL: //需要实现MySQL的分页逻辑   
  67.                 break ;  
  68.                   
  69.         }  
  70.           
  71.           
  72.         metaStatementHandler.setValue("delegate.boundSql.sql" , dialect.getLimitString(originalSql, rowBounds.getOffset(), rowBounds.getLimit()) );  
  73.         metaStatementHandler.setValue("delegate.rowBounds.offset" , RowBounds.NO_ROW_OFFSET );  
  74.         metaStatementHandler.setValue("delegate.rowBounds.limit" , RowBounds.NO_ROW_LIMIT );  
  75.         if (log.isDebugEnabled()){  
  76.             BoundSql boundSql = statementHandler.getBoundSql();  
  77.             log.debug("生成分页SQL : "  + boundSql.getSql());  
  78.         }  
  79.         return  invocation.proceed();  
  80.     }  
  81.   
  82.     /* (non-Javadoc)  
  83.      * @see org.apache.ibatis.plugin.Interceptor#plugin(java.lang.Object)  
  84.      */   
  85.     @Override   
  86.     public  Object plugin(Object target) {  
  87.         return  Plugin.wrap(target,  this );  
  88.     }  
  89.   
  90.     /* (non-Javadoc)  
  91.      * @see org.apache.ibatis.plugin.Interceptor#setProperties(java.util.Properties)  
  92.      */   
  93.     @Override   
  94.     public   void  setProperties(Properties arg0) {  
  95.         // TODO Auto-generated method stub   
  96.           
  97.     }  
  98.   
  99. }  

 

 (4)将Mybatis的拦截器配置到Mybatis的全局配置文件(mybatis.cfg.xml)中,具体如下:

Java代码  收藏代码
  1. <?xml version= "1.0"  encoding= "UTF-8"  ?>  
  2.   
  3. <!DOCTYPE configuration PUBLIC   
  4.     "-//mybatis.org//DTD Config 3.0//EN"   
  5.     "http://mybatis.org/dtd/mybatis-3-config.dtd" >  
  6.   
  7. <configuration>  
  8.     <properties>  
  9.               <property name="dialect"  value= "oracle" />  
  10.     </properties>  
  11.           
  12.     <plugins>  
  13.             <plugin interceptor="org.mybatis.extend.interceptor.PaginationInterceptor" />  
  14.     </plugins>  
  15.          
  16. </configuration>  

 

(5)使用方法同Mybatis逻辑分页一样,拦截器会自动拦截执行SQL的地方,加上分页代码:

Java代码  收藏代码
  1. getSqlSession().selectList(sqlId, paramMap, new  RowBounds(pageId, pageSize)); 
分享到:
评论

相关推荐

    mybatis分页配置

    1. **基于插件的分页**:MyBatis 提供了一个 PageHelper 插件,它可以方便地实现物理分页。首先,你需要在 Maven 或 Gradle 的依赖中添加 PageHelper 的依赖,然后在 MyBatis 的配置文件中启用该插件。PageHelper ...

    springmybatis

    mybatis实战教程mybatis in action之七实现mybatis分页源码下载 mybatis实战教程mybatis in action之八mybatis 动态sql语句 mybatis实战教程mybatis in action之九mybatis 代码生成工具的使用 mybatis ...

    【Java-框架-Mybatis】(01) - 文件

    - 分页查询:通过设置RowBounds对象实现物理分页,或者使用Mybatis Plus等扩展库进行更复杂的分页。 - 复杂查询:利用Mybatis的动态SQL,可以轻松处理复杂条件的查询。 总结,Mybatis作为一款优秀的Java持久层...

    mybatis_plus

    4. 分页查询:内建的分页插件实现了物理分页和逻辑分页,支持多种数据库,且配置简单。 5. CRUD操作:提供了基本的增删改查接口,只需继承BaseMapper,即可一键生成对应的Mapper和XML文件。 三、主要功能 1. CRUD...

    实现分页查询(上)

    2. 物理分页:将数据预先分割成固定大小的页存储,每次请求时直接读取指定页的数据,适用于数据量极大且频繁访问的情况。 3. 记录数分页:先查询总记录数,然后计算出总页数,再根据页码获取数据,适用于数据量较小...

    java逻辑分页

    逻辑分页不同于物理分页,物理分页是在数据库层面进行数据切片,而逻辑分页则是在应用程序层面上实现,通常通过查询全部数据并按需显示每一页的数据。 这篇博客“java逻辑分页”可能详细介绍了如何在Java应用中实现...

    java分页例子

    1. 使用SQL语句实现分页:最直接的方法是在SQL查询语句中添加LIMIT和OFFSET关键字(MySQL),或者使用ROW_NUMBER()函数配合子查询(如Oracle、SQL Server)。例如: ```sql SELECT * FROM (SELECT ROW_NUMBER() ...

    基于SSM ( Spring + SpringMVC + Mybatis)开发的知识问答社区+源代码+文档说明

    数据的物理分页使用的是开源项目Mybatis-Page-Helper ,也是非常的轻量和易于引入。hibernate-validator的数据实体验证也使得参数的验证变得简单了起来。随着不停的实现与增加功能,引入的东西也变得丰富了起来。 #...

    MybatisPlus使用实战,MybatisPlus简介和使用示例

    这篇文章将深入探讨MybatisPlus的基本概念、核心特性以及使用示例,帮助开发者更好地理解和运用这个工具。 一、MybatisPlus简介 MybatisPlus是由百度开源的一个轻量级框架,它的主要目标是简化Mybatis的常规操作,...

    SpringbootMybatisPlusPractice

    3. **分页查询**:Mybatis Plus内置了分页插件,只需传入Page对象即可实现分页查询,支持多种数据库的分页方式。 4. **填充公共字段**:通过`@TableField(fill = FieldFill.INSERT)`或`@TableField(fill = ...

    java面试知识

    - 或使用WITH子句配合RANK()函数实现更复杂的分页逻辑。 ##### Oracle的基本数据类型 - **NUMBER**:数值类型。 - **VARCHAR2**:可变长度字符串。 - **DATE**:日期类型。 - **TIMESTAMP**:精确到毫秒的时间戳。...

    SingleMall-项目环境搭建-前后端分离-图灵杨过1

    PageHelper是MyBatis的物理分页插件,有助于提高查询性能。此外,项目还利用Swagger-UI生成API文档,方便接口的管理和测试。搜索引擎Elasticsearch用于提供高效的搜索功能,RabbitMQ处理消息队列,实现异步通信。...

Global site tag (gtag.js) - Google Analytics