記一次mybatis-plus自定義sql注入器不起做用的問題

以前本身寫過一個關於mybatis-plus多表聯查的組件,原理是用到了mybatis-plus擴展的口(sql注入),即繼承DefaultSqlInjectorspring

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

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

}

可是集成到別的項目發現不起做用,很奇怪,batis-plus自帶的查詢沒問題,但就是自定義注入器不行,不該該是初始化的時候從spring容器找嗎。。。?sql

因而經過斷點跟蹤,發現注入器是GlobalConfig 的屬性,而且有一個默認值緩存

/**
 * SQL注入器
 */
private ISqlInjector sqlInjector = new DefaultSqlInjector();

顯然以前確定賦值過一次,繼續往前追蹤starter有個MybatisPlusAutoConfiguration裏面有個初始化beanmybatis

@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初始化這一塊的代碼。app

最後總結一下集成項目的時候一些bean的初始化要注意一些屬性的初始化,否則可能會形成一些未知的問題!ide

相關文章
相關標籤/搜索