记一次mybatis-plus自定义sql注入器不起作用的问题

之前自己写过一个关于mybatis-plus多表联查的组件,原理是用到了mybatis-plus扩展的口(sql注入),即继承DefaultSqlInjector

/**

  • @author chengang
    */
    @Component
    public class MySqlInjector extends DefaultSqlInjector {

    @Override
    public List getMethodList(Class<?> mapperClass) {
    List methodList = super.getMethodList(mapperClass);
    methodList.add(new JoinMethod());
    return methodList;
    }

}
但是集成到别的项目发现不起作用,很奇怪,batis-plus自带的查询没问题,但就是自定义注入器不行,不应该是初始化的时候从spring容器找吗。。。?

于是通过断点跟踪,发现注入器是GlobalConfig 的属性,并且有一个默认值

/**

  • SQL注入器
    */
    private ISqlInjector sqlInjector = new DefaultSqlInjector();
    显然之前肯定赋值过一次,继续往前追踪starter有个MybatisPlusAutoConfiguration里面有个初始化bean

@SuppressWarnings(“SpringJavaInjectionPointsAutowiringInspection”)
@Bean
@ConditionalOnMissingBean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
// TODO 使用 MybatisSqlSessionFactoryBean 而不是 SqlSessionFactoryBean
MybatisSqlSessionFactoryBean factory = new MybatisSqlSessionFactoryBean();
factory.setDataSource(dataSource);
factory.setVfs(SpringBootVFS.class);
if (StringUtils.hasText(this.properties.getConfigLocation())) {
factory.setConfigLocation(this.resourceLoader.getResource(this.properties.getConfigLocation()));
}
applyConfiguration(factory);
if (this.properties.getConfigurationProperties() != null) {
factory.setConfigurationProperties(this.properties.getConfigurationProperties());
}
if (!ObjectUtils.isEmpty(this.interceptors)) {
factory.setPlugins(this.interceptors);
}
if (this.databaseIdProvider != null) {
factory.setDatabaseIdProvider(this.databaseIdProvider);
}
if (StringUtils.hasLength(this.properties.getTypeAliasesPackage())) {
factory.setTypeAliasesPackage(this.properties.getTypeAliasesPackage());
}
if (this.properties.getTypeAliasesSuperType() != null) {
factory.setTypeAliasesSuperType(this.properties.getTypeAliasesSuperType());
}
if (StringUtils.hasLength(this.properties.getTypeHandlersPackage())) {
factory.setTypeHandlersPackage(this.properties.getTypeHandlersPackage());
}
if (!ObjectUtils.isEmpty(this.typeHandlers)) {
factory.setTypeHandlers(this.typeHandlers);
}
Resource[] mapperLocations = this.properties.resolveMapperLocations();
if (!ObjectUtils.isEmpty(mapperLocations)) {
factory.setMapperLocations(mapperLocations);
}
// TODO 修改源码支持定义 TransactionFactory
this.getBeanThen(TransactionFactory.class, factory::setTransactionFactory);

// TODO 对源码做了一定的修改(因为源码适配了老旧的mybatis版本,但我们不需要适配)
Class<? extends LanguageDriver> defaultLanguageDriver = this.properties.getDefaultScriptingLanguageDriver();
if (!ObjectUtils.isEmpty(this.languageDrivers)) {
    factory.setScriptingLanguageDrivers(this.languageDrivers);
}
Optional.ofNullable(defaultLanguageDriver).ifPresent(factory::setDefaultScriptingLanguageDriver);

// TODO 自定义枚举包
if (StringUtils.hasLength(this.properties.getTypeEnumsPackage())) {
    factory.setTypeEnumsPackage(this.properties.getTypeEnumsPackage());
}
// TODO 此处必为非 NULL
GlobalConfig globalConfig = this.properties.getGlobalConfig();//这里是初始化全局缓存的最初开始
// TODO 注入填充器
this.getBeanThen(MetaObjectHandler.class, globalConfig::setMetaObjectHandler);
// TODO 注入主键生成器
this.getBeanThen(IKeyGenerator.class, i -> globalConfig.getDbConfig().setKeyGenerator(i));//这里注入自定义的主键生成器
// TODO 注入sql注入器
this.getBeanThen(ISqlInjector.class, globalConfig::setSqlInjector);//这里设置注入器属性,注入自定义注入器就在这里
// TODO 注入ID生成器
this.getBeanThen(IdentifierGenerator.class, globalConfig::setIdentifierGenerator);
// TODO 设置 GlobalConfig 到 MybatisSqlSessionFactoryBean
factory.setGlobalConfig(globalConfig);
return factory.getObject();

}
到这里基本就很明确了,当你使用自定义SqlSessionFactory 的时候,本方法不会执行,也就不会初始化刚开始自定义的sql注入器了,知道这个基本问题就解决了,把集成项目的SqlSessionFactory 去掉,或者加上GlobalConfig初始化这一块的代码。

最后总结一下集成项目的时候一些bean的初始化要注意一些属性的初始化,不然可能会造成一些未知的问题!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值