前言
Java项目中多个数据源,相应配置拿些方法哪些类访问
类似JDBC每个类都要写一遍会比较冗余,有没有集中式管理呢??
看这篇文章之前推荐阅读:
1. 基本知识
本身该注解通过Java的切面,源于Spring,推荐阅读补充知识:Spring框架从入门到学精(全)
自定义 @DS
注解通常是为了在方法级别上指定数据源,实现动态数据源切换的功能
通过在不同的方法上标注不同的数据源,可以使得这些方法在执行时使用不同的数据库连接
作用:
- 实现动态数据源切换:允许在不同的方法中使用不同的数据库连接
- 简化配置:通过注解方式,避免了在每个方法中手动切换数据源的麻烦
使用方式
定义注解:首先需要定义 @DS 注解,指定它的元注解为 @Target 和 @Retention,以及定义它的属性
查看其源码:
package com.baomidou.dynamic.datasource.annotation;
import java.lang.annotation.*;
/**
* The core Annotation to switch datasource. It can be annotate at class or method.
*
* @author TaoYu Kanyuxia
* @since 1.0.0
*/
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DS {
/**
* groupName or specific database name or spring SPEL name.
*
* @return the database you want to switch
*/
String value();
}
-
@Target({ElementType.TYPE, ElementType.METHOD})
:指定了注解@DS
可以应用在哪些地方,指定了@DS
注解可以应用在类和方法上 -
@Retention(RetentionPolicy.RUNTIME)
:指定了注解@DS
在程序运行时保留,可以通过反射来访问并解析@DS
注解的信息 -
@Documented
:标记这个注解是应该被 javadoc 工具记录的,当生成 API 文档时,如果一个类用@Documented
注解修饰,那么它的注解将出现在生成的文档中 -
String value()
;:属性,返回一个字符串,用于指定要切换到的数据库的名称
2. Demo
使用之前先引入依赖包:
<dependency>
<groupId>com.github.vlvolad</groupId>
<artifactId>spring-dynamic-datasource</artifactId>
<version>${spring-dynamic-datasource.version}</version>
</dependency>
配置数据源:
spring:
datasource: # 配置数据源
dynamic: # 数据源配置的一个自定义前缀,这个前缀是用于配置动态数据源,即可以在运行时动态切换数据源
primary: master # 指定了默认数据源的名称为 master
strict: true # 指定了严格模式,意味着如果在代码中请求了一个不存在的数据源,将抛出异常
datasource:
master:
url: jdbc:mysql://localhost:3306/db_master
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
slave:
url: jdbc:mysql://localhost:3307/db_slave
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
并在方法上动态切换数据源:
@Service
public class MyService {
@DS("master")
public void method1() {
// 方法1的实现
}
@DS("slave")
public void method2() {
// 方法2的实现
}
}
除了上面用在方法上,也可直接用在类上,对于这个类的波动方法都用于某个数据库
3. 实战
以下实战与上述Demo类似,只不过用在了方法上 (与正常开发一样,只不过在此处添加了该注解)
@Service
@DS("slave")
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
public class TemperatureAlarmHistServiceImpl implements ITemperatureAlarmHistService {
@Resource
private TemperatureAlarmHistMapper temperatureAlarmHistMapper;
public boolean saveForList(List<TemperatureAlarmHist> temperatureAlarmHistList) {
return temperatureAlarmHistMapper.saveForList(temperatureAlarmHistList);
}
}
对应的数据源配置如下:
#数据源配置
spring:
# 排除DruidDataSourceAutoConfigure
autoconfigure:
exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure
datasource:
dynamic:
# 设置默认的数据源或者数据源组,默认值即为master
primary: master
datasource:
master:
url: jdbc:mysql://localhost:3306/db_master
username: root
password: root
slave:
url: jdbc:oracle:manong:@//localhost:1521/GIS
username: root
password: ROOTGPS1
ep:
url: jdbc:sqlserver://localhost:1433;databaseName=manong
username: root
password: root
提供的配置中,exclude 属性指定了要排除的自动配置类 com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure
这样做的目的是排除Druid连接池的自动配置,避免它与手动配置的数据源发生冲突
另外一种排除的方式:
@SpringBootApplication(exclude = DruidDataSourceAutoConfigure.class)
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
前提是 上述这两种方式本身已经引入了该依赖包
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.1</version>
</dependency>