Mybatis 分页

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

 

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


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

 

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


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

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


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

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

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

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

 

java代码: getSqlSession().selectList(sqlId, paramMap,new RowBounds(pageId, pageSize));
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值