您的位置:首页 > 其它

Mybatis实现物理分页

2012-12-02 17:14 351 查看
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.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中未设置数据库类型");

}

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逻辑分页一样,拦截器会自动拦截执行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);

}

/**

* 查询 返回一个结果

* @param <T>

* @param key

* @param params

* @return

*/

public <T> T get(String key, Object params) {

return (T) getSqlSession().selectOne(key, params);

}

/**

* 查询 返回多个结果

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

}

/**

* 查询 可带参数 返回多个结果

* @param <T>

* @param key

* @param params

* @return

*/

public <T> List<T> findList(String key, Object params) {

return getSqlSession().selectList(key, params);

}

/**

* 分页查询 可带参数

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

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: