Mybatis自定义插件与PageHelper与冲突解决与公共参数写入

每天积累一点,又一天总会成功

目录

背景

技术方案

技术方案选择

实现步骤

查询拦截器

操作拦截器

公共实体

配置拦截器

查询拦截器不生效

问题解决


背景

       有的系统为保证系统数据存储安全我们系统中有些公共字段需要加密存储,在使用时读入到内存中我们需要解密。

技术方案

1、入库代码与查询时进行数据加密与解密

2、持久层使用AOP拦截根据公共参数进行加密与解密

3、自己定义Mybatis拦截器实现

技术方案选择

1、方案一代码比较耦合,主要代码比较重复

2、老系统公共参数比较乱,不适合

3、比较适合;把通过拦截器把公共参数放到 入参里面,在SQL进行解密,在入库比较单一直接在拦截器进行加密。

实现步骤

查询拦截器

@Intercepts(
        {
                @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}),

        }
)
public class GloableParamInterceptor implements Interceptor {

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        Object[] args = invocation.getArgs();
        MappedStatement ms = (MappedStatement) args[0];
        Object parameter = args[1];
        //TODO 自己要进行的各种处理
        if (!Objects.isNull(parameter)) {
            if (parameter instanceof Map) {
                ((Map) parameter).put("secretKey", "密钥");
            } else if (parameter instanceof Long) {
                Long id = (Long) parameter;
                Map parameters = new HashMap<>();
                parameters.put("id", id);
                parameters.put("secretKey", "密钥");
                args[1] = parameters;
            } else if (parameter instanceof Long) {
                String id = (String) parameter;
                Map parameters = new HashMap<>();
                parameters.put("id", id);
                parameters.put("secretKey", "密钥");
                args[1] = parameters;
            }
        }
        return  invocation.proceed();
    }

    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {
    }

}

注意:Mybatis Xml配置中ParamType 不能配置值,不然会报错

操作拦截器

@Intercepts(
        {
           @Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class}),
           @Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class})

        }
)
public class OPInterceptor implements Interceptor {

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        Object[] args = invocation.getArgs();
        if (!CommonUtils.isNullOrEmpty(args)) {
            for (Object object: args) {
                if (object instanceof CommonVo) {
                    //加密处理
                   CommonVo object1 = (CommonVo) object;
                    object1.setName(AesEncode.enCode(object1.getName())) 

                }
            }
        }
        return  invocation.proceed();
    }

    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {
    }

公共实体

public class CommonVo implements Serializable {
    
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

配置拦截器

        配置拦截器有很多种,这里我只说一种,通过代码配置

@Configuration
public class GlobalVariableConfig {


    @Autowired
    private List<SqlSessionFactory> sqlSessionFactoryList;


    @PostConstruct
    public void addPageInterceptor() {
        GloableParamInterceptor gloableParamInterceptor = new GloableParamInterceptor();
        OpInterceptor opInterceptor = new OpInterceptor ();
        Properties properties = new Properties();
        //先把一般方式配置的属性放进去
        properties.putAll(this.properties.getProperties());
        //在把特殊配置放进去,由于close-conn 利用上面方式时,属性名就是 close-conn 而不是 closeConn,所以需要额外的一步
        pageInterceptor.setProperties(properties);
        for (SqlSessionFactory sqlSessionFactory : sqlSessionFactoryList) {
            sqlSessionFactory.getConfiguration().addInterceptor(gloableParamInterceptor);
            sqlSessionFactory.getConfiguration().addInterceptor(insertOrUpdataInterceptor);
        }
    }
}

查询拦截器不生效

        通过分析,发现拦截器与pagehelper定义分页拦截器有冲突,分页拦截器先调用,他在调用完成后没有往下调。

其种Mybatis中我们在集成时有这个自动加载:

groupId=com.github.pagehelper
artifactId=pagehelper-spring-boot-autoconfigure

我们定义的查询拦截器是不会生效的

问题解决

首先通过关闭自动加载配置,在入库排除加载

PageHelperAutoConfiguration通过
@SpringBootApplication(exclude = {PageHelperAutoConfiguration.class})

修改配置,拷贝 PageHelperAutoConfiguration初始化,并把我们自己加载上去

@Configuration
@EnableConfigurationProperties({PageHelperProperties.class})
public class GlobalVariableConfig {


    @Autowired
    private List<SqlSessionFactory> sqlSessionFactoryList;
    @Autowired
    private PageHelperProperties properties;
    /**
     * 接受分页插件额外的属性
     *
     * @return
     */
    @Bean
    @ConfigurationProperties(prefix = "pagehelper")
    public Properties pageHelperProperties() {
        return new Properties();
    }

    @PostConstruct
    public void addPageInterceptor() {
        GloableParamInterceptor gloableParamInterceptor = new GloableParamInterceptor();
        PageInterceptor pageInterceptor = new PageInterceptor();
        OpInterceptor opInterceptor = new OpInterceptor();
        Properties properties = new Properties();
        //先把一般方式配置的属性放进去
        properties.putAll(pageHelperProperties());
        properties.putAll(this.properties.getProperties());
        //在把特殊配置放进去,由于close-conn 利用上面方式时,属性名就是 close-conn 而不是 closeConn,所以需要额外的一步
        pageInterceptor.setProperties(properties);
        for (SqlSessionFactory sqlSessionFactory : sqlSessionFactoryList) {
            sqlSessionFactory.getConfiguration().addInterceptor(pageInterceptor);
            sqlSessionFactory.getConfiguration().addInterceptor(gloableParamInterceptor);
            sqlSessionFactory.getConfiguration().addInterceptor(opInterceptor );
        }
    }
}

测试生效

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值