MybatisPlus多数据源下报错invalid bound statement not found

标题:解决 MyBatis-Plus 多数据源配置中 invalid bound statement not found 的问题

一、环境说明

当前项目使用的依赖版本如下:

xml

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.2.0</version>
</dependency>

<!-- 并未引入 mybatis-plus 官方的多数据源依赖 -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
    <version>2.5.7</version>
</dependency>
二、多数据源的具体配置
启动类中的 @MapperScan 配置

java

@MapperScans({
    @MapperScan(basePackages = {"com.aaa.dao"}, sqlSessionFactoryRef = DatasourceConf.SESSION_FACTORY),
    @MapperScan(basePackages = {"com.bbb.dao"}, sqlSessionFactoryRef = OtherDatasourceConf.OTHER_SESSION_FACTORY)
})
主数据源配置类

java

@Configuration
public class DatasourceConf {
    public static final String SESSION_FACTORY = "SessionFactory";

    @Primary
    @Bean(name = SESSION_FACTORY)
    public SqlSessionFactory dianOrderSessionFactory(MybatisProperties properties) throws Exception {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(secondDatasource());
        //...
    }

    @Primary
    @Bean
    public DataSource secondDatasource() {
        return new HikariDataSource(secondHikariConfig());
    }

    @Bean
    @ConfigurationProperties(prefix = "spring.datasource.aaa.hikari")
    public HikariConfig secondHikariConfig() {
        return new HikariConfig();
    }
}
其他数据源配置类

java

@Configuration
public class OtherDatasourceConf {
    public static final String OTHER_SESSION_FACTORY = "otherSessionFactory";

    @Bean(name = OTHER_SESSION_FACTORY)
    public SqlSessionFactory otherSessionFactory(MybatisProperties properties) throws Exception {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(otherDataSource());
        //....
    }

    @Bean
    public DataSource otherDataSource() {
        return new HikariDataSource(otherHikariConfig());
    }

    @Bean
    @ConfigurationProperties(prefix = "spring.datasource.hikari")
    public HikariConfig otherHikariConfig() {
        return new HikariConfig();
    }
}
三、问题描述

多数据源配置完成后,发现 基于 XML 配置的 SQL 执行正常。但是如果调用 MyBatis-Plus 提供的 内置方法(如 selectByIdupdateById 等),会抛出如下异常:

txt

Invalid bound statement (not found)
四、原因分析

通过源码分析发现,MyBatis-Plus 默认会通过 MybatisPlusAutoConfiguration 自动配置 SqlSessionFactoryBean,如下:

java

@Configuration
@ConditionalOnClass({SqlSessionFactory.class, SqlSessionFactoryBean.class})
@ConditionalOnSingleCandidate(DataSource.class)
@EnableConfigurationProperties(MybatisPlusProperties.class)
@AutoConfigureAfter(DataSourceAutoConfiguration.class)
public class MybatisPlusAutoConfiguration implements InitializingBean {

    @Bean
    @ConditionalOnMissingBean
    public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
        // 注意这里使用的是 MybatisSqlSessionFactoryBean 而非 SqlSessionFactoryBean
        MybatisSqlSessionFactoryBean factory = new MybatisSqlSessionFactoryBean();
        factory.setDataSource(dataSource);
        //...
        return factory.getObject();
    }
}

问题在于:多数据源的配置中,每个数据源需要手动配置 SqlSessionFactory,直接导致 MybatisPlusAutoConfiguration 中的自动配置 SqlSessionFactory 无法生效。手动配置的 SqlSessionFactoryBean 为 MyBatis 的标准实现,而非 MyBatis-Plus 的 MybatisSqlSessionFactoryBean,因此无法加载 MyBatis-Plus 的基础功能,导致出现了 Invalid bound statement 异常。

五、解决方案

为了解决上述问题,需要在多数据源配置类中,将标准 SqlSessionFactoryBean 修改为 Mybatis-Plus 提供的 MybatisSqlSessionFactoryBean ,并确保使用的是 MybatisPlusProperties,而非 MybatisProperties。以下是修正后的代码:

修改主数据源配置类

java

@Configuration
public class DatasourceConf {
    public static final String SESSION_FACTORY = "SessionFactory";

    @Primary
    @Bean(name = SESSION_FACTORY)
    public SqlSessionFactory dianOrderSessionFactory(MybatisPlusProperties properties) throws Exception {
        MybatisSqlSessionFactoryBean sqlSessionFactoryBean = new MybatisSqlSessionFactoryBean(); // 使用 MybatisSqlSessionFactoryBean
        sqlSessionFactoryBean.setDataSource(secondDatasource());
        sqlSessionFactoryBean.setConfiguration(properties.getConfiguration());
        sqlSessionFactoryBean.setMapperLocations(properties.resolveMapperLocations());
        //...
        return sqlSessionFactoryBean.getObject();
    }

    @Primary
    @Bean
    public DataSource secondDatasource() {
        return new HikariDataSource(secondHikariConfig());
    }

    @Bean
    @ConfigurationProperties(prefix = "spring.datasource.aaa.hikari")
    public HikariConfig secondHikariConfig() {
        return new HikariConfig();
    }
}
修改其他数据源配置类

java

@Configuration
public class OtherDatasourceConf {
    public static final String OTHER_SESSION_FACTORY = "otherSessionFactory";

    @Bean(name = OTHER_SESSION_FACTORY)
    public SqlSessionFactory otherSessionFactory(MybatisPlusProperties properties) throws Exception {
        MybatisSqlSessionFactoryBean sqlSessionFactoryBean = new MybatisSqlSessionFactoryBean(); // 使用 MybatisSqlSessionFactoryBean
        sqlSessionFactoryBean.setDataSource(otherDataSource());
        sqlSessionFactoryBean.setConfiguration(properties.getConfiguration());
        sqlSessionFactoryBean.setMapperLocations(properties.resolveMapperLocations());
        //...
        return sqlSessionFactoryBean.getObject();
    }

    @Bean
    public DataSource otherDataSource() {
        return new HikariDataSource(otherHikariConfig());
    }

    @Bean
    @ConfigurationProperties(prefix = "spring.datasource.hikari")
    public HikariConfig otherHikariConfig() {
        return new HikariConfig();
    }
}
六、注意事项
  1. MybatisSqlSessionFactoryBean

    • MyBatis-Plus 针对 MyBatis 扩展的 SqlSessionFactoryBean,负责加载内置基础方法及增强功能。
  2. MybatisPlusProperties

    • 确保数据源配置中注入的属性来源为 MybatisPlusProperties,这样可以正确加载 MyBatis-Plus 的 Mapper 配置。
  3. MapperScan 配置

    • 多数据源的 Mapper 需要通过 @MapperScan 注解,指定对应的 SqlSessionFactory
七、小结

通过将标准 SqlSessionFactoryBean 替换为 MyBatis-Plus 的 MybatisSqlSessionFactoryBean,并正确加载 MybatisPlusProperties,可以成功解决多数据源场景下 invalid bound statement (not found) 的问题。如果你在实际操作中遇到更多问题,可以随时留言交流!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值