mysql防注入插件_Mybatis插件-自定义拦截器

Mybatis插件通常意义就是自定义的拦截器,基于业务需求,需要在进行数据库查询之前或者之后进行拦截。如从线程变量中传递参数,动态修改SQL来实现数据的筛选,而不是每次在查询前,手动将条件注入到查询中;或者在不破坏原有查询逻辑时,动态的添加字段insert/update等;

类型有:

Executor、ParameterHandler、ResultSetHandler、StatementHandler

拦截器使用:

》@intercepts声明该类为拦截器,@signature声明拦截对象;

》method为我们需要拦截的prepare方法,type为所要拦截的接口类,args为prepare方法的参数;

》拦截器顺序

sqlSessionFactory.getConfiguration().InterceptorChain中的 pluginAll中遍历所有拦截器

通过调用拦截器的plugin()方法生成动态代理对象;

第一次循环的代理对象是原始的StatementHandler返回的是Plugin类型的代理类P1

第二次循环代理的对象是P1返回的是Plugin类型的代理类P2;

执行顺序并非1 > 2 >3,而是3 > 2 > 1

Interceptor3:{

Interceptor2: {

Interceptor1: {

target: Executor

}

}

}

举个栗子:

当需要根据当前用户的不同属性判别用户的数据权限,在不破坏原有数据查询逻辑的情况下,可通过拦截器实现数据权限过滤:

自定义EntitledQueryInterceptor 注入spring bean

@Intercepts(

{

@Signature(type = ParameterHandler.class, method = "setParameters", args = {PreparedStatement.class}),

@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 EntitledQueryInterceptor implements Interceptor {

@Override

public Object intercept(Invocation invocation) throws Throwable {

}

@Override

public Object plugin(Object target) {

return (target instanceof Executor) ? Plugin.wrap(target, this) : target;

}

@Override

public void setProperties(Properties properties) {

}

}

在实际使用时,配合PageHelper等插件可能会产生冲突问题,PageInterceptor是executor拦截器,如果sqlSessionFactory.getConfiguration().InterceptorChain后加入了PageInterceptor,那么运行时就先执行PageInterceptor,此时如果自定义的拦截器添加了新参数在SQL中,就会出现参数NotFound error。

org.apache.ibatis.binding.BindingException: Parameter '*' not found. Available parameters are [*,*....]

解决办法:

》自定义spring configuration 如:

@Configuration

@AutoConfigureAfter(PageHelperAutoConfiguration.class)

public class CustomMybatisAutoConfiguration {

@Autowired

private List sqlSessionFactoryList;

@PostConstruct

public void addMyInterceptor() {

for (SqlSessionFactory sqlSessionFactory : sqlSessionFactoryList) {

sqlSessionFactory.getConfiguration().addInterceptor(new EntitledQueryInterceptor(entitledMapperValueResolver()));

}

}

@Bean

public EntitledMapperValueResolver entitledMapperValueResolver() {

return new EntitledMapperValueResolver();

}

}

PS:责任链模式

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值