Mybatis技术(3) 实现物理分页
Mybatis技术(三) 实现物理分页Mybatis技术(三) 实现物理分页博客分类:?Mybatis技术内幕Mybatis物理分页Myb
Mybatis技术(三) 实现物理分页
Mybatis技术(三) 实现物理分页博客分类:?- Mybatis技术内幕Mybatis物理分页
Mybatis的自带分页方法只是逻辑分页,如果数据量很大,内存会溢出,不知道为什么开源组织不在里面实现类似Hibernate的物理分页处理方法。在不改动Mybatis源代码的情况下,怎么使Mybatis支持物理分页呢?下面我们来看看。
?
(1)新建一个Java类Dialect.java,该类的内容如下:
Java代码??
- package?org.mybatis.extend.interceptor;??
- ??
- public?abstract?class?Dialect?{??
- ??
- ????public?static?enum?Type{??
- ????????MYSQL,??
- ????????ORACLE??
- ????}??
- ??????
- ????public?abstract?String?getLimitString(String?sql,?int?skipResults,?int?maxResults);??
- ??????
- }??
?
?
(2)新建一个Java类OracleDialect.java,该类继承Dialect 类,具体的内容如下:
Java代码??
- package?org.mybatis.extend.interceptor;??
- ??
- public?class?OracleDialect?extends?Dialect{??
- ??
- ????/*?(non-Javadoc)?
- ?????*?@see?org.mybatis.extend.interceptor.IDialect#getLimitString(java.lang.String,?int,?int)?
- ?????*/??
- ????@Override??
- ????public?String?getLimitString(String?sql,?int?offset,?int?limit)?{??
- ??
- ????????sql?=?sql.trim();??
- ????????StringBuffer?pagingSelect?=?new?StringBuffer(sql.length()?+?100);??
- ??????????
- ????????pagingSelect.append("select?*?from?(?select?row_.*,?rownum?rownum_?from?(?");??
- ??????????
- ????????pagingSelect.append(sql);??
- ??????????
- ????????pagingSelect.append("?)?row_?)?where?rownum_?>?").append(offset).append("?and?rownum_?<=?").append(offset?+?limit);??
- ??????????
- ????????return?pagingSelect.toString();??
- ????}??
- ??
- }??
?
(3)新建一个Mybaits的拦截器PaginationInterceptor.java,实现Interceptor接口,该类的内容如下:
Java代码??
- package?org.mybatis.extend.interceptor;??
- ??
- import?java.sql.Connection;??
- import?java.util.Map;??
- import?java.util.Properties;??
- ??
- import?org.apache.ibatis.executor.parameter.DefaultParameterHandler;??
- import?org.apache.ibatis.executor.statement.StatementHandler;??
- import?org.apache.ibatis.mapping.BoundSql;??
- import?org.apache.ibatis.plugin.Interceptor;??
- import?org.apache.ibatis.plugin.Intercepts;??
- import?org.apache.ibatis.plugin.Invocation;??
- import?org.apache.ibatis.plugin.Plugin;??
- import?org.apache.ibatis.plugin.Signature;??
- import?org.apache.ibatis.reflection.MetaObject;??
- import?org.apache.ibatis.session.Configuration;??
- import?org.apache.ibatis.session.RowBounds;??
- import?org.slf4j.Logger;??
- import?org.slf4j.LoggerFactory;??
- ??
- ??
- @Intercepts({@Signature(type=StatementHandler.class,method="prepare",args={Connection.class})})??
- public?class?PaginationInterceptor?implements?Interceptor?{??
- ????//日志对象??
- ????protected?static?Logger?log?=?LoggerFactory.getLogger(PaginationInterceptor.class);??
- ????/*?(non-Javadoc)?
- ?????*?@see?org.apache.ibatis.plugin.Interceptor#intercept(org.apache.ibatis.plugin.Invocation)?
- ?????*/??
- ????@Override??
- ????public?Object?intercept(Invocation?invocation)?throws?Throwable?{??
- ????????StatementHandler?statementHandler?=?(StatementHandler)invocation.getTarget();??
- ????????MetaObject?metaStatementHandler?=?MetaObject.forObject(statementHandler);??
- ??????????
- ????????RowBounds?rowBounds?=?(RowBounds)metaStatementHandler.getValue("delegate.rowBounds");??
- ????????if(rowBounds?==?null?||?rowBounds?==?RowBounds.DEFAULT){??
- ????????????return?invocation.proceed();??
- ????????}??
- ??????????
- ????????DefaultParameterHandler?defaultParameterHandler?=?(DefaultParameterHandler)metaStatementHandler.getValue("delegate.parameterHandler");??
- ????????Map?parameterMap?=?(Map)defaultParameterHandler.getParameterObject();??
- ????????Object?sidx?=?parameterMap.get("_sidx");??
- ????????Object?sord?=?parameterMap.get("_sord");??
- ??????????
- ????????String?originalSql?=?(String)metaStatementHandler.getValue("delegate.boundSql.sql");??
- ??????????
- ????????if(sidx?!=?null?&&?sord?!=?null){??
- ????????????originalSql?=?originalSql?+?"?order?by?"?+?sidx?+?"?"?+?sord;??
- ????????}??
- ??????????
- ????????Configuration?configuration?=?(Configuration)metaStatementHandler.getValue("delegate.configuration");??
- ??????????
- ????????????????????????????Dialect.Type?databaseType??=?null;??
- ????????try{??
- ????????????databaseType?=?Dialect.Type.valueOf(configuration.getVariables().getProperty("dialect").toUpperCase());??
- ????????}?catch(Exception?e){??
- ????????????//ignore??
- ????????}??
- ????????if(databaseType?==?null){??
- ????????????throw?new?RuntimeException("the?value?of?the?dialect?property?in?configuration.xml?is?not?defined?:?"?+?configuration.getVariables().getProperty("dialect"));??
- ????????}??
- ????????Dialect?dialect?=?null;??
- ????????switch(databaseType){??
- ????????????case?ORACLE:??
- ????????????????dialect?=?new?OracleDialect();??
- ????????????????break;??
- ????????????case?MYSQL://需要实现MySQL的分页逻辑??
- ????????????????break;??
- ??????????????????
- ????????}??
- ??????????
- ??????????
- ????????metaStatementHandler.setValue("delegate.boundSql.sql",?dialect.getLimitString(originalSql,?rowBounds.getOffset(),?rowBounds.getLimit())?);??
- ????????metaStatementHandler.setValue("delegate.rowBounds.offset",?RowBounds.NO_ROW_OFFSET?);??
- ????????metaStatementHandler.setValue("delegate.rowBounds.limit",?RowBounds.NO_ROW_LIMIT?);??
- ????????if(log.isDebugEnabled()){??
- ????????????BoundSql?boundSql?=?statementHandler.getBoundSql();??
- ????????????log.debug("生成分页SQL?:?"?+?boundSql.getSql());??
- ????????}??
- ????????return?invocation.proceed();??
- ????}??
- ??
- ????/*?(non-Javadoc)?
- ?????*?@see?org.apache.ibatis.plugin.Interceptor#plugin(java.lang.Object)?
- ?????*/??
- ????@Override??
- ????public?Object?plugin(Object?target)?{??
- ????????return?Plugin.wrap(target,?this);??
- ????}??
- ??
- ????/*?(non-Javadoc)?
- ?????*?@see?org.apache.ibatis.plugin.Interceptor#setProperties(java.util.Properties)?
- ?????*/??
- ????@Override??
- ????public?void?setProperties(Properties?arg0)?{??
- ????????//?TODO?Auto-generated?method?stub??
- ??????????
- ????}??
- ??
- }??
?
?(4)将Mybatis的拦截器配置到Mybatis的全局配置文件(mybatis.cfg.xml)中,具体如下:
Java代码??
- <?xml?version="1.0"?encoding="UTF-8"??>??
- ??
- <!DOCTYPE?configuration?PUBLIC???
- ????"-//mybatis.org//DTD?Config?3.0//EN"??
- ????"http://mybatis.org/dtd/mybatis-3-config.dtd">??
- ??
- <configuration>??
- ????<properties>??
- ??????????????<property?name="dialect"?value="oracle"/>??
- ????</properties>??
- ??????????
- ????<plugins>??
- ????????????<plugin?interceptor="org.mybatis.extend.interceptor.PaginationInterceptor"/>??
- ????</plugins>??
- ?????????
- </configuration>??
?
(5)使用方法同Mybatis逻辑分页一样,拦截器会自动拦截执行SQL的地方,加上分页代码:
Java代码??
- getSqlSession().selectList(sqlId,?paramMap,new?RowBounds(pageId,?pageSize)); ?
?
1 楼 azrael6619 2012-06-13 Object sidx = parameterMap.get("_sidx");
Object sord = parameterMap.get("_sord");
这两个参数是哪里放进去的?