SpringBoot多数据源
3 分钟 11279 字 |
SpringBoot多数据源
1 手动切换数据源
- application.properties
# 主数据库:TDengine
# 数据源驱动
spring.datasource.primary.driver-class-name=com.taosdata.jdbc.rs.RestfulDriver
# 数据库连接地址
# 多数据源写jdbc-url
spring.datasource.primary.jdbc-url=jdbc:TAOS-RS://localhost:6041/workshop?timezone=UTC+8&charset=UTF-8&locale=en_US.UTF-8
# 数据库用户名&密码
spring.datasource.primary.username=root
spring.datasource.primary.password=
# 副数据库:MySQL
spring.datasource.secondary.driver-class-name=com.mysql.cj.jdbc.Driver
# 数据库连接地址
spring.datasource.secondary.jdbc-url=jdbc:mysql://localhost:3306/augment?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8&useSSL=false
# 数据库用户名&密码
spring.datasource.secondary.username=root
spring.datasource.secondary.password=
- 主数据源配置
PrimaryDataSourceConfig.java
@Configuration
// 指定主数据库扫描对应的Mapper文件夹,生成代理对象
@MapperScan(basePackages ="com.dec.workshop.iot.mapper" ,sqlSessionFactoryRef = "primarySqlSessionFactory")
public class PrimaryDataSourceConfig {
/**
* 主数据源,Primary注解必须增加,它表示该数据源为默认数据源
* 项目中还可能存在其他的数据源,如获取时不指定名称,则默认获取这个数据源,如果不添加,则启动时候回报错
*/
@Primary
@Bean(name = "primaryDataSource")
// 读取spring.datasource.primary前缀的配置文件映射成对应的配置对象
@ConfigurationProperties(prefix = "spring.datasource.primary")
public DataSource dataSource() {
DataSource build = DataSourceBuilder.create().build();
return build;
}
/**
* 事务管理器,Primary注解作用同上
*/
@Bean(name = "primaryTransactionManager")
@Primary
public PlatformTransactionManager dataSourceTransactionManager(@Qualifier("primaryDataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
/**
* session工厂,Primary注解作用同上
*/
@Bean(name = "primarySqlSessionFactory")
@Primary
public SqlSessionFactory sqlSessionFactory(@Qualifier("primaryDataSource") DataSource dataSource) throws Exception {
final SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();
sessionFactoryBean.setDataSource(dataSource);
//sessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(primaryDataSourceConfig.MAPPER_LOCATION));
return sessionFactoryBean.getObject();
}
}
- 次数据源配置
SecondaryDataSourceConfig.java
@Configuration
@MapperScan(basePackages ="com.dec.workshop.manager.mapper" ,sqlSessionFactoryRef = "secondarySqlSessionFactory")
public class SecondaryDataSourceConfig {
@Bean(name = "secondaryDataSource")
@ConfigurationProperties(prefix = "spring.datasource.secondary")
public DataSource dataSource() {
DataSource build = DataSourceBuilder.create().build();
return build;
}
@Bean(name = "secondaryTransactionManager")
public PlatformTransactionManager dataSourceTransactionManager(@Qualifier("secondaryDataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean(name = "secondarySqlSessionFactory")
public SqlSessionFactory sqlSessionFactory(@Qualifier("secondaryDataSource") DataSource dataSource) throws Exception {
final SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();
sessionFactoryBean.setDataSource(dataSource);
return sessionFactoryBean.getObject();
}
}
- 对某数据库进行操作时,调用对应的mapper即可
2 动态切换数据源
- 配置文件
application.properties
# 主数据库:TDengine
# 数据源驱动
spring.datasource.primary.driver-class-name=com.taosdata.jdbc.rs.RestfulDriver
# 数据库连接地址
spring.datasource.primary.jdbc-url=jdbc:TAOS-RS://localhost:6041/workshop?timezone=UTC+8&charset=UTF-8&locale=en_US.UTF-8
# 数据库用户名&密码
spring.datasource.primary.username=root
spring.datasource.primary.password=taosdata
# 副数据库:MySQL
spring.datasource.secondary.driver-class-name=com.mysql.cj.jdbc.Driver
# 数据库连接地址
spring.datasource.secondary.jdbc-url=jdbc:mysql://localhost:3306/augment?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8&useSSL=false
# 是否启用从数据库
spring.datasource.secondary.enabled=true
# 数据库用户名&密码
spring.datasource.secondary.username=root
spring.datasource.secondary.password=qwe123qwe
- 数据源配置
DataSourceConfig.java
@Configuration
public class DataSourceConfig {
/**
* db1数据库配置
*/
@Bean("primary")
@ConfigurationProperties(prefix = "spring.datasource.primary")
public DataSource primarySource() {
return DataSourceBuilder.create().build();
}
/**
* db2数据库配置
*/
@Bean("secondary")
@ConfigurationProperties(prefix = "spring.datasource.secondary")
@ConditionalOnProperty(prefix = "spring.datasource.secondary", name = "enabled", havingValue = "true")
public DataSource secondarySource() {
return DataSourceBuilder.create().build();
}
/**
* 动态数据库配置
*/
@Primary
@Bean(name = "dynamicDataSource")
public DataSource dynamicDataSource() {
DynamicDataSource dynamicDataSource = new DynamicDataSource();
// 默认数据源
dynamicDataSource.setDefaultTargetDataSource(primarySource());
// 配置多数据源
Map<Object, Object> dsMap = new HashMap(5);
dsMap.put("primary", primarySource());
dsMap.put("secondary", secondarySource());
dynamicDataSource.setTargetDataSources(dsMap);
return dynamicDataSource;
}
/**
* 配置@Transactional注解事物
* @return
*/
@Bean
public PlatformTransactionManager transactionManager() {
return new DataSourceTransactionManager(dynamicDataSource());
}
}
DataSourceContextHolder.java
public class DataSourceContextHolder {
// 默认数据源
public static final String DEFAULT_DS = "primary";
private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();
public static void setDB(String dbType) {
contextHolder.set(dbType);
}
public static String getDB() {
return (contextHolder.get());
}
public static void clearDB() {
contextHolder.remove();
}
}
DynamicDataSource.java
public class DynamicDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return DataSourceContextHolder.getDB();
}
}
- 注解
DataBase.java
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface DataBase {
String value() default "primary";
}
- 切面
DataBaseAspect.java
@Aspect
@Component
public class DataBaseAspect {
@Pointcut("@annotation(com.dec.core.annotation.DataBase)")
public void dbPointCut() {
}
@Before("dbPointCut()")
public void beforeSwitchDS(JoinPoint point){
//获得当前访问的class
Class<?> className = point.getTarget().getClass();
//获得访问的方法名
String methodName = point.getSignature().getName();
//得到方法的参数的类型
Class[] argClass = ((MethodSignature)point.getSignature()).getParameterTypes();
String dataSource = DataSourceContextHolder.DEFAULT_DS;
try {
// 得到访问的方法对象
Method method = className.getMethod(methodName, argClass);
// 判断是否存在@DateBase注解
if (method.isAnnotationPresent(DataBase.class)) {
DataBase annotation = method.getAnnotation(DataBase.class);
// 取出注解中的数据源名
dataSource = annotation.value();
}
} catch (Exception e) {
e.printStackTrace();
}
// 切换数据源
DataSourceContextHolder.setDB(dataSource);
}
@After("dbPointCut()")
public void afterSwitchDS(JoinPoint point){
DataSourceContextHolder.clearDB();
}
}
- 使用
@DataBase("primary")
public void test(){
return;
}
Service方法中直接调用注解
3 调用已有轮子
- pom.xml
<!--导入MyBatis-Plus作为持久层框架-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.2</version>
</dependency>
<!--动态数据源-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>3.4.0</version>
</dependency>
- application.yaml
spring:
datasource:
dynamic:
primary: primary #设置默认的数据源或者数据源组,默认值即为master
strict: false #严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源
datasource:
primary:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/workshop?serverTimezone
username: root
password: qwe123qwe
secondary:
driver-class-name: com.taosdata.jdbc.rs.RestfulDriver
url: jdbc:TAOS-RS://localhost:6041/workshop?timezone
username: root
password: taosdata
- 使用
在方法或类上:@DS("secondary")
参考
- https://juejin.cn/post/7025511138364227621
- https://www.jianshu.com/p/1912d2599473
- https://www.baomidou.com/pages/a61e1b/#dynamic-datasource
~ ~ The End ~ ~
分类标签:,none
文章标题:SpringBoot多数据源
文章链接:http://120.46.217.131:82/archives/63/
最后编辑:2023 年 5 月 29 日 22:00 By Yang
许可协议: 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)
文章标题:SpringBoot多数据源
文章链接:http://120.46.217.131:82/archives/63/
最后编辑:2023 年 5 月 29 日 22:00 By Yang
许可协议: 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)