美文网首页程序员
Spring Boot项目根据model属性,排序拦截器

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

作者: zuoqy | 来源:发表于2018-08-17 11:15 被阅读0次

说明:此拦截器配置在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分页拦截器类似。

相关文章

网友评论

    本文标题:Spring Boot项目根据model属性,排序拦截器

    本文链接:https://www.haomeiwen.com/subject/wdjzbftx.html