说明
:此拦截器配置在pageHelper分页拦截器之前拦截,对model中字段进行排序。适应业务
:对表格进行排序,可快速查找或对比数据。
1.创建SortHelperAutoConfiguration.java
SortInfo.java
SortInterceptor.java
SortHelperAutoConfiguration.java
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.context.annotation.Configuration;
import com.github.pagehelper.autoconfigure.PageHelperAutoConfiguration;
import javax.annotation.PostConstruct;
import java.util.List;
@Configuration
@AutoConfigureAfter(PageHelperAutoConfiguration.class)
@ConditionalOnBean(SqlSessionFactory.class)
public class SortHelperAutoConfiguration {
@Autowired
private List<SqlSessionFactory> sqlSessionFactoryList;
@PostConstruct
public void addSortInterceptor() {
SortInterceptor interceptor = new SortInterceptor();
System.out.println("Sort Interceptor Config!!");
for (SqlSessionFactory sqlSessionFactory : sqlSessionFactoryList) {
sqlSessionFactory.getConfiguration().addInterceptor(interceptor);
}
}
}
SortInfo.java
public class SortInfo {
private String field;//排序字段
private String dir;//排序方向 desc(倒序) asc(正序)
private boolean isDbField = false;
public String getField() {
return field;
}
public void setField(String field) {
this.field = field;
}
public String getDir() {
return dir;
}
public void setDir(String dir) {
this.dir = dir;
}
public boolean isDbField() {
return isDbField;
}
public void setDbField(boolean isDbField) {
this.isDbField = isDbField;
}
}
SortInterceptor.java
import org.apache.ibatis.cache.CacheKey;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ResultMap;
import org.apache.ibatis.mapping.ResultMapping;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
@Intercepts(
{
@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}),
@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class, CacheKey.class, BoundSql.class}),
}
)
public class SortInterceptor implements Interceptor{
@SuppressWarnings("rawtypes")
public static final ThreadLocal<SortInfo> localSort = new ThreadLocal<SortInfo>();
/**
* @Description: 开始排序
* @throws
*/
@SuppressWarnings("rawtypes")
public static void useSort(String field, String dir, boolean isDbField) {
SortInfo sort = new SortInfo();
sort.setDbField(isDbField);
sort.setDir(dir);
sort.setField(field);
localSort.set(sort);
}
@SuppressWarnings("rawtypes")
public static void useSort(String field, String dir) {
useSort(field, dir, false);
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
public Object intercept(Invocation invocation) throws Throwable {
SortInfo sortInfo = localSort.get();
if (sortInfo == null) {
return invocation.proceed();
}
try{
Object[] args = invocation.getArgs();
MappedStatement ms = (MappedStatement) args[0];
Object parameter = args[1];
RowBounds rowBounds = (RowBounds) args[2];
ResultHandler resultHandler = (ResultHandler) args[3];
Executor executor = (Executor) invocation.getTarget();
CacheKey cacheKey;
BoundSql boundSql;
if(args.length == 4){
boundSql = ms.getBoundSql(parameter);
cacheKey = executor.createCacheKey(ms, parameter, rowBounds, boundSql);
} else {
cacheKey = (CacheKey) args[4];
boundSql = (BoundSql) args[5];
}
String sql = boundSql.getSql();
String orderSql = buildOrderSql(sql, ms, sortInfo);
BoundSql newBoundSql = new BoundSql(ms.getConfiguration(), orderSql, boundSql.getParameterMappings(), parameter);
List resultList = executor.query(ms, parameter, RowBounds.DEFAULT, resultHandler, cacheKey, newBoundSql);
return resultList;
}
catch(Throwable t)
{
localSort.remove();
throw t;
}
}
private String buildOrderSql(String sql, MappedStatement mappedStatement, SortInfo sortInfo){
StringBuilder pageSql = new StringBuilder(sql);
StringBuilder allSql = new StringBuilder();
allSql.append("select allpage.* from(").append(pageSql.toString()).append(") allpage");
String field = sortInfo.getField();
String dir = sortInfo.getDir();
if(dir == null){
dir = "";
}
if(sortInfo.isDbField() == false)
{
Map<String, String> map = buildFieldMapping(mappedStatement);
field = map.get(field);
}
if(field != null)
{
allSql.append(" order by allpage." + field + " " + dir + " ");
}
return allSql.toString();
}
private Map<String, String> buildFieldMapping(MappedStatement mappedStatement) {
ResultMap resultMap = mappedStatement.getResultMaps().get(0);
List<ResultMapping> mapping = resultMap.getResultMappings();
Map<String, String> mapper = new HashMap<String, String>();
for (ResultMapping mp : mapping) {
mapper.put(mp.getProperty(), mp.getColumn());
if(mp.getNestedResultMapId()!=null)
buildSubFieldMapping(mapper, mappedStatement, mp.getNestedResultMapId(), mp.getProperty());
}
return mapper;
}
private void buildSubFieldMapping(Map<String,String> mapper, MappedStatement mappedStatement, String id, String property) {
ResultMap resultMap = mappedStatement.getConfiguration().getResultMap(id);
if(resultMap==null)
return;
List<ResultMapping> mapping = resultMap.getResultMappings();
for (ResultMapping mp : mapping) {
mapper.put(property + "." + mp.getProperty(), mp.getColumn());
}
}
@Override
public Object plugin(Object target) {
return Plugin.wrap(target, this);
}
@Override
public void setProperties(Properties arg0) {
// TODO Auto-generated method stub
}
}
2.在resource文件夹下创建文件夹META-INF
3.在刚刚创建得META-INF文件夹下创建文件spring.factories
图二.png
使用方法:在对应需要排序得Service中调用方法
SortInterceptor.useSort(sortField, sortDir);
与pageHelper分页拦截器类似。
网友评论