SoFunction
Updated on 2025-03-08

Spring boot configuration method using sharding jdbc

This article introduces the configuration method of using sharding jdbc for spring boot. I will share it with you. The details are as follows:

illustrate

To exclude DataSourceAutoConfiguration, otherwise multiple data sources cannot be configured

@SpringBootApplication
@EnableAutoConfiguration(exclude={})
public class Application {

  public static void main(String[] args) {
   (, args);
  }
 
}

The configured multiple data sources are handed over to sharding-jdbc for management, sharding-jdbc creates a DataSource data source for mybatis use.

Official Documentation:/index_zh.html

step

Configure multiple data sources, it is best to have certain rules for the name of the data source to facilitate the configuration of the calculation rules for the database.

@Bean(initMethod="init", destroyMethod="close", name="dataSource0")
@ConfigurationProperties(prefix = "")
public DataSource dataSource0(){
  return new DruidDataSource();
}

@Bean(initMethod="init", destroyMethod="close", name="dataSource1")
@ConfigurationProperties(prefix = "spring.datasource2")
public DataSource dataSource1(){
  return new DruidDataSource();
}

Configure data source rules, that is, hand over multiple data sources to sharding-jdbc for management, and can set default data sources. When the table does not have database rules configured, the default data sources will be used.

@Bean
public DataSourceRule dataSourceRule(@Qualifier("dataSource0") DataSource dataSource0, 
    @Qualifier("dataSource1") DataSource dataSource1){
  Map<String, DataSource> dataSourceMap = new HashMap<>();
  ("dataSource0", dataSource0);
  ("dataSource1", dataSource1);
  return new DataSourceRule(dataSourceMap, "dataSource0");
}

Configure data source policies and table policies, and implement specific policies yourself.

@Bean
public ShardingRule shardingRule(DataSourceRule dataSourceRule){
  //Table Strategy  TableRule orderTableRule = ("t_order")
      .actualTables(("t_order_0", "t_order_1"))
      .tableShardingStrategy(new TableShardingStrategy("order_id", new ModuloTableShardingAlgorithm()))
      .dataSourceRule(dataSourceRule)
      .build();
  TableRule orderItemTableRule = ("t_order_item")
      .actualTables(("t_order_item_0", "t_order_item_1"))
      .tableShardingStrategy(new TableShardingStrategy("order_id", new ModuloTableShardingAlgorithm()))
      .dataSourceRule(dataSourceRule)
      .build();
  //Binding table policy, the main table strategy will be used to calculate the routed data source during query. Therefore, the rules of the table that agrees to bind the table strategy need to be consistent, which can improve efficiency to a certain extent  List&lt;BindingTableRule&gt; bindingTableRules = new ArrayList&lt;BindingTableRule&gt;();
  (new BindingTableRule((orderTableRule, orderItemTableRule)));
  return ()
      .dataSourceRule(dataSourceRule)
      .tableRules((orderTableRule, orderItemTableRule))
      .bindingTableRules(bindingTableRules)
      .databaseShardingStrategy(new DatabaseShardingStrategy("user_id", new ModuloDatabaseShardingAlgorithm()))
      .tableShardingStrategy(new TableShardingStrategy("order_id", new ModuloTableShardingAlgorithm()))
      .build();
}

Create a data source DataSource for sharding-jdbc, which MybatisAutoConfiguration will use

@Bean("dataSource")
public DataSource shardingDataSource(ShardingRule shardingRule){
  return (shardingRule);
}

Need to manually configure the transaction manager (the reason is unknown)

//Configuration transaction needs to be declared manually@Bean
public DataSourceTransactionManager transactitonManager(@Qualifier("dataSource") DataSource dataSource){
  return new DataSourceTransactionManager(dataSource);
}

Simple implementation of library distribution strategy, interface: DatabaseShardingAlgorithm

import ;
import ;

import ;
import ;
import ;

/**
  * Created by on May 11, 2017.
  */
public class ModuloDatabaseShardingAlgorithm implements SingleKeyDatabaseShardingAlgorithm&lt;Long&gt; {

  @Override
  public String doEqualSharding(Collection&lt;String&gt; databaseNames, ShardingValue&lt;Long&gt; shardingValue) {
   for (String each : databaseNames) {
      if ((() % 2 + "")) {
        return each;
      }
    }
    throw new IllegalArgumentException();
  }
  
