Mybatis实现物理分页
Mybatis的自帶分頁方法只是邏輯分頁,如果數(shù)據(jù)量很大,內(nèi)存會(huì)溢出,不知道為什么開源組織不在里面實(shí)現(xiàn)類似Hibernate的物理分頁處理方法。在不改動(dòng)Mybatis源代碼的情況下,怎么使Mybatis支持物理分頁呢?下面我們來看看。
?
(1)新建一個(gè)Java類Dialect.java,該類的內(nèi)容如下:
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)新建一個(gè)Java類OracleDialect.java,該類繼承Dialect 類,具體的內(nèi)容如下:
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)新建一個(gè)Mybaits的攔截器PaginationInterceptor.java,實(shí)現(xiàn)Interceptor接口,該類的內(nèi)容如下:
Java代碼?package org.mybatis.extend.interceptor
import java.sql.Connection;
import java.util.List;
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;
import platform.pages.mybatis.dialects.MysqlDialect;
import platform.pages.mybatis.dialects.OracleDialect;
/**
?* Mybaits的攔截器
?*
?* @author fhx 2013-1-27 下午03:04:33
?*/
@Intercepts( { @Signature(type = StatementHandler.class, method = "prepare", args = { Connection.class }) })
public class PaginationInterceptor implements Interceptor {
?protected static Logger log = LoggerFactory.getLogger(PaginationInterceptor.class);
?@Override
?public Object intercept(Invocation invocation) throws Throwable {
??StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
??BoundSql boundSql2 = statementHandler.getBoundSql();
??List list = boundSql2.getParameterMappings();
??MetaObject metaStatementHandler = MetaObject.forObject(statementHandler);
??RowBounds rowBounds = (RowBounds) boundSql2.getParameterObject();
??if (rowBounds == null || rowBounds == RowBounds.DEFAULT) {
???return invocation.proceed();
??}
??String originalSql = (String) metaStatementHandler.getValue("delegate.boundSql.sql");
??Configuration configuration = (Configuration) metaStatementHandler.getValue("delegate.configuration");
??Dialect.Type databaseType = null;
??try {
???databaseType = Dialect.Type.valueOf(configuration.getVariables().getProperty("dialect").toUpperCase());
??} catch (Exception e) {
???System.out.println("mybatis-config.xml中未設(shè)置數(shù)據(jù)庫類型");
??}
??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: // oracle 分頁
???dialect = new OracleDialect();
???break;
??case MYSQL: // MySQL分頁
???dialect = new MysqlDialect();
???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();
?}
?@Override
?public Object plugin(Object target) {
??return Plugin.wrap(target, this);
?}
?@Override
?public void setProperties(Properties arg0) {
?}
}
?
?(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邏輯分頁一樣,攔截器會(huì)自動(dòng)攔截執(zhí)行SQL的地方,加上分頁代碼:
Java代碼?getSqlSession().selectList(sqlId,?paramMap,new?RowBounds(pageId,?pageSize));?
????????????? (6) 和spring集成封裝有superDao
public class SupperDao extends SqlSessionDaoSupport{
?
?protected Logger log = LoggerFactory.getLogger(getClass());
?
?/**
? * 保存
? * @param key
? * @param object
? */
?public void save(String key, Object object) {
??getSqlSession().insert(key, object);
?}
?
?/**
? * 刪除
? * @param key
? * @param id
? */
?public void delete(String key, Serializable id) {
??getSqlSession().delete(key, id);
?}
?
?/**
? * 刪除
? * @param key
? * @param object
? */
?public void delete(String key, Object object) {
??getSqlSession().delete(key, object);
?}
?
?/**
? * 查詢 返回一個(gè)結(jié)果
? * @param <T>
? * @param key
? * @param params
? * @return
? */
?public <T> T get(String key, Object params) {
??return (T) getSqlSession().selectOne(key, params);
?}
?
?/**
? * 查詢 返回多個(gè)結(jié)果
? * @param <T>
? * @param key
? * @return
? */
?public <T> List<T> findList(String key) {
??return getSqlSession().selectList(key);
?}
?
?/**
? * 分頁查詢
? * @param <T>
? * @param key
? * @param offset
? * @param pageSize
? * @return
? */
?public <T> List<T> findList(String key,int offset,int pageSize) {
??return getSqlSession().selectList(key,new RowBounds(offset, pageSize));
?}
?
?/**
? * 查詢 可帶參數(shù) 返回多個(gè)結(jié)果
? * @param <T>
? * @param key
? * @param params
? * @return
? */
?public <T> List<T> findList(String key, Object params) {
??return getSqlSession().selectList(key, params);
?}
?
?/**
? * 分頁查詢 可帶參數(shù)
? * @param <T>
? * @param key
? * @param params
? * @param pageNo
? * @param pageSize
? * @return
? */
?public <T> List<T> findList(String key, Object params,int pageOffset,int pageSize) {
??return getSqlSession().selectList(key, params,new RowBounds(pageOffset, pageSize));
?}
總結(jié)
以上是生活随笔為你收集整理的Mybatis实现物理分页的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ibatis解决sql注入问题 .
- 下一篇: 命令方式定时关机