这里做的是以ByPage结尾的,使用mysql数据库
一、page类:
package com.ming.util;
/**
* 分页对应的实体类
*/
public class Page {
/**
* 总条数
*/
private int totalNumber;
/**
* 当前第几页
*/
private int currentPage;
/**
* 总页数
*/
private int totalPage;
/**
* 每页显示条数
*/
private int pageNumber = 5;
/**
* 数据库中limit的参数,从第几条开始取
*/
private int dbIndex;
/**
* 数据库中limit的参数,一共取多少条
*/
private int dbNumber;
/**
* 根据当前对象中属性值计算并设置相关属性值
*/
public void count() {
// 计算总页数
int totalPageTemp = this.totalNumber / this.pageNumber;
int plus = (this.totalNumber % this.pageNumber) == 0 ? 0 : 1;
totalPageTemp = totalPageTemp + plus;
if(totalPageTemp <= 0) {
totalPageTemp = 1;
}
this.totalPage = totalPageTemp;
// 设置当前页数
// 总页数小于当前页数,应将当前页数设置为总页数
if(this.totalPage < this.currentPage) {
this.currentPage = this.totalPage;
}
// 当前页数小于1设置为1
if(this.currentPage < 1) {
this.currentPage = 1;
}
// 设置limit的参数
this.dbIndex = (this.currentPage - 1) * this.pageNumber;
this.dbNumber = this.pageNumber;
}
public int getTotalNumber() {
return totalNumber;
}
public void setTotalNumber(int totalNumber) {
this.totalNumber = totalNumber;
this.count();
}
public int getCurrentPage() {
return currentPage;
}
public void setCurrentPage(int currentPage) {
this.currentPage = currentPage;
}
public int getTotalPage() {
return totalPage;
}
public void setTotalPage(int totalPage) {
this.totalPage = totalPage;
}
public int getPageNumber() {
return pageNumber;
}
public void setPageNumber(int pageNumber) {
this.pageNumber = pageNumber;
this.count();
}
public int getDbIndex() {
return dbIndex;
}
public void setDbIndex(int dbIndex) {
this.dbIndex = dbIndex;
}
public int getDbNumber() {
return dbNumber;
}
public void setDbNumber(int dbNumber) {
this.dbNumber = dbNumber;
}
}
二、拦截器
package com.ming.interceptor;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Map;
import java.util.Properties;
import org.apache.ibatis.executor.parameter.ParameterHandler;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
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.reflection.SystemMetaObject;
import com.ming.util.Page;
/**
*
* 拦截器签名:要拦截的目标类型是StatementHandler(注意:type只能配置成接口类型),
* 拦截的方法是名称为prepare参数为Connection类型的方法
*
*/
@Intercepts({ @Signature(type = StatementHandler.class, method = "prepare", args = { Connection.class }) })
public class PageInterceptor1 implements Interceptor {
public Object intercept(Invocation invocation) throws Throwable {
// 拦截获取statement处理类
StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
// 把statement处理类交给MetaObject代理类代理
MetaObject metaObject = MetaObject.forObject(statementHandler, SystemMetaObject.DEFAULT_OBJECT_FACTORY,
SystemMetaObject.DEFAULT_OBJECT_WRAPPER_FACTORY);
MappedStatement mappedStatement = (MappedStatement) metaObject.getValue("delegate.mappedStatement");
String id = mappedStatement.getId();
//以ByPage结尾的才操作
if (id.matches(".+ByPage$")) {
BoundSql boundSql = statementHandler.getBoundSql();
String sql = boundSql.getSql();
String countSql = "select count(*) from (" + sql + ")a";
// 获取connection
Connection connection = (Connection) invocation.getArgs()[0];
// 通过connection获取prepareStatement
PreparedStatement countStatement = connection.prepareStatement(countSql);
// 获取参数处理类
ParameterHandler parameterHandler = (ParameterHandler) metaObject.getValue("delegate.parameterHandler");
// 通过参数处理类 把参数设置进去
parameterHandler.setParameters(countStatement);
// 开始查询
ResultSet rs = countStatement.executeQuery();
// 获取传过来的参数
Map<?, ?> parameter = (Map<?, ?>) boundSql.getParameterObject();
// 获取page参数
Page page = (Page) parameter.get("page");
if (rs.next()) {
// 为page设置查询出来的所有数据条数
page.setTotalNumber(rs.getInt(1));
}
// 改造后带分页查询的SQL语句
String pageSql = sql + " limit " + page.getDbIndex() + "," + page.getDbNumber();
// 代理类设置改装好sql语句
metaObject.setValue("delegate.boundSql.sql", pageSql);
}
return invocation.proceed();
}
public Object plugin(Object target) {
//不合条件的 直接放行
return Plugin.wrap(target, this);
}
public void setProperties(Properties properties) {
}
}
小例子下载地址: