**
**
配置文件
#tomcat配置
server.port=8888
server.servlet.session.timeout=1800m
server.tomcat.uri-encoding=UTF-8
#s数据压缩
server.compression.enabled=true
server.compression.mime-types=application/json,application/xml,text/html,text/xml,text/plain
server.compression.min-response-size=100
#mybatis插件配置
mybatis-plus.configuration.map-underscore-to-camel-case=true
mybatis-plus.mapper-locations=classpath:mapper/*Mapper.xml
mybatis-plus.typeAliasesPackage=com.dfdk.datamanage.entity
#数据库连接池配置
#drive数据库
spring.datasource.druid.drive.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.druid.drive.url=jdbc:mysql://192.168.43\
.117:3306/drive?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT
spring.datasource.druid.drive.username=root
spring.datasource.druid.drive.password=root
#scada数据库
#spring.datasource.scada.driver-class-name=oracle.jdbc.OracleDriver
#spring.datasource.url=jdbc:oracle:thin:@//172.20.51.66:1521/orcl
spring.datasource.druid.scada.driver-class-name=oracle.jdbc.OracleDriver
spring.datasource.druid.scada.url=jdbc:oracle:thin:@//127.0.0.1:1521/orcl
spring.datasource.druid.scada.username=system
spring.datasource.druid.scada.password=123456
spring.datasource.druid.initialSize=5
spring.datasource.druid.minIdle=5
spring.datasource.druid.maxActive=20
spring.datasource.druid.maxWait=60000
spring.datasource.druid.time-between-eviction-runs-millis=60000
spring.datasource.druid.min-evictable-idle-time-millis=300000
spring.datasource.druid.validation-query=SELECT 1 FROM DUAL
spring.datasource.druid.test-while-idle=true
spring.datasource.druid.test-on-borrow=false
spring.datasource.druid.test-on-return=false
spring.datasource.druid.pool-prepared-statements=true
spring.datasource.druid.max-pool-prepared-statement-per-connection-size=20
spring.datasource.druid.filters=stat,wall,log4j2
spring.datasource.druid.connection-properties=druid.stat.mergeSql=true;
spring.datasource.druid.filter.stat.slow-sql-millis=5000
# 合并多个DruidDataSource的监控数据
spring.datasource.type=com.alibaba.druid.pool.xa.DruidXADataSource
#jta相关参数配置
#spring.jta.log-dir=classpath:tx-logs
#spring.jta.transaction-manager-id=xatx
spring.datasource.druid.use-global-data-source-stat=true
#配置日志输出
spring.datasource.druid.filter.slf4j.enabled=true
spring.datasource.druid.filter.slf4j.statement-close-after-log-enabled=false
spring.datasource.druid.filter.slf4j.statement-create-after-log-enabled=false
spring.datasource.druid.filter.slf4j.result-set-close-after-log-enabled=false
spring.datasource.druid.filter.slf4j.result-set-open-after-log-enabled=false
创建DS注解类
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface DS {
String value() default "scada";
}
创建Confi用来配置多源数据库
@Configuration
public class DataSourceConfig {
@Value("${spring.datasource.type:com.alibaba.druid.pool.xa.DruidXADataSource}")
String xaDataSourceClassName;
@Value("${mybatis-plus.mapper-locations}")
private String mapperLocations;
@Primary
@Bean(name = "bigdataDataSource")
@ConfigurationProperties(prefix = "spring.datasource.druid.drive")
public DataSource bigdataDataSource() {
String sourceName = "drive";
AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean();
xaDataSource.setXaDataSource(((XADataSource) DataSourceBuilder.create().build()));
xaDataSource.setXaDataSourceClassName(xaDataSourceClassName);
xaDataSource.setUniqueResourceName(sourceName);
xaDataSource.setPoolSize(5);
return xaDataSource;
}
@Bean(name = "platDataSource")
@ConfigurationProperties(prefix = "spring.datasource.druid.scada")
public DataSource platDataSource() {
String sourceName = "scada";
AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean();
xaDataSource.setXaDataSourceClassName(xaDataSourceClassName);
xaDataSource.setUniqueResourceName(sourceName);
xaDataSource.setPoolSize(5);
return xaDataSource;
}
// 配置数据源
@Bean(name = "dynamicDataSource")
public DynamicDataSource dataSource(@Qualifier("bigdataDataSource") DataSource bigdataDataSource,
@Qualifier("platDataSource") DataSource platDataSource) {
Map
创建自定义的数据库类
public interface DataSourceNames {
String DRIVE = "drive";
String SCADA = "scada";
String LOCATION = "location";
}
创建本地线程以及set,get来动态切换数据库
public class DynamicDataSource extends AbstractRoutingDataSource {
private static final ThreadLocal contextHolder = new ThreadLocal<>();
public static final String DEFAULT_SQL = "drive";
public DynamicDataSource(DataSource defaultTargetDataSource, Map
利用AOP来完成动态数据库的切换
@Aspect
@Component
@Order(-100)
public class DynamicDataSourceAspect {
private static final Logger loger = LoggerFactory.getLogger(DynamicDataSourceAspect.class);
/**
* 前置增强,方法执行前,通过JoinPoint访问连接点上下文的信息
*
* @param joinPoint
*/
@Before("@annotation(com.dfdk.datamanage.config.DS)")
public void beforeSwitchDataSource(JoinPoint joinPoint) {
// 获取连接点的方法签名对象
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
// 获取方法
Method method = methodSignature.getMethod();
// 设置默认的数据源为Master,防止切库出现异常执行失败的情况
String dataSource = DynamicDataSource.DEFAULT_SQL;
// 判断方法上是否标注了@RouteDataSource
if (method.isAnnotationPresent(DS.class)) {
DS routeDataSource = method.getDeclaredAnnotation(DS.class);
// 获取@RouteDataSource上的value的值
dataSource = routeDataSource.value();
}
// 设置数据源
loger.info("当前切换到"+dataSource);
DynamicDataSource.setDataSource(dataSource);
}
/**
* 后置增强,清空DatasourceContextHolder,防止threadLocal误用带来的内存泄露
*/
@After("@annotation(com.dfdk.datamanage.config.DS)")
public void afterSwitchDataSource() {
// 方法执行完成后,清除threadlocal中持有的database
DynamicDataSource.clearDataSource();
}
}
只需在service层加方法上加入注解就可以了,@DS注解默认是注解中定义的值
最后启动类加一个注解以及开启包扫描
@SpringBootApplication(exclude = {
DataSourceAutoConfiguration.class
})
@MapperScan("com.dfdk.datamanage.mapper")
这样就能通过注解实现数据库动态SQL的切换了,不过要注意分包哈
通过jta管理实现分布式事务可以查看我下一篇文章
https://blog.csdn.net/qq_38727189/article/details/99712740