一、SpringBoot的多数据源
在日常项目中,避免不了会用到多数据源或者读写分离的实现,下面来看一下如何实现
1-1、基础准备-创建一个springboot父级项目
首先创建一个springboot项目作为Parent项目,然后引入相关pom依赖,最终pom内容如下: 主要需要引入mysql驱动、drui数据源、mybatis-plus
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.jony</groupId>
<artifactId>readwrite</artifactId>
<version>1.0</version>
<name>readwrite</name>
<description>readwrite</description>
<packaging>pom</packaging>
<modules>
<module>DynamicDS</module>
</modules>
<properties>
<java.version>17</java.version>
<spring-boot.version>2.7.8</spring-boot.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--mysql 驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.22</version>
</dependency>
<!--drui连接池-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.11</version>
</dependency>
<!--mybatis-plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.1</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<!--spring boot 的版本管理-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
1-2、在Controller层指定数据源
1-2-1、创建一个module项目
给父项目创建一个module设置名称为:DynamicDS,其中pom的内容如下(pom中的parent引入父项目):
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.jony</groupId>
<artifactId>readwrite</artifactId>
<version>1.0</version>
</parent>
<groupId>com.jony</groupId>
<artifactId>DynamicDS</artifactId>
<version>1.0</version>
<name>DynamicDS</name>
<description>DynamicDS</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
1-2-2、配置数据源
暂时设置两个数据源(datasource1及datasource2),如下:
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
#自定义第一个数据源
datasource1:
url: jdbc:mysql://localhost:3306/coursedb?serverTimezone=UTC
username: root
password: root
initial-size: 1
min-idle: 1
max-active: 20
test-on-borrow: true
driver-class-name: com.mysql.cj.jdbc.Driver
#自定义第二个数据源
datasource2:
url: jdbc:mysql://localhost:3306/coursedb2?serverTimezone=UTC
username: root
password: root
initial-size: 1
min-idle: 1
max-active: 20
test-on-borrow: true
driver-class-name: com.mysql.cj.jdbc.Driver
1-2-3、加载数据源
创建一个加载数据源的类,并且添加@Configuration注解,最终代码如下:
@Configuration
public class DataSourceConfig {
@Bean(name = "dataSource1")
@ConfigurationProperties(prefix = "spring.datasource.datasource1")
public DataSource dataSource1() {
// 底层会自动拿到spring.datasource中的配置, 创建一个DruidDataSource
return DruidDataSourceBuilder.create().build();
}
@Bean(name = "dataSource2")
@ConfigurationProperties(prefix = "spring.datasource.datasource2")
public DataSource dataSource2() {
// 底层会自动拿到spring.datasource中的配置, 创建一个DruidDataSource
return DruidDataSourceBuilder.create().build();
}
}
以上代码主要读取配置文件,完成数据源的加载,并且通过@Bean指定Bean的名称
1-2-4、读取数据库,及设置默认数据源
使用AbstractRoutingDataSource创建两个库,R表示读库,W表示写库。同时设置dataSource1为默认数据源,防止未指定数据源报错。
@Component("dynamicDataSource")
@Primary
public class DynamicDataSource extends AbstractRoutingDataSource {
public static ThreadLocal<String> name = new ThreadLocal<String>();
@Override
protected Object determineCurrentLookupKey() {
return name.get();
}
@Resource(name = "dataSource1")
DataSource dataSource1;
@Resource(name = "dataSource2")
DataSource dataSource2;
@Override
public void afterPropertiesSet() {
// 为targetDataSources初始化所有数据源
Map<Object, Object> targetDataSources=new HashMap<Object,Object>();
targetDataSources.put("R",dataSource1);
targetDataSources.put("W",dataSource2);
super.setTargetDataSources(targetDataSources);
// 为defaultTargetDataSource 设置默认的数据源
super.setDefaultTargetDataSource(dataSource1);
super.afterPropertiesSet();
}
}
1-2-5、Controller中设置使用的数据源
@Controller
@RequestMapping("/RDS")
public class CourseControllerRDS {
@Resource
CourseMapper courseMapper;
@ResponseBody
@RequestMapping("/queryCourse")
public Object queryOrder(@RequestParam(value = "dsKey",defaultValue = "R") String dsKey){
DynamicDataSource.name.set(dsKey);
return courseMapper.selectList(null);
}
@ResponseBody
@RequestMapping("/createCourse")
public String createCourse(@RequestParam(value = "dsKey",defaultValue = "W") String dsKey, Course course){
DynamicDataSource.name.set(dsKey);
courseMapper.insert(course);
return "SUCCESS BY RDS";
}
}
1-3、使用dynamic-datasource在Service中指定数据源
1-3-1、创建module项目
同样创建一个module,其pom和上面创建的类似,以父项目作为parent,同时添加baomidou的dynamic-datasource-spring-boot-starter
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.jony</groupId>
<artifactId>readwrite</artifactId>
<version>1.0</version>
</parent>
<groupId>com.jony</groupId>
<artifactId>DSFrameWork</artifactId>
<version>1.0</version>
<name>DSFrameWork</name>
<description>DSFrameWork</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-core -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-core</artifactId>
<version>3.0.5</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>3.5.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.6.3</version>
</plugin>
</plugins>
</build>
</project>
1-3-2、配置数据源
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
#使用dynamicDatasource框架
dynamic:
#设置默认的数据源或者数据源组,read
primary: read
#严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源
strict: false
datasource:
read:
url: jdbc:mysql://localhost:3306/coursedb?serverTimezone=UTC
username: root
password: root
initial-size: 1
min-idle: 1
max-active: 20
test-on-borrow: true
driver-class-name: com.mysql.cj.jdbc.Driver
write:
url: jdbc:mysql://localhost:3306/coursedb2?serverTimezone=UTC
username: root
password: root
initial-size: 1
min-idle: 1
max-active: 20
test-on-borrow: true
driver-class-name: com.mysql.cj.jdbc.Driver
1-3-3、数据源设置
在service中通过设置@DS注解,就可以设置当前文件的数据源,在方法中也可以通过@DS来设置数据源,方法的设置优先级高于类上的设置
@Service
@DS("write")
public class CourseService {
@Resource
private JdbcTemplate jdbcTemplate;
// @DS("read")
public List selectCourse(){
return jdbcTemplate.queryForList("select * from course");
}
@DS("read")
public int createCourse(Course course){
return jdbcTemplate.update("insert into course values(?,?,?,?)",course.getCid(),course.getCname(),course.getUserId(),course.getCstatus());
}
}
到此两种数据源配置的方法就介绍完毕了