1. myatis-plus多数据源使用,我用的不是dymanic datasource,而是自定义的多数据源配置方式,如下图,相信很多人都用过,由于我不是介绍怎么使用多数据源,所以具体的我就不介绍了。
@Configuration @MapperScan(basePackages = "com.lyten.custom.system.mapper", sqlSessionTemplateRef = "sysSqlSessionTemplate") public class ConfigDataSource extends MybatisplusMultiConfig { @Autowired private ConfigDataSourceProperty configDataSourceProperty; @Bean(name = "sysds") public DataSource dataSource() { return super.dataSource(configDataSourceProperty); } public SqlSessionFactory sqlSessionFactory() throws Exception { DataSource ds = SpringUtils.getBean("sysds"); return super.sqlSessionFactory(ds, configDataSourceProperty.getMapperLocations()); } @DependsOn("sysds") @Bean(name = "sysSqlSessionTemplate") public SqlSessionTemplate sqlSessionTemplate() throws Exception { return super.sqlSessionTemplate(sqlSessionFactory()); } @Bean("sysTransactionManager") public PlatformTransactionManager sysTransactionManager(@Qualifier("sysds") DataSource dataSource){ return new DataSourceTransactionManager(dataSource); } }
这里有个很要注意的地方,我是有多个模块,每个模块都有resources,resource目录下都有mapper目录,里面装着模块各自的xxxMapper.xml。三个模块的目录结构相同。例如A,B,C三个模块吧。当我从前端调A模块的插入方式时,会报表不存在,查看报错,我插入的是A.sysUser,但报错是插入了B.sysUser。我检查了数据源配置,@MapperScan扫描路径并没有错,怎么会插到别的用户下了呢?通过调试到baseMapper里,发现到了SqlHelper时,居然是B的数据源,并且statement也是乱的,B的statement把A的mapper也装进去了,在这里我才知道不是@MapperScan扫描mapper的问题,是扫描xml时出了问题,这问题就在于三个模块的xml路径完全一样,因此在yml中配置都是mapperLocations: classpath*:mapper/*Mapper.xml。后面,我把每个模块都改了下,例如A的xml在resources/system/mapper里,同时mapperLocations也改成了classpath*:system/mapper/*Mapper.xml,这样就解决了这个问题。
第二个问题,@Transactional使用的注意点,当然,我目前出问题,主要是saveBatch这个方法,像save、update方法都没有问题。主要是什么呢,还是同一个项目,有三个数据源,也有创建了三个TransactionManager的bean,在方法调用时,也明确声明了
@Override @Transactional(rollbackFor = Exception.class,transactionManager = "sysTransactionManager") public boolean copy(String sourceSubId, String targetSubId, String userId) { //
return saveBatch(sysCustomDicTemplateList); }
这个方法中间的查询什么的都没有问题,但执行saveBatch的时候,报了No qualifying bean of type 'org.springframework.transaction.TransactionManager' available: expected single matching bean but found 3:,有三个TransactionManager,它不知道该用哪个。我查了saveBatch方法,如下,这是com/baomidou/mybatisplus/extension/service/impl/ServiceImpl.java
/** * 批量插入 * * @param entityList ignore * @param batchSize ignore * @return ignore */ @Transactional(rollbackFor = Exception.class) @Override public boolean saveBatch(Collection<T> entityList, int batchSize) { String sqlStatement = getSqlStatement(SqlMethod.INSERT_ONE); return executeBatch(entityList, batchSize, (sqlSession, entity) -> sqlSession.insert(sqlStatement, entity)); }
WHF?这里不也是@Transactional么?没有设置事务的传播类型,不是会加入已有事务么?怎么会报没事务呢?具体原因有点复杂,就是它这个方法在后面执行中,会去取默认的TransactionManager,而不是取我设置的那个,但是我程序中没有设置默认的TransactionManager,因此,它就会报这个错,解决办法有两个,一个是设置一个默认的TransactionManager,但不行,因为我有三个数据源。那第二个就是重写saveBatch方法了。
@Transactional(rollbackFor = Exception.class,transactionManager = "apisysTransactionManager") public boolean saveBatch(List<SysCustomDicTemplate> sysCustomDicTemplateList) { String sqlStatement = getSqlStatement(SqlMethod.INSERT_ONE); return executeBatch(sysCustomDicTemplateList, sysCustomDicTemplateList.size(), (sqlSession, entity) -> sqlSession.insert(sqlStatement, entity)); }
两个问题其实解决都不复杂,就是发现这些问题,花了很长时间。
标签:mapper,return,saveBatch,数据源,Transactional,plus,public From: https://www.cnblogs.com/lythen/p/16949284.html