`
kobe学java
  • 浏览: 258360 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类
最新评论

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));  

 

分享到:
评论
1 楼 azrael6619 2012-06-13  
Object sidx = parameterMap.get("_sidx");  
Object sord = parameterMap.get("_sord"); 
这两个参数是哪里放进去的?

相关推荐

    mybatis物理分页插件

    而“mybatis物理分页插件”是针对MyBatis设计的一个扩展,用于解决在大数据量查询时的性能问题,通过实现物理分页来避免内存溢出。 物理分页是指在数据库层面进行分页,相比于逻辑分页(在应用层进行数据截取),...

    mybatis 物理分页,借助于mybatis-paginator插件

    总结来说,`mybatis-paginator`是一个强大且实用的工具,它帮助开发者在MyBatis中轻松实现物理分页,提高大数据查询的效率。通过学习和使用这个插件,你可以更深入地理解数据库分页原理,并提升你的项目性能。同时,...

    mybatis3 物理分页源代码

    本主题将深入探讨Mybatis3中如何实现物理分页,特别是通过拦截器来实现这一功能。 首先,我们来看Interceptor接口。在Mybatis中,拦截器扮演着关键角色,它允许我们在特定的执行点(如SQL语句的准备、执行等)插入...

    Spring集成MyBatis 通用Mapper以及 pagehelper分页插件

    通用Mapper通过动态代理技术实现了方法的自动映射,只需要定义Mapper接口,无需编写XML,即可实现对数据库的基本操作。 PageHelper是另一个MyBatis的分页插件,它提供了强大的分页功能,可以无缝地与MyBatis和...

    mybatis mysql分页实例(不能用找我)

    在MySQL中,我们通常使用LIMIT和OFFSET关键字来实现物理分页,LIMIT用于指定每页显示的记录数,OFFSET则用来偏移起始位置。 在MyBatis中实现分页,我们需要以下步骤: 1. **配置MyBatis**:确保你的项目已经集成了...

    修改ibatis源代码实现物理分页

    综上所述,修改Ibatis源代码实现物理分页涉及的关键技术包括动态SQL、自定义插件、数据库方言处理以及性能优化。通过这样的改造,我们可以充分利用数据库的分页功能,提高查询效率,降低内存占用,从而提升整个系统...

    spring+springMVC+mybatis拦截器分页 源码

    MyBatis的分页功能通常通过PageHelper或MyBatis-Plus等插件实现,它们允许开发者在不修改原有SQL的基础上,轻松实现物理分页或逻辑分页。分页不仅可以提高应用的性能,避免一次性加载大量数据导致内存压力,还能提供...

    springboot-mybatis-分页

    PageHelper通过拦截器的方式,自动拦截SQL,实现物理分页。使用PageHelper后,只需要在Mapper接口的方法上添加@Select、@Insert、@Update或@Delete注解,就可以自动实现分页功能,极大地提高了开发效率。 【BaseDao...

    IDEA: spring+mybatis+springMVC SSM框架(三) spring 整合 Mybatis 以及分页插件 PageHelper

    只需在查询方法上添加PageHelper.startPage()和 PageInfo.Page(),即可实现物理分页,同时支持多种数据库,如MySQL、Oracle等。 6. **配置PageHelper**:在Spring配置文件中,需要引入PageHelper的bean,配置数据库...

    淘淘商城Mybatis分页插件 - PageHelper

    5. **物理分页**:通过数据库特有的分页机制实现物理分页,提高查询效率。 6. **逻辑分页**:在某些不支持物理分页的数据库中,通过排序和限制数据量实现逻辑分页。 7. **动态SQL生成**:根据分页参数动态生成高效的...

    Spring整合Mybatis

    Spring整合Mybatis是Java开发中常见的一种技术组合,它将Spring的IoC(Inversion of Control,控制反转)和AOP(Aspect Oriented Programming,面向切面编程)能力与Mybatis的灵活SQL映射功能结合,提高了开发效率并...

    Spring+mybatis+PageHelper分页插件

    PageHelper不仅支持物理分页,还支持逻辑分页,同时兼容多种数据库,如MySQL、Oracle、DB2等。 在"描述"中提到,这是一个新手项目,后端已经测试正常,这意味着分页功能已经在服务器端实现了。然而,前端网页部分...

    mybatis-plus优缺点

    12. **内置分页插件**:基于MyBatis物理分页机制,简化了分页查询的实现。 13. **性能分析插件**:可以输出SQL语句及其执行时间,帮助开发人员优化慢查询。 14. **全局拦截插件**:提供全表DELETE/UPDATE操作的智能...

    springboot_mybatis项目

    - **PageHelper分页插件**:这是一个非常实用的Mybatis分页插件,它可以实现物理分页和逻辑分页,只需简单配置即可实现高效、便捷的分页功能。 - **Mybatis-Plus**:它是Mybatis的增强工具,在Mybatis的基础上只做...

    pagehelper-fix/pagehelper 淘淘商城MyBatis分页插件

    【标签】中的"pagehelper"是我们的主要讨论对象,它是一个广泛使用的MyBatis插件,提供了包括物理分页、逻辑分页、参数处理、结果处理等功能。"分页插件"强调了PageHelper的核心作用,即实现高效且易于使用的数据库...

    Springboot-Mybatis-Gradle:Gradle 构建SpringBoot项目,使用Mybatis来持久化,集成PageHelper分页插件,实现热部署

    使用PageHelper可以简化分页查询的编写,提高开发效率,同时提供了一套完整的解决方案,包括物理分页、逻辑分页、参数处理等。 5. **Junit4**:JUnit4是Java领域广泛使用的单元测试框架,它提供了丰富的断言方法和...

    Android+Java后端(Springboot+Mybatis)小商店项目源码+数据库+项目说明.zip

    Android+Java后端(Springboot+Mybatis)小商店项目源码+数据库+项目说明.zip 主要实现一个商城的下单、购物车、支付等基本功能,熟悉后端的开发过程,因为自己做...PageHelper MyBatis物理分页插件 Redis 分布式缓存

    spring boot+mybatis+pagehelp分布+通用mapper

    【PageHelper】是MyBatis的分页插件,它对MyBatis的SQL执行过程进行了拦截,实现了物理分页。PageHelper提供了强大的分页功能,可以自动计算总页数、总记录数,支持多种数据库,如MySQL、Oracle等,并且能自动识别...

    MyBatis-Plus技术文档.pdf

    - **内置分页插件**:支持物理分页,使用简单直观,适用于多种数据库。 - **性能分析插件**:可输出SQL语句及其执行时间,有助于开发者在开发测试阶段迅速定位性能瓶颈。 - **全局拦截插件**:提供全表delete、...

    baomidou-mybatis-plus-3.0.zip

    在分页功能上,Mybatis-Plus内置了PageHelper插件,可以实现高效的物理分页,同时兼容各种数据库,如MySQL、Oracle等。开发者只需要简单设置即可实现优雅的分页效果。 另外,Mybatis-Plus3.0还提供了丰富的扩展点,...

Global site tag (gtag.js) - Google Analytics