• 源码分析 – MyBatis Plus 多数据源踩坑


    公司准备把报表数据库从MySQL迁到TiDB,先用几个功能试点。于是在系统上需要配置多个数据源。之前在上家公司用MyBatis时配置过4个数据源,MyBatis Plus下应该是大同小异。不出意外的话就要出意外,结果还是踩了坑。

    环境

    MyBatis Plus版本:3.0.6

    配置

    项目中使用shardingjdbc管理数据源,这里只贴其中一个配置

    @Bean("tidbSqlSessionFactory")
    public SqlSessionFactoryBean getTidbSqlSessionFactory(@Autowired ApplicationContext context, @Autowired MetaObjectHandler metaObjectHandler) throws Exception {
    
        MasterSlaveDataSource dataSource = (MasterSlaveDataSource) context.getBean(DataSource.class);
        DataSource tidbDataSource = dataSource.getConnection().getDataSourceMap().get("ds-tidb");
    
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(tidbDataSource);
    
        List resourceList = new ArrayList<>();
        String path = MybatisPlusConfig.class.getResource("/mapper2").getPath();
        FileUtils.scan(path, f -> {
            if (f.getPath().endsWith(".xml")) {
                String xml = f.getPath().substring(f.getPath().lastIndexOf("mapper2"));
                log.info("loading -> {}", xml);
                resourceList.add(new ClassPathResource(xml));
            }
        });
        bean.setMapperLocations(resourceList.toArray(new Resource[resourceList.size()]));
    
        MybatisConfiguration mybatisConfig = new MybatisConfiguration();
        mybatisConfig.addInterceptor(new PaginationInterceptor());
        mybatisConfig.addInterceptor(new OptimisticLockerInterceptor());
        bean.setConfiguration(mybatisConfig);
    
        GlobalConfig globalConfig = GlobalConfigUtils.getGlobalConfig(mybatisConfig);
        globalConfig.setSqlInjector(new LogicSqlInjector());
        globalConfig.setMetaObjectHandler(metaObjectHandler);
    
        return bean;
    }

    使用注解扫描

    @MapperScan(basePackages = "com.ienjoys.reportform.dao2", sqlSessionFactoryRef = "tidbSqlSessionFactory")

    也可以创建 MapperScannerConfigurer 配置扫描

    遇坑

    启动项目正常,点击测试了一些功能也没发现问题。在跑定时任务时抛出错误:

    定位错误行,未获取到 sqlSessionFactory 。

    查看源码发现,MyBatis Plus 的 IService 接口,save 方法和 saveBatch 方法获取sqlSessionFactory方式不一样。

    save方法是获取baseMapper,而批量操作的saveBatch方法是从全局配置 GlobalConfig 里获取的。

    在配置多数据源时,每个sqlSession的配置是独立的,不能共用一个,否则会出现部分配置被覆盖。而自己创建 GlobalConfig ,sqlSessionFactory是没有指定的。需要手动设置。

    globalConfig.signGlobalConfig(bean.getObject());

    重启项目,测试通过。

    新版已修复

    我在github上查看最新的MyBatis Plus源码,发现该问题在3.4.0之后的版本修复。以下是最新源码:

    软件开发是一个持续过程,平时用的依赖库也要不断更新才行。

  • 相关阅读:
    正则表达式2
    pytorch入门,deep-learning-for-image-processing-master的test3-vggnet
    【嵌入式开源库】timeslice的使用,完全解耦的时间片轮询框架构
    Leetcode 647. 回文子串
    工业机器人在汽车制造行业中的应用
    k8s、helm删除不掉资源问题处理
    插入排序(直接、二分)
    【机器学习】SVM入门-硬间隔模型
    还有人以为高并发=多线程吗?跟着大佬带你了解二者关系与区别,面试难题轻松拿下!
    谷粒商城-基础篇Day04-品牌管理
  • 原文地址:https://blog.csdn.net/YYniannian/article/details/125866929