“This is the 13th day of my participation in the First Challenge 2022. For details: First Challenge 2022”

preface

In our development project, a large project may have multiple data sources, may be multi-master multi-slave, multi-database, mixed configuration, etc., so this time based on the dynamic-datasource-spring-boot-starter multi-data source configuration.

The development environment

Development tool IDEA JDK1.8 Spring Boot 2.3.0 Mybatis -plus 3.3.0

introduce

Dynamic-datasource – Spring-boot-starter is a project initiated by mybatis- Plus members of small pot lid individuals. It is a fast integrated multi-data source starter based on Springboot.

The characteristics of

  • Support data source grouping, suitable for a variety of scenarios pure multi-library read and write separation of a master multi-slave mixed mode.
  • Support database sensitive configuration information encryption ENC().
  • Support each database to independently initialize the table structure schema and database.
  • Supports no data source startup and lazy loading of data sources (creating connections when needed).
  • Support custom annotations, inherit DS(3.2.0+).
  • Provides and simplifies fast integration with Druid, HikariCp, BeeCp, and Dbcp2.
  • Provide integration solutions for Mybatis-Plus, Quartz, ShardingJdbc, P6sy, Jndi and other components.
  • Provide a custom data source source solution (such as full load from the database).
  • Provides a dynamic solution to add and remove data sources after the project starts.
  • Provide pure read and write separation scheme in Mybatis environment.
  • Provides a solution for parsing data sources using SPEL dynamic parameters. Built-in SPEL, session, header, support customization.
  • Supports nested switching of multiple data sources. (ServiceA >>> ServiceB >>> ServiceC).
  • Provides the ** distributed transaction scheme based on SEATA.
  • Provides a local multi-data source transaction scheme.

convention

  • This framework only does the core thing of switching data sources, and does not limit your specific operations. Switching data sources can do any CRUD.
  • All data source headers separated by underscores (_) are group names. Data sources with the same group name are grouped under the same group.
  • The switch data source can be a group name or a concrete data source name. The group name is switched using the load balancing algorithm.
  • The default data source name for the master, you can use the spring. The datasource. Dynamic. The primary modification.
  • Annotations on methods take precedence over class annotations.
  • DS supports inheriting DS from abstract classes, but does not support inheriting DS from interfaces.

Quick start

Introduction of depend on

The Spring Boot multi-source configuration example is based on mybatis-plus and dynamic-datasource-spring-boot-starter. The main one is dynamic-datasource-spring-boot-starter. Provides multiple data source configuration initiators

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.3.0</version>
</dependency>

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-generator</artifactId>
    <version>3.3.0</version>
</dependency>

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
    <version>3.3.0</version>
</dependency>
Copy the code

The sample is introduced

This configuration will be based on the primary and secondary data sources as a simple example. Query information about the same table in two databases through different interfaces. Create demo table SQL as follows:


CREATE TABLE `s_user` (
  `userid` int(11) NOT NULL AUTO_INCREMENT,
  `user_name` varchar(255) DEFAULT NULL,
  `name` varchar(255) DEFAULT NULL,
  `pass_word` varchar(255) DEFAULT NULL,
  `salt` varchar(255) DEFAULT NULL,
  `state` varchar(255) DEFAULT NULL,
  `create_time` datetime DEFAULT NULL,
  PRIMARY KEY (`userid`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

Copy the code

Data Source Configuration

Introduce two data sources master and Slave_1. Query different data sources in the project, and the information in the database is different.

server.port=8888 swagger.enable=true spring.datasource.dynamic.primary=master spring.datasource.dynamic.strict=false Spring. The datasource. Dynamic. The datasource. Master. Url = JDBC: mysql: / / 127.0.0.1:3306 / test? useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull spring.datasource.dynamic.datasource.master.username=test spring.datasource.dynamic.datasource.master.password=123456789  spring.datasource.dynamic.datasource.master.driver-class-name=com.mysql.cj.jdbc.Driver Spring. The datasource. Dynamic. The datasource. Slave_1. Url = JDBC: mysql: / / 127.0.0.1:3306 / test_save? useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull spring.datasource.dynamic.datasource.slave_1.username=test_save spring.datasource.dynamic.datasource.slave_1.password=123456789 spring.datasource.dynamic.datasource.slave_1.driver-class-name=com.mysql.cj.jdbc.DriverCopy the code

The test data

The user information in the master database is as follows:

User information for the slave_1 database is as follows:

Start the class

/** * public id: Java full stack architect **
@SpringBootApplication
@MapperScan(value = "com.example.demo.mapper")
public class DemoBootMybatisPlusDataSourceApplication {

    public static void main(String[] args){ SpringApplication.run(DemoBootMybatisPlusDataSourceApplication.class, args); }}Copy the code

The test interface

Write two test interfaces for two data sources, and then call different methods through the interfaces to see if queries return information from different databases.


@Api(description = "User Management")
@RequestMapping("user")
@RestController
public class UserController {

    @Resource
    private UserService userService;

    // Public id: Java full stack architect
    @ApiOperation(value = "Master gets users by username")
    @RequestMapping(value = "getMasterUserList",method = RequestMethod.GET)
    public List<User> getMasterUserList(){
        return userService.list();
    }

    // Author: Nuggets Jr
    @ApiOperation(value = "Slave_1 Obtains users by username")
    @RequestMapping(value = "getUserList",method = RequestMethod.GET)
    public List<User> getUserList(){
        returnuserService.getUserList(); }}Copy the code

implementation

Dynamic-datasource -spring-boot-starter provides multiple data sources for configuring initiators. By default, the master datasource is used. We can use @ds to switch data sources when we need to. @ds can be annotated on methods or classes, and the proximity principle exists.

Method annotations take precedence over class annotations. In the following code example, the getUserList() method is annotated with @ds (“slave_1”), so the slave_1 library is queried first


@Service
@DS("master")
public class UserServiceImpl extends ServiceImpl< UserMapper.User> implements UserService  {

    @Resource
    private  UserMapper userMapper;

    @Override
    @DS("slave_1")
    public List<User> getUserList() {
        System.out.println("slave_1");
        List<User> list = userMapper.selectList(new QueryWrapper<User>());
        System.out.println(list);
        returnlist; }}Copy the code

Run the demo

After starting the project, enter the address information in the browser and invoke the interface in Swagger.Query information about all users in the master user table as follows:

Query all user information in the slave_1 database. The query result is as follows:

conclusion

Well, the above is the introduction of Spring Boot multi-data source configuration example, thank you for reading, I hope you like, if it is helpful to you, welcome to like favorites. If there are shortcomings, welcome comments and corrections. See you next time.

About the author: [Little Ajie] a love tinkering with the program ape, JAVA developers and enthusiasts. Public number [Java full stack architect] maintainer, welcome to pay attention to reading communication.