Spring Boot项目根据model属性,排序拦截器

说明:此拦截器配置在pageHelper分页拦截器之前拦截,对model中字段进行排序。适应业务:对表格进行排序,可快速查找或对比数据。

图一.png

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分页拦截器类似。


出自:zuoqy博客 如若转载请注明出处!