1、通过ThreadLocal封装分页
- 线程分页参数:
public class PageThreadLocalUtil {
private static final ThreadLocal<BasePage> PAGE_THREAD_LOCAL = new ThreadLocal();
public static void setPageThreadLocal(BasePage basePage) {
PAGE_THREAD_LOCAL.set(basePage);
}
public static void getPageThreadLocal() {
PAGE_THREAD_LOCAL.get();
}
public static void removePageThreadLocal() {
PAGE_THREAD_LOCAL.remove();
}
public static void init(int start, int size) {
BasePage basePage = new BasePage();
basePage.setStart(start);
basePage.setSize(size);
setPageThreadLocal(basePage);
}
}
- 分页参数:
@Data
public class BasePage<T> implements Serializable {
private Integer start;
private Integer size;
private Integer total;
private boolean flag;
}
- 自定义拦截器:
拦截器配置:
//@Intercepts({@Signature(
// type = Executor.class,
// method = “query”,
// args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class }) })
@Intercepts(@Signature(
type = StatementHandler.class,
method = "prepare",
args = {Connection.class, Integer.class}))
public class MyPageHelper implements Interceptor {
@Override
public Object intercept(Invocation invocation) throws Throwable {
StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
MetaObject metaObject = MetaObject.forObject(statementHandler, SystemMetaObject.DEFAULT_OBJECT_FACTORY,
SystemMetaObject.DEFAULT_OBJECT_WRAPPER_FACTORY, new DefaultReflectorFactory());
// map.xml对应id
MappedStatement mappedStatement = (MappedStatement) metaObject.getValue("delegate.mappedStatement");
String statementId = mappedStatement.getId();
// 获取StatementHandler中的变量: 判断是否为查询:select
String trimSql = (String) metaObject.getValue("delegate.boundSql.sql");
int index = trimSql.trim().toLowerCase().indexOf("select");
if (index != 0) {
return invocation.proceed();
}
BasePage page = PageThreadLocalUtil.getPageThreadLocal();
if(!page.getFlag()) {
return invocation.proceed();
}
// 数量查询
String sql = statementHandler.getBoundSql().getSql();
String countSql = "select count(*) " + sql.substring(sql.toLowerCase().indexOf("from"));
Connection connection = (Connection) invocation.getArgs()[0];
PreparedStatement ps = connection.prepareStatement(countSql);
//渲染参数
ParameterHandler parameterHandler = (ParameterHandler) metaObject.getValue("delegate.parameterHandler");;
parameterHandler.setParameters(ps);
ResultSet resultSet = ps.executeQuery();
if(resultSet.next()){
page .setTotal(resultSet.getInt(1));
}
int start = page.getStart()
int size = page.getSize()
String pageSql = sql + " limit " + start + "," + size + "";
metaObject.setValue("delegate.boundSql.sql", pageSql);
return invocation.proceed();
}
}
2、封装分页查询参数BasePage
- 查询参数继承BasePage
@Intercepts(@Signature(
type = StatementHandler.class,
method = "prepare",
args = {Connection.class, Integer.class}))
public class MyPageHelper implements Interceptor {
@Override
public Object intercept(Invocation invocation) throws Throwable {
StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
MetaObject metaObject = MetaObject.forObject(statementHandler, SystemMetaObject.DEFAULT_OBJECT_FACTORY,
SystemMetaObject.DEFAULT_OBJECT_WRAPPER_FACTORY, new DefaultReflectorFactory());
MappedStatement mappedStatement = (MappedStatement) metaObject.getValue("delegate.mappedStatement");
String statementId = mappedStatement.getId();
String trimSql = (String) metaObject.getValue("delegate.boundSql.sql");
int index = trimSql.trim().toLowerCase().indexOf("select");
if (index != 0) {
return invocation.proceed();
}
// 获取传入分页参数, [类型必须与参数类型一致]
// Object parameterObject = parameterHandler.getParameterObject();
// List<ParameterMapping> parameterMappings = statementHandler.getBoundSql().getParameterMappings();
Object parameterObject1 = statementHandler.getBoundSql().getParameterObject();
BasePage page = findPageObject(parameterObject1);
if(page == null) {
return invocation.proceed();
}
int size = page.getSize();
int start = page.getStart();
// 数量查询
String sql = statementHandler.getBoundSql().getSql();
String countSql = "select count(*) " + sql.substring(sql.toLowerCase().indexOf("from"));
Connection connection = (Connection) invocation.getArgs()[0];
PreparedStatement ps = connection.prepareStatement(countSql);
//渲染参数
ParameterHandler parameterHandler = (ParameterHandler) metaObject.getValue("delegate.parameterHandler");;
parameterHandler.setParameters(ps);
ResultSet resultSet = ps.executeQuery();
if(resultSet.next()){
page.setTotal(resultSet.getInt(1));
}
String pageSql = sql + " limit " + start + "," + size + "";
metaObject.setValue("delegate.boundSql.sql", pageSql);
return invocation.proceed();
}
private BasePage<?> findPageObject(Object parameterObj) {
if (parameterObj instanceof BasePage<?>) {
return (BasePage<?>) parameterObj;
} else if (parameterObj instanceof Map) {
for (Object val : ((Map<?, ?>) parameterObj).values()) {
if (val instanceof BasePage<?>) {
return (BasePage<?>) val;
}
}
}
return null;
}
}
参考文档: