In development, you may encounter the situation of using multiple data sources in one project. We can use springboot to quickly implement the configuration of multiple data sources. The mybatis-plus team baomidou has provided an open source project dynamicDataSource to facilitate the configuration of multiple data sources. Here, springboot + mybatis-plus + dynamicDataSource is used to realize the rapid configuration of multiple data sources.
data preparation
Create databases, tables and add data. The demo database and test database each have a student table, each of which has only one piece of data. The names of the students are their database names for easy distinction.
1.1 Create a springboot project and import coordinates.
The pom file is as follows. If the SQL file is written in the resources directory, you don’t need to configure the resource in the build tag. Otherwise, you need to configure it. Otherwise, the SQL file will be ignored during compilation and an error will be reported.
<?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>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.10</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.demo</groupId>
<artifactId>dynamic-datasource-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.32</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>3.6.1</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.16</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.3.1</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/mapper/**/*.xml</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
</build>
</project>
1.2 Modify the configuration file
The mapper-locations configuration is the location of the SQL file. Mybatis-plus does not need to write SQL without configuration, but it still needs to write SQL when encountering complex logic, so it is recommended to match it.
type is used to configure the data connection pool. Here, the druid connection pool of alibaba is used. If it is not configured, the default connection pool is used. Primary is the default data source and must be configured.
Here, for convenience, different databases of the local mysql are used to implement, and they can be changed according to the actual situation when using.
spring:
datasource:
#使用druid连接池
type: com.alibaba.druid.pool.DruidDataSource
dynamic:
#设置默认的数据源或者数据源组,默认值即为master
primary: test
#严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源
strict: false
datasource:
test:
url: jdbc:mysql://localhost:3306/test?useSSL=false&useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true
username: root
password: 1234
driver-class-name: com.mysql.cj.jdbc.Driver
demo:
url: jdbc:mysql://localhost:3306/demo?useSSL=false&useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true
username: root
password: 1234
driver-class-name: com.mysql.cj.jdbc.Driver
mybatis-plus:
mapper-locations: classpath:/com.demo.dynamicdatasourcedemo/mapper/**/*.xml
1.3 Create entities and interfaces
Entity classes and mapper interfaces, such as a Student entity, a native Mapper interface, and two Mapper interfaces that add DS annotations to switch data sources. @DS is the annotation provided by dynamicDataSource. The value in the annotation is the name of the configured data source. Which data source is filled in will switch to which data source. This annotation can be used on classes and methods. The priority of methods under the same class is higher than that of classes.
1.4 create service
Create another StudentService to call different mapper interfaces to view the differences.
demo1 adds DS annotations to the method to switch the demo data source and calls the native interface;
test1 adds DS annotation to the method to switch the test data source and calls the native interface;
demo2 adds DS annotations to the method to switch the test data source and calls the demo data source interface;
test2 adds DS annotations to the method to switch the demo data source and calls the test data source interface;
package com.demo.dynamicdatasourcedemo.service;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.demo.dynamicdatasourcedemo.entity.Student;
import com.demo.dynamicdatasourcedemo.mapper.StudentMapper;
import com.demo.dynamicdatasourcedemo.mapper.demo.DemoStudentMapper;
import com.demo.dynamicdatasourcedemo.mapper.test.TestStudentMapper;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
@Service
public class StudentService {
@Resource
private StudentMapper studentMapper;
@Resource
private TestStudentMapper testStudentMapper;
@Resource
private DemoStudentMapper demoStudentMapper;
@DS("demo")
public List<Student> getAllDemoStudent1() {
System.out.println("demo student 1 ...");
return studentMapper.selectList(null);
}
@DS("test")
public List<Student> getAllTestStudent1() {
System.out.println("test student 1 ...");
return studentMapper.selectList(null);
}
@DS("test")
public List<Student> getAllDemoStudent2() {
System.out.println("demo student 2 ...");
return demoStudentMapper.selectList(null);
}
@DS("demo")
public List<Student> getAllTestStudent2() {
System.out.println("test student 2 ...");
return testStudentMapper.selectList(null);
}
}
1.5 Test
Do a simple test in the startup class, and from the output, it is obvious that it is as expected. Both the DS annotation in the service and the DS annotation in the mapper can take effect, and the priority in the mapper is higher, and the order of priority is: mapper method>mapper class>service method>service class. Since then, springboot has been used to quickly switch data sources.
1.6 Custom annotations
dynamicDataSource supports custom annotations after version 3.2.0, and you need to inherit DS to use custom annotations. TestMapper is used to switch the test data source, and DemoMapper is used to switch the demo data source. Use custom annotations on the mapper class, and inherit DS later.
1.7 Test custom annotations
From the test results, the effect of custom annotations is as expected.
The Gitee address of the dynamicDataSource project: dynamic-datasource-spring-boot-starter: Based on SpringBoot multi-data source dynamic data source master-slave separation quick starter supports distributed transactions (gitee.com)
If you are interested in dynamicDataSource, you can go to the official address of the above project to view, and there are detailed documents in it.