• 周六. 10 月 12th, 2024

5G编程聚合网

5G时代下一个聚合的编程学习网

热门标签

Spring boot 2. X basic tutorial: multi data source configuration of mybatis

King Wang

1 月 3, 2022

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

  1. 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 .
  2. 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 .
  3. 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 :

  1. 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 .

  1. 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

  1. 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 .
  2. In the constructor of the configuration class , adopt @Qualifier Annotation to specify which data source to use , Its name corresponds to DataSourceConfiguration The name of the function defined by the data source in the configuration class .
  3. 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 :

  1. Go to Primary Data source inserts a piece of data
  2. from Primary The data source queries the data just inserted , If the configuration is correct, you can query it
  3. from Secondary The data source queries the data just inserted , If the configuration is correct, it should not be found
  4. Go to Secondary Data source inserts a piece of data
  5. from Primary The data source queries the data just inserted , If the configuration is correct, it should not be found
  6. 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.

发表回复