网站免费高清素材软件,谷歌官网首页,苏州小程序定制开发公司,塘坑网站建设1.问题现象
在用Mybatis plus开发的项目中#xff0c;用自带的API批量保存的方法saveBatch操作时#xff0c;发现报没有找到表的错误。
错误日志截图如下#xff1a; 表实际是存在的#xff0c;且发现其他的方法都没有问题#xff0c;包括save、update等单个的方法…1.问题现象
在用Mybatis plus开发的项目中用自带的API批量保存的方法saveBatch操作时发现报没有找到表的错误。
错误日志截图如下 表实际是存在的且发现其他的方法都没有问题包括save、update等单个的方法都是正常的。百思不得其解配置和代码都没有问题。
下面是该数据源对应的配置文件。
dataSourceConfig中配置的mapperLocations的位置
其apollo中配置的value值为classpath*:/mapper/*.xml 原来的maper.xml路径 2.问题分析
在项目中用了2个数据源上面是其中的一个数据源。
另一个数据源的mapper.xml配置的路径是 其apollo中配置的value值也为classpath*:/mapper/*.xml
本来是想保存数据到A数据库结果是执行的是另一个数据库B其实是因为 SqlSessionFactory 错误导致的。
项目中有2个数据源分别用的不同的 SqlSessionFactory。
经分析跟踪代码后发现执行saveBatch后最终调用到了这个方法 public static boolean executeBatch(Class? entityClass, Log log, ConsumerSqlSession consumer) {SqlSessionFactory sqlSessionFactory sqlSessionFactory(entityClass);SqlSessionHolder sqlSessionHolder (SqlSessionHolder) TransactionSynchronizationManager.getResource(sqlSessionFactory);boolean transaction TransactionSynchronizationManager.isSynchronizationActive();if (sqlSessionHolder ! null) {SqlSession sqlSession sqlSessionHolder.getSqlSession();//原生无法支持执行器切换当存在批量操作时会嵌套两个session的优先commit上一个session//按道理来说这里的值应该一直为false。sqlSession.commit(!transaction);}SqlSession sqlSession sqlSessionFactory.openSession(ExecutorType.BATCH);if (!transaction) {log.warn(SqlSession [ sqlSession ] was not registered for synchronization because DataSource is not transactional);}com.baomidou.mybatisplus.core.metadata.TableInfoHelper 中 initTableInfo方法会将每个实体类与对应的数据库配置保存到缓存TABLE_INFO_CACHE 中 也就是我们在创建 SqlSessionFactory 时候设置的 setMapperLocations, 设置路径下的所有mapper.xml 对应的实体都会保存对应的数据库配置。
因此我们需要将不同的 SqlSessionFactory 配置用不同的 mapper 目录来扫描。不同数据源的操作放在各自的 mapper 子目录下作区分。
上面我们定义2个SqlSessionFactory中配置的mapper文件路径是一样的。
由于 classpath*:mapper/**/*Mapper.xml 路径一样导致初始化实体类和数据库配置对应关系被覆盖的现象。 即同样的 mapper.xml 文件中被不同的 SqlSessionFactory 扫描了两次导致mapper.xml中的实体类信息只有一种SqlSessionFactory信息。
3.解决办法
需要将其中的一个数据源对应的mapper文件映射的路径改一下改成和另一个数据源配置的路径不同就可以了。
修改后的路径