  @Override
  public Collection&lt;String&gt; doInSharding(Collection&lt;String&gt; databaseNames, ShardingValue&lt;Long&gt; shardingValue) {
   Collection&lt;String&gt; result = new LinkedHashSet&lt;&gt;(());
    for (Long value : ()) {
      for (String tableName : databaseNames) {
        if ((value % 2 + "")) {
          (tableName);
        }
      }
    }
    return result;
  }
  
  @Override
  public Collection&lt;String&gt; doBetweenSharding(Collection&lt;String&gt; databaseNames, ShardingValue&lt;Long&gt; shardingValue) {
   Collection&lt;String&gt; result = new LinkedHashSet&lt;&gt;(());
    Range&lt;Long&gt; range = (Range&lt;Long&gt;) ();
    for (Long i = (); i &lt;= (); i++) {
      for (String each : databaseNames) {
        if ((i % 2 + "")) {
          (each);
        }
      }
    }
    return result;
  }

}

Basic implementation of table sub-stage strategy, interface: TableShardingAlgorithm

import ;
import ;

import ;
import ;
import ;

/**
  * Created by on May 11, 2017.
  */
public class ModuloTableShardingAlgorithm implements SingleKeyTableShardingAlgorithm&lt;Long&gt; {

  @Override
  public String doEqualSharding(Collection&lt;String&gt; tableNames, ShardingValue&lt;Long&gt; shardingValue) {
   for (String each : tableNames) {
      if ((() % 2 + "")) {
        return each;
      }
    }
    throw new IllegalArgumentException();
  }
  
  @Override
  public Collection&lt;String&gt; doInSharding(Collection&lt;String&gt; tableNames, ShardingValue&lt;Long&gt; shardingValue) {
   Collection&lt;String&gt; result = new LinkedHashSet&lt;&gt;(());
    for (Long value : ()) {
      for (String tableName : tableNames) {
        if ((value % 2 + "")) {
          (tableName);
        }
      }
    }
    return result;
  }
  
  @Override
  public Collection&lt;String&gt; doBetweenSharding(Collection&lt;String&gt; tableNames, ShardingValue&lt;Long&gt; shardingValue) {
   Collection&lt;String&gt; result = new LinkedHashSet&lt;&gt;(());
    Range&lt;Long&gt; range = (Range&lt;Long&gt;) ();
    for (Long i = (); i &lt;= (); i++) {
      for (String each : tableNames) {
        if ((i % 2 + "")) {
          (each);
        }
      }
    }
    return result;
  }

}

At this point, the function of dividing the database and dividing the table has been implemented

Read and write separation

Read and write separation requires adding a layer of master and slave data source creation before creating DataSourceRule

// Build a read-write separation data source. The read-write separation data source implements the DataSource interface, which can be directly processed as a data source.// masterDataSource0, slaveDataSource00, slaveDataSource01, etc. are real data sources configured using DBCP and other connection pools.DataSource masterSlaveDs0 = ("ms_0", 
          masterDataSource0, slaveDataSource00, slaveDataSource01);
DataSource masterSlaveDs1 = ("ms_1", 
          masterDataSource1, slaveDataSource11, slaveDataSource11);

// Build a database and table data sourceMap&lt;String, DataSource&gt; dataSourceMap = new HashMap&lt;&gt;(2);
("ms_0", masterSlaveDs0);
("ms_1", masterSlaveDs1);

// Continue to create ShardingDataSource through ShardingDataSourceFactory

When using the main library

HintManager hintManager = ();
();
// continueJDBCoperate

Forced routing

  1. Implemented using ThreadLocal mechanism, change the value used to calculate the route through HintManager before performing database operations
  2. When setting up HintManager, the policies for the partition library and the partition table must be set at the same time, and the tables that need to be routed after setting must be set to calculate the value of the route. For example, after forced routing, you need to operate two tables t_order and t_order_item, then the distribution and distribution strategies of both tables need to be set.
HintManager hintManager = ();
("t_order", "user_id", 1L);
("t_order", "order_id", ());
("t_order_item", "user_id", 1L);
("t_order_item", "order_id", ());

Transactions

  1. sharding-jdbc-transaction implements flexible transactions (memory-based transaction log memory and embedded asynchronous jobs are provided by default), and can combine elastic-job (sharding-jdbc-transaction-async-job) to implement asynchronous flexible transactions.
  2. There is no way to use it in combination with spring, you need to encapsulate it yourself

The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.