本项目是ruoyi的分离版,官网只有mybatis+atomikos,本文用于集成mybatisplus+atomikos,已用于实际项目中,不同环境依赖包版本不一致可能需要自行修改。
common中引入mybatisplus,framework中引入atomikos
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.2.0</version>
</dependency>
<!--分布式事务-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jta-atomikos</artifactId>
</dependency>
注意添加user,uniqueResourceName
# 数据源配置
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.cj.jdbc.Driver
druid:
# 主库数据源
master:
url: jdbc:mysql://192.168.1.111:3306/db0
username: root
user: root
password: 123456
uniqueResourceName: MASTER
# 从库数据源
slave:
# 从数据源开关/默认关闭
enabled: false
url: jdbc:mysql://192.168.1.111:3306/db1
username: root
user: root
password: 123456
uniqueResourceName: SLAVE
# 电商数据源
ds:
# 从数据源开关/默认关闭
enabled: true
url: jdbc:mysql://192.168.1.111:3306/db3
username: root
user: root
password: 123456
uniqueResourceName: DS
package com.wms.framework.config;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.sql.DataSource;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import com.alibaba.druid.spring.boot.autoconfigure.properties.DruidStatProperties;
import com.alibaba.druid.util.Utils;
import com.wms.common.enums.DataSourceType;
import com.wms.common.utils.spring.SpringUtils;
import com.wms.framework.config.properties.DruidProperties;
import com.wms.framework.datasource.DynamicDataSource;
/**
* druid 配置多数据源
*
* @author ruoyi
*/
@Configuration
public class DruidConfig
{
@Bean
@ConfigurationProperties("spring.datasource.druid.master")
public DataSource masterDataSource(DruidProperties druidProperties)
{
DruidDataSource dataSource = DruidDataSourceBuilder.create().build();
return druidProperties.dataSource(dataSource);
}
@Bean
@ConfigurationProperties("spring.datasource.druid.slave")
@ConditionalOnProperty(prefix = "spring.datasource.druid.slave", name = "enabled", havingValue = "true")
public DataSource slaveDataSource(DruidProperties druidProperties)
{
DruidDataSource dataSource = DruidDataSourceBuilder.create().build();
return druidProperties.dataSource(dataSource);
}
@Bean
@ConfigurationProperties("spring.datasource.druid.ds")
@ConditionalOnProperty(prefix = "spring.datasource.druid.ds", name = "enabled", havingValue = "true")
public DataSource dsDataSource(DruidProperties druidProperties)
{
DruidDataSource dataSource = DruidDataSourceBuilder.create().build();
return druidProperties.dataSource(dataSource);
}
@Bean(name = "dynamicDataSource")
@Primary
public DynamicDataSource dataSource(DataSource masterDataSource)
{
Map<Object, Object> targetDataSources = new HashMap<>();
targetDataSources.put(DataSourceType.MASTER.name(), masterDataSource);
setDataSource(targetDataSources, DataSourceType.SLAVE.name(), "slaveDataSource");
setDataSource(targetDataSources, DataSourceType.DS.name(), "dsDataSource");
return new DynamicDataSource(masterDataSource, targetDataSources);
}
/**
* 设置数据源
*
* @param targetDataSources 备选数据源集合
* @param sourceName 数据源名称
* @param beanName bean名称
*/
public void setDataSource(Map<Object, Object> targetDataSources, String sourceName, String beanName)
{
try
{
DataSource dataSource = SpringUtils.getBean(beanName);
targetDataSources.put(sourceName, dataSource);
}
catch (Exception e)
{
}
}
/**
* 去除监控页面底部的广告
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
@Bean
@ConditionalOnProperty(name = "spring.datasource.druid.statViewServlet.enabled", havingValue = "true")
public FilterRegistrationBean removeDruidFilterRegistrationBean(DruidStatProperties properties)
{
// 获取web监控页面的参数
DruidStatProperties.StatViewServlet config = properties.getStatViewServlet();
// 提取common.js的配置路径
String pattern = config.getUrlPattern() != null ? config.getUrlPattern() : "/druid/*";
String commonJsPattern = pattern.replaceAll("\\*", "js/common.js");
final String filePath = "support/http/resources/js/common.js";
// 创建filter进行过滤
Filter filter = new Filter()
{
@Override
public void init(javax.servlet.FilterConfig filterConfig) throws ServletException
{
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException
{
chain.doFilter(request, response);
// 重置缓冲区,响应头不会被重置
response.resetBuffer();
// 获取common.js
String text = Utils.readFromResource(filePath);
// 正则替换banner, 除去底部的广告信息
text = text.replaceAll("
" , "");
text = text.replaceAll("powered.*?shrek.wang", "");
response.getWriter().write(text);
}
@Override
public void destroy()
{
}
};
FilterRegistrationBean registrationBean = new FilterRegistrationBean();
registrationBean.setFilter(filter);
registrationBean.addUrlPatterns(commonJsPattern);
return registrationBean;
}
}
package com.wms.common.enums;
import com.wms.common.annotation.DataSource;
import lombok.Getter;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
/**
* 数据源
*
* @author ruoyi
*/
public enum DataSourceType
{
/**
* 主库
*/
MASTER("MASTER"),
/**
* 从库
*/
SLAVE("SLAVE"),
/**
* 电商
*/
DS("DS");
@Getter
private String value;
DataSourceType(String value) {
this.value = value;
}
public static List<DataSourceType> getSlaveList() {
return Arrays.asList(SLAVE, DS);
}
/**
* 根据注解获取数据源
*
* @param dataSource
* @return
*/
public static DataSourceType getDataSourceKey(DataSource dataSource) {
if (dataSource == null) {
return MASTER;
}
if (dataSource.value() == DataSourceType.SLAVE) {
List<DataSourceType> dataSourceKeyList = DataSourceType.getSlaveList();
// FIXME 目前乱序
Collections.shuffle(dataSourceKeyList);
return dataSourceKeyList.get(0);
} else {
return dataSource.value();
}
}
}
aspectj包下新增DataSourceAspectPlus类
package com.wms.framework.aspectj;
import com.wms.common.annotation.DataSource;
import com.wms.common.enums.DataSourceType;
import com.wms.framework.datasource.DynamicDataSourceContextHolder;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.core.annotation.AnnotationUtils;
import java.lang.reflect.Method;
@Component
@Slf4j
@Aspect
@Order(-1)
public class DataSourceAspectPlus {
@Pointcut("execution(* com.wms.*.dao.*Mapper.*(..))||execution(* com.baomidou.mybatisplus.core.mapper.*Mapper.*(..)))")
public void pointCut() {
}
@Around("pointCut()")
public Object doBefore(ProceedingJoinPoint pjp) throws Throwable {
MethodSignature signature = (MethodSignature) pjp.getSignature();
Method method = signature.getMethod();
DataSource dataSource = AnnotationUtils.findAnnotation(method, DataSource.class);
DataSourceType keyEnum = DataSourceType.getDataSourceKey(dataSource);
log.info("选择的数据源:"+keyEnum.getValue());
DynamicDataSourceContextHolder.setDataSourceType(keyEnum.getValue());
Object o=pjp.proceed();
DynamicDataSourceContextHolder.clearDataSourceType();
return o;
}
@Pointcut("execution(* com.baomidou.mybatisplus.extension.service.IService.*Batch*(..)))")
public void pointCutBatch() {
}
//对mybatisplus批量操作切面
@Around("pointCutBatch()")
public Object doBeforeBatch(ProceedingJoinPoint pjp) throws Throwable {
DynamicDataSourceContextHolder.setDataSourceType(DataSourceType.MASTER.getValue());
Object o = pjp.proceed();
DynamicDataSourceContextHolder.clearDataSourceType();
return o;
}
}
datasource包下新增DynamicSqlSessionTemplate
package com.wms.framework.datasource;
import static java.lang.reflect.Proxy.newProxyInstance;
import static org.apache.ibatis.reflection.ExceptionUtil.unwrapThrowable;
import static org.mybatis.spring.SqlSessionUtils.closeSqlSession;
import static org.mybatis.spring.SqlSessionUtils.getSqlSession;
import static org.mybatis.spring.SqlSessionUtils.isSqlSessionTransactional;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.exceptions.PersistenceException;
import org.apache.ibatis.executor.BatchResult;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.MyBatisExceptionTranslator;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.dao.support.PersistenceExceptionTranslator;
/**
* 自定义SqlSessionTemplate,动态切换数据源
*
* @author ruoyi
*/
public class DynamicSqlSessionTemplate extends SqlSessionTemplate
{
private final SqlSessionFactory sqlSessionFactory;
private final ExecutorType executorType;
private final SqlSession sqlSessionProxy;
private final PersistenceExceptionTranslator exceptionTranslator;
private Map<String, SqlSessionFactory> targetSqlSessionFactorys;
private SqlSessionFactory defaultTargetSqlSessionFactory;
public DynamicSqlSessionTemplate(SqlSessionFactory sqlSessionFactory)
{
this(sqlSessionFactory, sqlSessionFactory.getConfiguration().getDefaultExecutorType());
}
public DynamicSqlSessionTemplate(SqlSessionFactory sqlSessionFactory, ExecutorType executorType)
{
this(sqlSessionFactory, executorType, new MyBatisExceptionTranslator(
sqlSessionFactory.getConfiguration().getEnvironment().getDataSource(), true));
}
public DynamicSqlSessionTemplate(SqlSessionFactory sqlSessionFactory, ExecutorType executorType,
PersistenceExceptionTranslator exceptionTranslator)
{
super(sqlSessionFactory, executorType, exceptionTranslator);
this.sqlSessionFactory = sqlSessionFactory;
this.executorType = executorType;
this.exceptionTranslator = exceptionTranslator;
this.sqlSessionProxy = (SqlSession) newProxyInstance(SqlSessionFactory.class.getClassLoader(),
new Class[] { SqlSession.class }, new DynamicSqlSessionTemplate.SqlSessionInterceptor());
this.defaultTargetSqlSessionFactory = sqlSessionFactory;
}
public void setTargetSqlSessionFactorys(Map<String, SqlSessionFactory> targetSqlSessionFactorys)
{
this.targetSqlSessionFactorys = targetSqlSessionFactorys;
}
public void setDefaultTargetSqlSessionFactory(SqlSessionFactory defaultTargetSqlSessionFactory)
{
this.defaultTargetSqlSessionFactory = defaultTargetSqlSessionFactory;
}
@Override
public SqlSessionFactory getSqlSessionFactory()
{
SqlSessionFactory targetSqlSessionFactory = targetSqlSessionFactorys
.get(DynamicDataSourceContextHolder.getDataSourceType());
if (targetSqlSessionFactory != null)
{
return targetSqlSessionFactory;
}
else if (defaultTargetSqlSessionFactory != null)
{
return defaultTargetSqlSessionFactory;
}
return this.sqlSessionFactory;
}
@Override
public Configuration getConfiguration()
{
return this.getSqlSessionFactory().getConfiguration();
}
public ExecutorType getExecutorType()
{
return this.executorType;
}
public PersistenceExceptionTranslator getPersistenceExceptionTranslator()
{
return this.exceptionTranslator;
}
/**
* {@inheritDoc}
*/
public <T> T selectOne(String statement)
{
return this.sqlSessionProxy.<T> selectOne(statement);
}
/**
* {@inheritDoc}
*/
public <T> T selectOne(String statement, Object parameter)
{
return this.sqlSessionProxy.<T> selectOne(statement, parameter);
}
/**
* {@inheritDoc}
*/
public <K, V> Map<K, V> selectMap(String statement, String mapKey)
{
return this.sqlSessionProxy.<K, V> selectMap(statement, mapKey);
}
/**
* {@inheritDoc}
*/
public <K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey)
{
return this.sqlSessionProxy.<K, V> selectMap(statement, parameter, mapKey);
}
/**
* {@inheritDoc}
*/
public <K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey, RowBounds rowBounds)
{
return this.sqlSessionProxy.<K, V> selectMap(statement, parameter, mapKey, rowBounds);
}
/**
* {@inheritDoc}
*/
public <E> List<E> selectList(String statement)
{
return this.sqlSessionProxy.<E> selectList(statement);
}
/**
* {@inheritDoc}
*/
public <E> List<E> selectList(String statement, Object parameter)
{
return this.sqlSessionProxy.<E> selectList(statement, parameter);
}
/**
* {@inheritDoc}
*/
public <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds)
{
return this.sqlSessionProxy.<E> selectList(statement, parameter, rowBounds);
}
/**
* {@inheritDoc}
*/
@SuppressWarnings("rawtypes")
public void select(String statement, ResultHandler handler)
{
this.sqlSessionProxy.select(statement, handler);
}
/**
* {@inheritDoc}
*/
@SuppressWarnings("rawtypes")
public void select(String statement, Object parameter, ResultHandler handler)
{
this.sqlSessionProxy.select(statement, parameter, handler);
}
/**
* {@inheritDoc}
*/
@SuppressWarnings("rawtypes")
public void select(String statement, Object parameter, RowBounds rowBounds, ResultHandler handler)
{
this.sqlSessionProxy.select(statement, parameter, rowBounds, handler);
}
/**
* {@inheritDoc}
*/
public int insert(String statement)
{
return this.sqlSessionProxy.insert(statement);
}
/**
* {@inheritDoc}
*/
public int insert(String statement, Object parameter)
{
return this.sqlSessionProxy.insert(statement, parameter);
}
/**
* {@inheritDoc}
*/
public int update(String statement)
{
return this.sqlSessionProxy.update(statement);
}
/**
* {@inheritDoc}
*/
public int update(String statement, Object parameter)
{
return this.sqlSessionProxy.update(statement, parameter);
}
/**
* {@inheritDoc}
*/
public int delete(String statement)
{
return this.sqlSessionProxy.delete(statement);
}
/**
* {@inheritDoc}
*/
public int delete(String statement, Object parameter)
{
return this.sqlSessionProxy.delete(statement, parameter);
}
/**
* {@inheritDoc}
*/
public <T> T getMapper(Class<T> type)
{
return getConfiguration().getMapper(type, this);
}
/**
* {@inheritDoc}
*/
public void commit()
{
throw new UnsupportedOperationException("Manual commit is not allowed over a Spring managed SqlSession");
}
/**
* {@inheritDoc}
*/
public void commit(boolean force)
{
throw new UnsupportedOperationException("Manual commit is not allowed over a Spring managed SqlSession");
}
/**
* {@inheritDoc}
*/
public void rollback()
{
throw new UnsupportedOperationException("Manual rollback is not allowed over a Spring managed SqlSession");
}
/**
* {@inheritDoc}
*/
public void rollback(boolean force)
{
throw new UnsupportedOperationException("Manual rollback is not allowed over a Spring managed SqlSession");
}
/**
* {@inheritDoc}
*/
public void close()
{
throw new UnsupportedOperationException("Manual close is not allowed over a Spring managed SqlSession");
}
/**
* {@inheritDoc}
*/
public void clearCache()
{
this.sqlSessionProxy.clearCache();
}
/**
* {@inheritDoc}
*/
public Connection getConnection()
{
return this.sqlSessionProxy.getConnection();
}
/**
* {@inheritDoc}
*
* @since 1.0.2
*/
public List<BatchResult> flushStatements()
{
return this.sqlSessionProxy.flushStatements();
}
/**
* Proxy needed to route MyBatis method calls to the proper SqlSession got from Spring's Transaction Manager It also
* unwraps exceptions thrown by {@code Method#invoke(Object, Object...)} to pass a {@code PersistenceException} to
* the {@code PersistenceExceptionTranslator}.
*/
private class SqlSessionInterceptor implements InvocationHandler
{
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
{
final SqlSession sqlSession = getSqlSession(DynamicSqlSessionTemplate.this.getSqlSessionFactory(),
DynamicSqlSessionTemplate.this.executorType, DynamicSqlSessionTemplate.this.exceptionTranslator);
try
{
Object result = method.invoke(sqlSession, args);
if (!isSqlSessionTransactional(sqlSession, DynamicSqlSessionTemplate.this.getSqlSessionFactory()))
{
sqlSession.commit(true);
}
return result;
}
catch (Throwable t)
{
Throwable unwrapped = unwrapThrowable(t);
if (DynamicSqlSessionTemplate.this.exceptionTranslator != null
&& unwrapped instanceof PersistenceException)
{
Throwable translated = DynamicSqlSessionTemplate.this.exceptionTranslator
.translateExceptionIfPossible((PersistenceException) unwrapped);
if (translated != null)
{
unwrapped = translated;
}
}
throw unwrapped;
}
finally
{
closeSqlSession(sqlSession, DynamicSqlSessionTemplate.this.getSqlSessionFactory());
}
}
}
}
config包下新增MyGlobalConfig
package com.wms.framework.config;
import com.baomidou.mybatisplus.core.config.GlobalConfig;
import com.wms.framework.datasource.DynamicSqlSessionTemplate;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
@Component
public class MyGlobalConfig extends GlobalConfig {
@Autowired
private DynamicSqlSessionTemplate sqlSessionTemplate;
private static DynamicSqlSessionTemplate mySqlSessionTemplate;
@Override
public SqlSessionFactory getSqlSessionFactory() {
return mySqlSessionTemplate.getSqlSessionFactory();
}
@PostConstruct
public void init() {
MyGlobalConfig.mySqlSessionTemplate = sqlSessionTemplate;
}
}
config中注释MyBatisConfig.java中所有的内容,新增MybatisPlusConfig
package com.wms.framework.config;
import com.atomikos.jdbc.nonxa.AtomikosNonXADataSourceBean;
import com.baomidou.mybatisplus.autoconfigure.SpringBootVFS;
import com.baomidou.mybatisplus.core.MybatisConfiguration;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import com.github.pagehelper.PageInterceptor;
import com.wms.common.enums.DataSourceType;
import com.wms.common.utils.StringUtils;
import com.wms.common.utils.bean.BeanUtils;
import com.wms.common.utils.spring.SpringUtils;
import com.wms.framework.datasource.DynamicSqlSessionTemplate;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.type.JdbcType;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
/**
* Mybatis Plus 配置
*
* @author ruoyi
*/
@EnableTransactionManagement(proxyTargetClass = true)
@Configuration
public class MybatisPlusConfig
{
@Bean
@ConfigurationProperties("spring.datasource.druid.master")
public AtomikosNonXADataSourceBean userMaster() {
//也可以直接return new AtomikosNonXADataSourceBean();
return DataSourceBuilder.create().type(AtomikosNonXADataSourceBean.class).build();
}
@Bean
@ConfigurationProperties("spring.datasource.druid.ds")
@ConditionalOnProperty(prefix = "spring.datasource.druid.ds", name = "enabled", havingValue = "true")
public AtomikosNonXADataSourceBean userSlave0() {
return DataSourceBuilder.create().type(AtomikosNonXADataSourceBean.class).build();
}
@Bean
@ConfigurationProperties("spring.datasource.druid.slave")
@ConditionalOnProperty(prefix = "spring.datasource.druid.slave", name = "enabled", havingValue = "true")
public AtomikosNonXADataSourceBean userSlave1() {
return DataSourceBuilder.create().type(AtomikosNonXADataSourceBean.class).build();
}
@Bean(name = "sqlSessionTemplate")
public DynamicSqlSessionTemplate customSqlSessionTemplate() throws Exception {
Map<String, SqlSessionFactory> sqlSessionFactoryMap = new HashMap<String, SqlSessionFactory>();
sqlSessionFactoryMap.put(DataSourceType.MASTER.getValue(),createSqlSessionFactory(userMaster()));
try
{
sqlSessionFactoryMap.put(DataSourceType.DS.getValue(), createSqlSessionFactory(userSlave0()));
}
catch (Exception e)
{
}
try
{
sqlSessionFactoryMap.put(DataSourceType.SLAVE.getValue(), createSqlSessionFactory(userSlave1()));
}
catch (Exception e)
{
}
DynamicSqlSessionTemplate sqlSessionTemplate = new DynamicSqlSessionTemplate(sqlSessionFactoryMap.get(DataSourceType.MASTER.getValue()));
sqlSessionTemplate.setTargetSqlSessionFactorys(sqlSessionFactoryMap);
return sqlSessionTemplate;
}
/**
* 创建数据源
*
* @param dataSource
* @return
*/
private SqlSessionFactory createSqlSessionFactory(AtomikosNonXADataSourceBean dataSource) throws Exception {
dataSource.setMaxPoolSize(10);
dataSource.setMinPoolSize(2);
dataSource.setPoolSize(2);
dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
dataSource.setMaxIdleTime(60);//最大闲置时间,超过最小连接池的连接将关闭
dataSource.setMaxLifetime(1200);//连接最大闲置时间 单位s 全部的连接超时将关闭
dataSource.setMaintenanceInterval(60);//定时维护线程周期 单位秒
//以上配置可提取到.yml内通过ConfigurationProperties注解注入
dataSource.init();//项目启动则初始化连接
MybatisSqlSessionFactoryBean sqlSessionFactory = new MybatisSqlSessionFactoryBean();
sqlSessionFactory.setDataSource(dataSource);
sqlSessionFactory.setTypeAliasesPackage("com.wms.**.domain");
if(DataSourceType.DS.getValue().equals(dataSource.getUniqueResourceName())){
sqlSessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/dsBusiness/dsBaseGoods/*Mapper.xml"));
}else if(DataSourceType.SLAVE.getValue().equals(dataSource.getUniqueResourceName())){
sqlSessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/business/haiguanDataWms/*Mapper.xml"));
}else{
sqlSessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/**/*Mapper.xml"));
}
sqlSessionFactory.setVfs(SpringBootVFS.class);
sqlSessionFactory.setPlugins(pageInterceptor());
MybatisConfiguration configuration = new MybatisConfiguration();
//configuration.setDefaultScriptingLanguage(MybatisXMLLanguageDriver.class);
configuration.setJdbcTypeForNull(JdbcType.NULL);
configuration.setMapUnderscoreToCamelCase(false);
configuration.setCacheEnabled(false);
configuration.setMapUnderscoreToCamelCase(true);
sqlSessionFactory.setConfiguration(configuration);
//重写了GlobalConfig的MyGlobalConfig注入到sqlSessionFactory使其生效
MyGlobalConfig globalConfig = new MyGlobalConfig();
sqlSessionFactory.setGlobalConfig(globalConfig);
sqlSessionFactory.afterPropertiesSet();
return sqlSessionFactory.getObject();
}
@Bean
PageInterceptor pageInterceptor(){
PageInterceptor pageInterceptor = new PageInterceptor();
Properties properties = new Properties();
properties.setProperty("helperDialect", "mysql");
pageInterceptor.setProperties(properties); // 由此可进入源码,
return pageInterceptor;
}
}
注意:pageInterceptor必须要有,否则分页失效
在业务层加入数据源注解,主库不需要加入注解,其他从库需要
@Service
@DataSource(value = DataSourceType.DS)
public class DsBaseGoodsServiceImpl extends ServiceImpl<DsBaseGoodsMapper, DsBaseGoods> implements IDsBaseGoodsService
最后,在方法是加入 @Transactional即可
@Override
@Transactional
public AjaxResult addArrivalNotice(DsArrivalNoticeHead dsArrivalNoticeHead) {
DsBaseGoods dsBaseGoods1 = new DsBaseGoods();
dsBaseGoods1.setBaseGoodsId("3146");
dsBaseGoods1.setWhNo("1");
dsBaseGoodsService.updateDsBaseGoods(dsBaseGoods1);
// List dsBaseGoods = dsBaseGoodsService.selectDsBaseGoodsList(new DsBaseGoods());
WmsCarInfo wmsCarInfo = new WmsCarInfo();
wmsCarInfo.setCarInfoId(IdUtils.fastSimpleUUID());
wmsCarInfo.setDriverName("123");
wmsCarInfoService.save(wmsCarInfo);
//校验仓库编码是否存在
int i =1/0;
//判断通知单号是否已经存在
//获取批次号
return null;
}