import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import javax.xml.bind.PropertyException;
import org.apache.ibatis.executor.ErrorContext;
import org.apache.ibatis.executor.ExecutorException;
import org.apache.ibatis.executor.statement.BaseStatementHandler;
import org.apache.ibatis.executor.statement.RoutingStatementHandler;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ParameterMapping;
import org.apache.ibatis.mapping.ParameterMode;
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.property.PropertyTokenizer;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.type.TypeHandler;
import org.apache.ibatis.type.TypeHandlerRegistry;
@Intercepts({@Signature(
type = StatementHandler.class,
method = "prepare",
args = {Connection.class}
)})
public class PagePlugin implements Interceptor {
private static String dialect = "";
private static String pageSqlId = ".*?Page*?";
public PagePlugin() {
}
public Object intercept(Invocation ivk) throws Throwable {
if (ivk.getTarget() instanceof RoutingStatementHandler) {
RoutingStatementHandler statementHandler = (RoutingStatementHandler)ivk.getTarget();
BaseStatementHandler delegate = (BaseStatementHandler)ReflectHelper.getValueByFieldName(statementHandler, "delegate");
MappedStatement mappedStatement = (MappedStatement)ReflectHelper.getValueByFieldName(delegate, "mappedStatement");
if (mappedStatement.getId().matches(pageSqlId)) {
BoundSql boundSql = delegate.getBoundSql();
Object parameterObject = boundSql.getParameterObject();
if (parameterObject == null) {
throw new NullPointerException("parameterObject error");
}
Connection connection = (Connection)ivk.getArgs()[0];
String sql = boundSql.getSql();
String countSql = "select count(0) from (" + sql + ") myCount";
PreparedStatement countStmt = connection.prepareStatement(countSql);
BoundSql countBS = new BoundSql(mappedStatement.getConfiguration(), countSql, boundSql.getParameterMappings(), parameterObject);
this.setParameters(countStmt, mappedStatement, countBS, parameterObject);
ResultSet rs = countStmt.executeQuery();
int count = 0;
if (rs.next()) {
count = rs.getInt(1);
}
rs.close();
countStmt.close();
Page page = null;
if (parameterObject instanceof Page) {
page = (Page)parameterObject;
page.setRecordsTotal(count);
} else if (parameterObject instanceof Map) {
Map<String, Object> map = (Map)parameterObject;
page = (Page)map.get("page");
if (page == null) {
page = new Page();
}
page.setRecordsTotal(count);
page.setRecordsFiltered(count);
} else {
Field pageField = ReflectHelper.getFieldByFieldName(parameterObject, "page");
if (pageField == null) {
throw new NoSuchFieldException(parameterObject.getClass().getName());
}
page = (Page)ReflectHelper.getValueByFieldName(parameterObject, "page");
if (page == null) {
page = new Page();
}
page.setRecordsTotal(count);
page.setRecordsFiltered(count);
ReflectHelper.setValueByFieldName(parameterObject, "page", page);
}
String pageSql = this.generatePageSql(sql, page);
ReflectHelper.setValueByFieldName(boundSql, "sql", pageSql);
}
}
return ivk.proceed();
}
private void setParameters(PreparedStatement ps, MappedStatement mappedStatement, BoundSql boundSql, Object parameterObject) throws SQLException {
ErrorContext.instance().activity("setting parameters").object(mappedStatement.getParameterMap().getId());
List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
if (parameterMappings != null) {
Configuration configuration = mappedStatement.getConfiguration();
TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry();
MetaObject metaObject = parameterObject == null ? null : configuration.newMetaObject(parameterObject);
for(int i = 0; i < parameterMappings.size(); ++i) {
ParameterMapping parameterMapping = (ParameterMapping)parameterMappings.get(i);
if (parameterMapping.getMode() != ParameterMode.OUT) {
String propertyName = parameterMapping.getProperty();
PropertyTokenizer prop = new PropertyTokenizer(propertyName);
Object value;
if (parameterObject == null) {
value = null;
} else if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {
value = parameterObject;
} else if (boundSql.hasAdditionalParameter(propertyName)) {
value = boundSql.getAdditionalParameter(propertyName);
} else if (propertyName.startsWith("__frch_") && boundSql.hasAdditionalParameter(prop.getName())) {
value = boundSql.getAdditionalParameter(prop.getName());
if (value != null) {
value = configuration.newMetaObject(value).getValue(propertyName.substring(prop.getName().length()));
}
} else {
value = metaObject == null ? null : metaObject.getValue(propertyName);
}
TypeHandler typeHandler = parameterMapping.getTypeHandler();
if (typeHandler == null) {
throw new ExecutorException("There was no TypeHandler found for parameter " + propertyName + " of statement " + mappedStatement.getId());
}
typeHandler.setParameter(ps, i + 1, value, parameterMapping.getJdbcType());
}
}
}
}
private String generatePageSql(String sql, Page page) {
if (page != null && (dialect != null || !dialect.equals(""))) {
StringBuffer pageSql = new StringBuffer();
if ("mysql".equals(dialect)) {
pageSql.append(sql);
pageSql.append(" limit " + page.getStart() + "," + page.getLength());
} else if ("oracle".equals(dialect)) {
pageSql.append("select * from (select tmp_tb.*,ROWNUM row_id from (");
pageSql.append(sql);
pageSql.append(") tmp_tb where ROWNUM<=");
pageSql.append(page.getStart() + page.getLength());
pageSql.append(") where row_id>");
pageSql.append(page.getStart());
}
return pageSql.toString();
} else {
return sql;
}
}
public Object plugin(Object arg0) {
return Plugin.wrap(arg0, this);
}
public void setProperties(Properties p) {
dialect = p.getProperty("dialect");
if (dialect == null || dialect.equals("")) {
try {
throw new PropertyException("dialect property is not found!");
} catch (PropertyException var4) {
var4.printStackTrace();
}
}
pageSqlId = p.getProperty("pageSqlId");
if (dialect == null || dialect.equals("")) {
try {
throw new PropertyException("pageSqlId property is not found!");
} catch (PropertyException var3) {
var3.printStackTrace();
}
}
}
}
工具类
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package com.sunnysoft.pageutil;
import java.lang.reflect.Field;
public class ReflectHelper {
public ReflectHelper() {
}
public static Field getFieldByFieldName(Object obj, String fieldName) {
Class superClass = obj.getClass();
while(superClass != Object.class) {
try {
return superClass.getDeclaredField(fieldName);
} catch (NoSuchFieldException var4) {
superClass = superClass.getSuperclass();
}
}
return null;
}
public static Object getValueByFieldName(Object obj, String fieldName) throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
Field field = getFieldByFieldName(obj, fieldName);
Object value = null;
if (field != null) {
if (field.isAccessible()) {
value = field.get(obj);
} else {
field.setAccessible(true);
value = field.get(obj);
field.setAccessible(false);
}
}
return value;
}
public static void setValueByFieldName(Object obj, String fieldName, Object value) throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
Field field = null;
try {
field = obj.getClass().getDeclaredField(fieldName);
} catch (Exception var5) {
return;
}
if (field.isAccessible()) {
field.set(obj, value);
} else {
field.setAccessible(true);
field.set(obj, value);
field.setAccessible(false);
}
}
}
Page对象
@Data
public class Page<E> implements Serializable {
private int start;
private int length;
private int recordsFiltered;
private int recordsTotal;
private List<E> data = Collections.emptyList();
}
Vo (查询实体)
@Data
public class QueryVo extends Page<StudentDto>{
private Integer studentId;
}
Dto(数据传输对象)
public class StudentDto{
private Integer studentId;
private String name;
private String address;
private Integer classId;
}
Service 接口
public interface IStudentService{
Page<StudentDto> queryDataByPage(QueryVo queryVo);
}
ServiceImpl
Page<StudentDto> queryDataByPage(QueryVo queryVo){
List<StudentDto> list = xxx.queryList(queryVo);
queryVo.getPage().setData(list);
return queryVo.getPage();
}
网友评论