• mybatis


    拦截器介绍

    mybatis提供了@Intercepts注解允许开发者对mybatis的执行器Executor进行拦截。
    Executor接口方法主要有update、query、commit、rollback等等。
    主要思路为:

    1. 进入拦截器方法中
    2. 获取拦截器方法参数
    3. 获取解析参数及MappedStatement
    4. 从MappedStatement声明类中获取resultMap
    5. 获取resultMappings并且进行自定义
    6. 重新组装新的ResultMap
    7. 利用反射将新的ResultMap设置进入MappedStatement中

    拦截器代码

    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.Interceptor;
    import org.apache.ibatis.plugin.Intercepts;
    import org.apache.ibatis.plugin.Invocation;
    import org.apache.ibatis.plugin.Plugin;
    import org.apache.ibatis.session.ResultHandler;
    import org.apache.ibatis.session.RowBounds;
    import org.springframework.stereotype.Component;
    import org.springframework.util.ReflectionUtils;
    
    import java.lang.reflect.Field;
    import java.util.*;
    
    @Component
    @Intercepts({@org.apache.ibatis.plugin.Signature(type = Executor.class, method = "query",
            args = {
                    MappedStatement.class,
                    Object.class,
                    RowBounds.class,
                    ResultHandler.class,
                    CacheKey.class,
                    BoundSql.class})})
    public class MybatisInterceptorConfig implements Interceptor {
    
        /*重置ResultMapping*/
        private List<ResultMapping> resetResultMap(List<ResultMapping> resultMaps){
                //ResultMaps.add
            return resultMaps;
        }
        @Override
        public Object intercept(Invocation invocation) throws Throwable {
            resetResultMap(invocation);
            return invocation.proceed();
        }
        @Override
        public Object plugin(Object o) {
            return Plugin.wrap(o, this);
        }
        @Override
        public void setProperties(Properties properties) {
    
        }
        private void resetResultMap(Invocation invocation) {
            final Object[] args = invocation.getArgs();
            MappedStatement mappedStatement = (MappedStatement) args[5];
            ResultMap resultMap = mappedStatement.getResultMaps().iterator().next();
            if (resultMap != null) {
                List<ResultMapping> resultMappings = resultMap.getResultMappings();
                if (resultMappings != null && !(resultMappings instanceof AdjustedList)) {
                    List<ResultMapping> newResultMappings = this.resetResultMap(new AdjustedList(resultMappings));
                    ResultMap newResultMap = new ResultMap.Builder(mappedStatement.getConfiguration(), resultMap.getId(), resultMap.getType(), newResultMappings).build();
                    Field field = ReflectionUtils.findField(MappedStatement.class, "resultMaps");
                    ReflectionUtils.makeAccessible(field);
                    ReflectionUtils.setField(field, mappedStatement, Collections.singletonList(newResultMap));
                }
            }
        }
        private class AdjustedList<E> extends ArrayList<E> {
            public AdjustedList(Collection<? extends E> c) {
                super(c);
            }
        }
    }
    
  • 相关阅读:
    LG P4449 & JZOJ 于神之怒
    [国家集训队]Crash的数字表格
    LG P3768 简单的数学题
    NOI2018 屠龙勇士
    为什么从后台获取的id到前端后却变了?Long类型转json时前端js丢失精度解决方案-----@JsonSerialize和@JsonDeserialize
    vue的filters过滤器优化
    根据key查询redis中是否存在key对应的value,根据key获取值
    PowerDesigner逆向工程将MYSQL数据库转成pdm
    解决图片验证码不显示的问题
    报错:Unknown column 'province' in 'field list'
  • 原文地址:https://www.cnblogs.com/cjunn/p/12173984.html
Copyright © 2020-2023  润新知