源码分析 - 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<ClassPathResource> 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方式不一样。

源码分析 - MyBatis Plus 多数据源踩坑_第1张图片

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

源码分析 - MyBatis Plus 多数据源踩坑_第2张图片

源码分析 - MyBatis Plus 多数据源踩坑_第3张图片

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

globalConfig.signGlobalConfig(bean.getObject());

源码分析 - MyBatis Plus 多数据源踩坑_第4张图片

重启项目,测试通过。

新版已修复

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

源码分析 - MyBatis Plus 多数据源踩坑_第5张图片

源码分析 - MyBatis Plus 多数据源踩坑_第6张图片

源码分析 - MyBatis Plus 多数据源踩坑_第7张图片

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


除非注明,否则均为”攻城狮·正“原创文章,请注明出处。

本文链接:https://engr-z.com/546.html

你可能感兴趣的:(java,mybatis,plus,mybatis,mysql,java)