论mybatisPlus 连表插件(mybatis-plus-join) 与自定义SQL注入器冲突

2023-10-21 12:37:52 浏览数 (1)

最近在写代码中,出现了一个比较有意思的报错,记录下来

mybatis-plus 的好处就不用多说了,带给我们最大的好处就是不用再重复编写那些简单的sql语句。但是多表查询的时候却还是不得不用xml来解决,但是想要偷懒,不想写xml,于是在同事的推荐下了解了 mybatis-plus-join于是乎就拿下来试用下。

很不错,在现在写代码全是lomda::编码方式的情况下,很合适,它的使用大概就是下面这样:

测试了下,没问题,能够解决目前场景下的问题。

而在把它导入在项目中时,问题就来了,由于项目里有写过自定义的sql注入器,加上连表插件后,启动居然报错了,于是乎查看源码分析原因,发现连表插件里也用到了sql注入器,原来如此,现在问题显而易见了。

因为连表插件里和项目原先配置里都有sql注入器,导致springboot容器在实例化类时不知选择哪一个,所以报错:

Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed。

看错误原因就知道该如何解决了,在项目原有的sql注入器实现类上加上@Primary 注解,意思是默认优先选择:

代码语言:javascript复制
public class MybatisPlusConfig {
    /**
     * 分页插件 
     */
    @Bean
    public MybatisPlusInterceptor paginationInterceptor() {
      
        //连表插件
        interceptor.addInnerInterceptor(new MPJInterceptor());
        //多租户,垃圾sql拦截插件......
        return interceptor;
    }
    
    /**
     * sql注入
     */
    @Bean
    @Primary
    public MySqlInjector myLogicSqlInjector() {
        return new MySqlInjector();
    }
}

这样虽然解决了报错问题,但是新的问题又出现了,由于设置了@Primary 默认加载,意味着连表插件里的功能就没法加载进去了,所以需要手动把里面实现的方法重新加入到项目里原有的sql注入器里:

1、先查看连表插件的源码,找到sql注入器的加载类,如下

代码语言:javascript复制
package com.github.yulichang.injector;
 
import com.baomidou.mybatisplus.core.injector.AbstractMethod;
import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;
import com.github.yulichang.method.*;
 
import java.util.List;
 
/**
 * SQL 注入器
 *
 * @author yulichang
 * @see DefaultSqlInjector
 */
public class MPJSqlInjector extends DefaultSqlInjector {
 
    @Override
    public List<AbstractMethod> getMethodList(Class<?> mapperClass) {
        List<AbstractMethod> list = super.getMethodList(mapperClass);
        list.add(new SelectJoinOne());
        list.add(new SelectJoinList());
        list.add(new SelectJoinPage());
        list.add(new SelectJoinMap());
        list.add(new SelectJoinMaps());
        list.add(new SelectJoinMapsPage());
        return list;
    }
}

2、将注入器里添加的方法添加到项目原有的sql注入器里,如下:

代码语言:javascript复制
package com.qhzx.td.config;

import java.util.List;

import com.baomidou.mybatisplus.core.injector.AbstractMethod;
import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;
import com.baomidou.mybatisplus.extension.injector.methods.InsertBatchSomeColumn;
import com.github.yulichang.injector.MPJSqlInjector;
import com.github.yulichang.method.*;
import org.springframework.stereotype.Component;

@Component
public class EasySqlInjector extends DefaultSqlInjector {

    @Override
    public List<AbstractMethod> getMethodList(Class<?> mapperClass) {
        List<AbstractMethod> methodList = super.getMethodList(mapperClass);
        // InsertBatchMethod,UpdateBatchMethod
        methodList.add(new InsertBatchMethod());
        methodList.add(new UpdateBatchMethod());

        //多表查询sql注入 从连表插件里移植过来的
        methodList.add(new SelectJoinCount());
        methodList.add(new SelectJoinOne());
        methodList.add(new SelectJoinList());
        methodList.add(new SelectJoinPage());
        methodList.add(new SelectJoinMap());
        methodList.add(new SelectJoinMaps());
        methodList.add(new SelectJoinMapsPage());
        return methodList;
    }

}

最后保存代码,完美启动,测试功能正常,OK

0 人点赞