Two days before , We have already introduced the JdbcTemplate Multi data source configuration for as well as Spring Data JPA Multi data source configuration for , Let’s talk about the use of MyBatis How to configure multiple data source scenarios .
Add configuration for multiple data sources
First in Spring Boot Configuration file for application.properties Set up two database configurations that you want to link , Such as this :
spring.datasource.primary.jdbc-url=jdbc:mysql://localhost:3306/test1
spring.datasource.primary.username=root
spring.datasource.primary.password=123456
spring.datasource.primary.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.secondary.jdbc-url=jdbc:mysql://localhost:3306/test2
spring.datasource.secondary.username=root
spring.datasource.secondary.password=123456
spring.datasource.secondary.driver-class-name=com.mysql.cj.jdbc.Driver
Explanation and attention :
- Multi source data configuration , The difference with a single data source is that spring.datasource After that, set a data source name primary and secondary To distinguish between different data source configurations , This prefix will be used in subsequent initialization of the data source .
- Data source connection configuration 2.x and 1.x There is a difference between the configuration items of :2.x Use spring.datasource.secondary.jdbc-url, and 1.x Version USES spring.datasource.secondary.url. If this error occurs during configuration java.lang.IllegalArgumentException: jdbcUrl is required with driverClassName., So it’s the configuration item .
- You can see , No matter which data access framework you use , The configuration of the data source is the same .
Initialize the data source with MyBatis To configure
After completing the configuration information of multiple data sources , Let’s create a configuration class to load the configuration information , Initialize the data source , And initialize each data source with MyBatis To configure .
Here we continue to split the data source and framework configuration :
- Create a configuration class for multiple data sources separately , Like the following :
@Configuration
public class DataSourceConfiguration {
@Primary
@Bean
@ConfigurationProperties(prefix = "spring.datasource.primary")
public DataSource primaryDataSource() {
return DataSourceBuilder.create().build();
}
@Bean
@ConfigurationProperties(prefix = "spring.datasource.secondary")
public DataSource secondaryDataSource() {
return DataSourceBuilder.create().build();
}
}
You can see the following JdbcTemplate、Spring Data JPA It’s as like as two peas. . adopt @ConfigurationProperties
You can know that the two data sources have loaded spring.datasource.primary.*
and spring.datasource.secondary.*
Configuration of .@Primary
The annotation specifies the master data source , When we don’t specifically specify which data source , You’ll use this Bean The real difference is in the JPA Configuration .
- Create the MyBatis To configure .
Primary Data sources JPA To configure :
@Configuration
@MapperScan(
basePackages = "com.didispace.chapter39.p",
sqlSessionFactoryRef = "sqlSessionFactoryPrimary",
sqlSessionTemplateRef = "sqlSessionTemplatePrimary")
public class PrimaryConfig {
private DataSource primaryDataSource;
public PrimaryConfig(@Qualifier("primaryDataSource") DataSource primaryDataSource) {
this.primaryDataSource = primaryDataSource;
}
@Bean
public SqlSessionFactory sqlSessionFactoryPrimary() throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(primaryDataSource);
return bean.getObject();
}
@Bean
public SqlSessionTemplate sqlSessionTemplatePrimary() throws Exception {
return new SqlSessionTemplate(sqlSessionFactoryPrimary());
}
}
Secondary Data sources JPA To configure :
@Configuration
@MapperScan(
basePackages = "com.didispace.chapter39.s",
sqlSessionFactoryRef = "sqlSessionFactorySecondary",
sqlSessionTemplateRef = "sqlSessionTemplateSecondary")
public class SecondaryConfig {
private DataSource secondaryDataSource;
public SecondaryConfig(@Qualifier("secondaryDataSource") DataSource secondaryDataSource) {
this.secondaryDataSource = secondaryDataSource;
}
@Bean
public SqlSessionFactory sqlSessionFactorySecondary() throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(secondaryDataSource);
return bean.getObject();
}
@Bean
public SqlSessionTemplate sqlSessionTemplateSecondary() throws Exception {
return new SqlSessionTemplate(sqlSessionFactorySecondary());
}
}
Explanation and attention :
- Configuration class
@MapperScan
Annotation to specify the Entity and Mapper The package path of ; In addition, it needs to be specified sqlSessionFactory and sqlSessionTemplate, These two concrete implementations are initialized in the class in the configuration class . - In the constructor of the configuration class , adopt
@Qualifier
Annotation to specify which data source to use , Its name corresponds toDataSourceConfiguration
The name of the function defined by the data source in the configuration class . - Defined in the configuration class SqlSessionFactory and SqlSessionTemplate The implementation of the , Pay attention to the correct data source ( If you use the demo code here , As long as the second step is OK, there is no need to modify it ).
Last introduction JPA When , Because it was introduced before JPA When to use , Said entity and Repository Method of definition , So it omits User and Repository The definition code of , But some readers still ask why there is no such thing , In fact, there are instructions , It’s also in the warehouse code . It is not avoided to ask such questions again , So just post it here .
According to the above Primary Definition of data source , stay com.didispace.chapter39.p
It’s a bag , Definition Primary Entities and data access objects to be used by data sources , Like the following :
@Data
@NoArgsConstructor
public class UserPrimary {
private Long id;
private String name;
private Integer age;
public UserPrimary(String name, Integer age) {
this.name = name;
this.age = age;
}
}
public interface UserMapperPrimary {
@Select("SELECT * FROM USER WHERE NAME = #{name}")
UserPrimary findByName(@Param("name") String name);
@Insert("INSERT INTO USER(NAME, AGE) VALUES(#{name}, #{age})")
int insert(@Param("name") String name, @Param("age") Integer age);
@Delete("DELETE FROM USER")
int deleteAll();
}
According to the above Secondary Definition of data source , stay com.didispace.chapter39.s
It’s a bag , Definition Secondary Entities and data access objects to be used by data sources , Like the following :
@Data
@NoArgsConstructor
public class UserSecondary {
private Long id;
private String name;
private Integer age;
public UserSecondary(String name, Integer age) {
this.name = name;
this.age = age;
}
}
public interface UserMapperSecondary {
@Select("SELECT * FROM USER WHERE NAME = #{name}")
UserSecondary findByName(@Param("name") String name);
@Insert("INSERT INTO USER(NAME, AGE) VALUES(#{name}, #{age})")
int insert(@Param("name") String name, @Param("age") Integer age);
@Delete("DELETE FROM USER")
int deleteAll();
}
Test verification
After finishing the above , We can write a test class to test whether the above multi data source configuration is correct , Let’s design a verification idea first :
- Go to Primary Data source inserts a piece of data
- from Primary The data source queries the data just inserted , If the configuration is correct, you can query it
- from Secondary The data source queries the data just inserted , If the configuration is correct, it should not be found
- Go to Secondary Data source inserts a piece of data
- from Primary The data source queries the data just inserted , If the configuration is correct, it should not be found
- from Secondary The data source queries the data just inserted , If the configuration is correct, you can query it
The specific implementation is as follows :
@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest
@Transactional
public class Chapter39ApplicationTests {
@Autowired
private UserMapperPrimary userMapperPrimary;
@Autowired
private UserMapperSecondary userMapperSecondary;
@Before
public void setUp() {
// Clear test sheet , The result is the same every time
userMapperPrimary.deleteAll();
userMapperSecondary.deleteAll();
}
@Test
public void test() throws Exception {
// Go to Primary Data source inserts a piece of data
userMapperPrimary.insert("AAA", 20);
// from Primary The data source queries the data just inserted , If the configuration is correct, you can query it
UserPrimary userPrimary = userMapperPrimary.findByName("AAA");
Assert.assertEquals(20, userPrimary.getAge().intValue());
// from Secondary The data source queries the data just inserted , If the configuration is correct, it should not be found
UserSecondary userSecondary = userMapperSecondary.findByName("AAA");
Assert.assertNull(userSecondary);
// Go to Secondary Data source inserts a piece of data
userMapperSecondary.insert("BBB", 20);
// from Primary The data source queries the data just inserted , If the configuration is correct, it should not be found
userPrimary = userMapperPrimary.findByName("BBB");
Assert.assertNull(userPrimary);
// from Secondary The data source queries the data just inserted , If the configuration is correct, you can query it
userSecondary = userMapperSecondary.findByName("BBB");
Assert.assertEquals(20, userSecondary.getAge().intValue());
}
}
Code example
For an example of this article, see the following in the warehouse chapter3-9
Catalog :
- Github:https://github.com/dyc87112/SpringBoot-Learning/
- Gitee:https://gitee.com/didispace/SpringBoot-Learning/
If you think this article is good , welcome Star Support , Your concern is the driving force of my persistence !
First article :Spring Boot 2.x Basic course :MyBatis Multi data source configuration for
, Reprint please indicate the source .
Welcome to my official account. : Program the ape DD, Get exclusive learning resources and daily dry goods push .
If you are interested in my other topics , Direct to my personal blog :didispace.com.