SoFunction
Updated on 2025-03-03

Mybatis-plus dynamic data source read and write separation method

1. Background

During the actual project development process, there will definitely be a distributed model of the master library and the slave library. The master library will be added, deleted and modified, and the slave library will be queried.

This ensures that different databases are operated and reduces the pressure on the database.

2. Dynamic data source

Create DynamicDatasourceService

import ;
import ;
public interface DynamicDatasourceService {


    /**
      * Get all data sources
      *
      * @return
      */
    Set<String> datasources();


    /**
      * Add data source
      *
      * @param dto Data source information
      * @return
      */
    Set<String> add(DataSourceDTO dto);


    /**
      * Remove data source
      *
      * @param name Connection pool name
      */
    void remove(String name);
}

Implement DynamicDatasourceService

package ;

import ;
import ;
import ;
import ;
import ;
import ;
import ;

import ;
import ;

@Service
public class DynamicDatasourceServiceImpl implements DynamicDatasourceService {


    private final DataSource dataSource;

    private final DefaultDataSourceCreator dataSourceCreator;

    public DynamicDatasourceServiceImpl(
            DataSource dataSource, DefaultDataSourceCreator dataSourceCreator) {
         = dataSource;
         = dataSourceCreator;
    }


    /**
      * Get all data sources
      *
      * @return
      */
    @Override
    public Set<String> datasources() {
        DynamicRoutingDataSource ds = (DynamicRoutingDataSource) dataSource;
        return ().keySet();
    }


    /**
      * Add data source
      *
      * @param dto
      * @return
      */
    @Override
    public Set<String> add(DataSourceDTO dto) {
        DataSourceProperty dataSourceProperty = new DataSourceProperty();
        (dto, dataSourceProperty);
        DynamicRoutingDataSource ds = (DynamicRoutingDataSource) dataSource;
        DataSource dataSource = (dataSourceProperty);
        ((), dataSource);
        return ().keySet();
    }


    /**
      * Delete the data source
      *
      * @param name
      */
    @Override
    public void remove(String name) {
        DynamicRoutingDataSource ds = (DynamicRoutingDataSource) dataSource;
        (name);
    }

}

2.1 Adding a data source

Here is the link to the username, password and other data sources in the configuration file I read

 public void addDatasource(String tenant) {
        if (().contains(tenant)) {
            return;
        }
        DataSourceDTO datasourceDTO = new DataSourceDTO();
        // Library name        (tenant);
        //Link information Read the main library information of the configuration file        (());
        //Replace the database        if ((())) {
            throw new RuntimeException("Profile reading failed");
        }
        String url = ();
        url = ("grid_test", tenant);
        (url);
        (());
        (());
        (datasourceDTO);
    }

2.2 Data source

Call the addDatasource() method above and the data source will be created successfully. It should be noted here that this method needs to be called every time you add, delete, modify and check to prevent the data source from existing.

3. Database query

The purpose of creating a new data source is to enable library partition operations.

The steps for the partitioning of the library are as follows:

3.1 Add configuration class

package ;

import ;
import ;
import ;
import ;
import ;
import ;

/**
  * Register a dynamic data source parser
  */
@Configuration
public class MyDynamicDataSourceConfig {

  @Bean
  public DsProcessor dsProcessor() {
    DsMapProcessor mapProcessor = new DsMapProcessor();
    DsHeaderProcessor headerProcessor = new DsHeaderProcessor();
    DsSessionProcessor sessionProcessor = new DsSessionProcessor();
    DsSpelExpressionProcessor spelExpressionProcessor = new DsSpelExpressionProcessor();
    (headerProcessor);
    (sessionProcessor);
    (spelExpressionProcessor);
    return mapProcessor;
  }
}
package ;

import ;
import ;
import ;
import .Address3DTO;
import ;
import ;
import ;

/**
  * Get the data source identifier through params map
  *
  * @author songlude
  */
public class DsMapProcessor extends DsProcessor {

    /**
      * Abstract matching conditions Only when matching will the current executor go, otherwise the next level of executor goes
      *
      * @param key DS annotation
      * @return Does it match
      */
    @Override
    public boolean matches(String key) {
        return ("#" + SQLConstants.EXEC_DATASOURCE);
    }

    /**
      * Abstraction ultimately determines the data source
      *
      * @param invocation method execution information
      * @param key DS annotation
      * @return Data source name
      */
    @Override
    public String doDetermineDatasource(MethodInvocation invocation, String key) {
        Object[] arguments = ();
        Object argument = arguments[0];

        if (argument instanceof Map) {
            Map<String, Object> params = (Map<String, Object>) argument;
            Object value = (SQLConstants.EXEC_DATASOURCE);
            return value == null ? null : ();
        } else if (argument instanceof CollectionDataPageParam) {
            CollectionDataPageParam collectionDataPageParam = (CollectionDataPageParam) argument;
            return collectionDataPageParam.getGRID_DATASOURCE();
        } else if (argument instanceof CollectionDataDO) {
            CollectionDataDO collectionDataDO = (CollectionDataDO) argument;
            return collectionDataDO.getGRID_DATASOURCE();
        } else if (argument instanceof Address3DTO) {
            Address3DTO address3DTO = (Address3DTO) argument;
            return address3DTO.getGRID_DATASOURCE();
        }
        return null;
    }
}

Here we need to judge the type of "argument". argument is the parameter you query the mapper parameters. Here I get argument[0], and the position of the mapper parameter is the first one.

3.2 Add data source query

The data source is specified through the @DS annotation, and the configuration class starts with # is specified.

 @DS("#GRID_DATASOURCE")
    @UpdateProvider(type = , method = "createDatabase")
    void createDatabase(Map<String, Object> params);

This will enable your dynamic data source and query the database.

Summarize

The above is personal experience. I hope you can give you a reference and I hope you can support me more.