一 方言
mybatis.pagination.dialect.Dialect.javapackage mybatis.pagination.dialect;
/**
* Created by Administrator on 2015/4/29.
*/
public interface Dialect {
public String getLimitString(String sql, int offset, int limit);
}mybatis.pagination.dialect.MySqlDialect.javapackage mybatis.pagination.dialect;
/**
* Created by Administrator on 2015/4/29.
*/
public class MySqlDialect implements Dialect{
@Override
public String getLimitString(String sql, int offset, int limit) {
String newSql = "select * from ("+sql+") e limit "+offset+","+limit;
return newSql;
}
}
mybatis.pagination.dialect.DialectProvider.javapackage mybatis.pagination.dialect;
/**
* Created by Administrator on 2015/4/29.
*/
public class DialectProvider {
private static DialectProvider dialectProvider = new DialectProvider();
private DialectProvider(){}
public static DialectProvider getInstance(){
return dialectProvider;
}
public Dialect getDialect(String dialectName){
if("mysql".equals(dialectName)){
return new MySqlDialect();
}
throw new RuntimeException("can't find the specified dialect : "+dialectName);
}
}
二 分页拦截器mybatis.pagination.interceptor.PaginationInterceptor.javapackage mybatis.pagination.interceptor;
import mybatis.pagination.dialect.Dialect;
import mybatis.pagination.dialect.DialectProvider;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.factory.DefaultObjectFactory;
import org.apache.ibatis.reflection.factory.ObjectFactory;
import org.apache.ibatis.reflection.wrapper.DefaultObjectWrapperFactory;
import org.apache.ibatis.reflection.wrapper.ObjectWrapperFactory;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.RowBounds;
import java.sql.Connection;
import java.util.Properties;
/**
* 通过拦截StatementHandler
的prepare
方法,重写sql语句实现物理分页。
* 老规矩,签名里要拦截的类型只能是接口。
*
*/
@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class})})
public class PaginationInterceptor implements Interceptor {
private static final ObjectFactory DEFAULT_OBJECT_FACTORY = new DefaultObjectFactory();
private static final ObjectWrapperFactory DEFAULT_OBJECT_WRAPPER_FACTORY = new DefaultObjectWrapperFactory();
@Override
public Object intercept(Invocation invocation) throws Throwable {
StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
MetaObject metaStatementHandler = MetaObject.forObject(statementHandler, DEFAULT_OBJECT_FACTORY,DEFAULT_OBJECT_WRAPPER_FACTORY);
RowBounds rowBounds = (RowBounds) metaStatementHandler.getValue("delegate.rowBounds");
// property在mybatis settings文件内配置
Configuration configuration = (Configuration) metaStatementHandler.getValue("delegate.configuration");
// 只重写需要分页的sql语句。通过MappedStatement的ID匹配,默认重写以Page结尾的MappedStatement的sql
BoundSql boundSql = (BoundSql) metaStatementHandler.getValue("delegate.boundSql");
String sql = boundSql.getSql();
// 重写sql
Dialect dialect = getDialect(configuration);
String newSql = dialect.getLimitString(sql,rowBounds.getOffset(),rowBounds.getLimit());
metaStatementHandler.setValue("delegate.boundSql.sql", newSql);
// 采用物理分页后,就不需要mybatis的内存分页了,所以重置下面的两个参数
metaStatementHandler.setValue("delegate.rowBounds.offset", RowBounds.NO_ROW_OFFSET);
metaStatementHandler.setValue("delegate.rowBounds.limit", RowBounds.NO_ROW_LIMIT);
// 将执行权交给下一个拦截器
return invocation.proceed();
}
private Dialect getDialect(Configuration configuration){
Properties properties = configuration.getVariables();
if(properties==null){
properties = new Properties();
}
String dialectName = properties.getProperty("dialect","mysql");
return DialectProvider.getInstance().getDialect(dialectName);
}
@Override
public Object plugin(Object target) {
// 当目标类是StatementHandler类型时,才包装目标类,否者直接返回目标本身,减少目标被代理的次数
if (target instanceof StatementHandler) {
return Plugin.wrap(target, this);
} else {
return target;
}
}
@Override
public void setProperties(Properties properties) {
//To change body of implemented methods use File | Settings | File Templates.
}
}
三 Mybatis 配置
四 pom.xml
org.mybatis
mybatis
3.1.1