美文网首页程序员
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