General documentation: Article directory Github: github.com/black-ant

A. The preface

Originally did not prepare to see this part of the source code, the cause of the matter is because before has been using 3.0 version, this time to see 5.0 want to try, the result did not run up, the official document does not give force, simply looked at the source code again, the problem found…..

Two. Where things started

The reason was that the shardingSphere-jdbc-core-spring-boot-starter dependency was used to complete all the configuration directly through the configuration file, but there were many problems in the whole process.

Fortunately, I have written a Bean configuration before, so I can see the problem with the whole process.

2.1 Java Bean Configuration Mode

The entire process of Java Bean configuration is posted here for comparison.2 uses JPA as the persistence framework

Maven configuration

<dependency>
    <groupId>org.apache.shardingsphere</groupId>
    <artifactId>shardingsphere-jdbc-core</artifactId>
    <version>5.0.0 - alpha</version>
</dependency>

Copy the code

The Config configuration

@Configuration
public class DatabaseConfig {

    /** * Method 1: configure */ through beans
    @Bean
    public DataSource dataSource(a) {
        // Configure the real data source
        Map<String, DataSource> dataSourceMap = new HashMap<>();

        // Configure the first data source
        BasicDataSource dataSource1 = new BasicDataSource();
        dataSource1.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource1.setUrl("JDBC: mysql: / / 127.0.0.1:3306 / database0? useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&serverTimezone=UTC");
        dataSource1.setUsername("root");
        dataSource1.setPassword("123456");
        dataSourceMap.put("ds0", dataSource1);

        // Configure the second data source
        BasicDataSource dataSource2 = new BasicDataSource();
        dataSource2.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource2.setUrl("JDBC: mysql: / / 127.0.0.1:3306 / database1? useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&serverTimezone=UTC");
        dataSource2.setUsername("root");
        dataSource2.setPassword("123456");
        dataSourceMap.put("ds1", dataSource2);

        // Configure the t_order table rule
        ShardingTableRuleConfiguration orderTableRuleConfig = new ShardingTableRuleConfiguration("t_blog"."ds${0.. 1}.t_blog_${0.. 1}");

        // Configure the primary key generation policy
        KeyGenerateStrategyConfiguration configuration = new KeyGenerateStrategyConfiguration("id".null);
        orderTableRuleConfig.setKeyGenerateStrategy(configuration);

        // Configure the library separation policy
        orderTableRuleConfig.setDatabaseShardingStrategy(new StandardShardingStrategyConfiguration("column_id"."dbShardingAlgorithm"));

        // Configure the sub-table policy
        orderTableRuleConfig.setTableShardingStrategy(new StandardShardingStrategyConfiguration("title_id"."tableShardingAlgorithm"));

        // Configure the sharding rule
        ShardingRuleConfiguration shardingRuleConfig = new ShardingRuleConfiguration();
        shardingRuleConfig.getTables().add(orderTableRuleConfig);

        // Configure the library separation algorithm
        Properties dbShardingAlgorithmrProps = new Properties();
        dbShardingAlgorithmrProps.setProperty("algorithm-expression"."ds${column_id % 2}");
        shardingRuleConfig.getShardingAlgorithms().put("dbShardingAlgorithm".new ShardingSphereAlgorithmConfiguration("INLINE", dbShardingAlgorithmrProps));

        // Configure the sub-table algorithm
        Properties tableShardingAlgorithmrProps = new Properties();
        tableShardingAlgorithmrProps.setProperty("algorithm-expression"."t_blog_${title_id % 2}");
        shardingRuleConfig.getShardingAlgorithms().put("tableShardingAlgorithm".new ShardingSphereAlgorithmConfiguration("INLINE", tableShardingAlgorithmrProps));

        DataSource dataSource = null;
        try {
            dataSource = ShardingSphereDataSourceFactory.createDataSource(dataSourceMap, Collections.singleton(shardingRuleConfig), new Properties());
        } catch (SQLException e) {
            e.printStackTrace();
        }
        //logger.info("datasource : {}", dataSource);
        returndataSource; }}Copy the code

Entity class

@Entity
@Table(name = "t_blog")
public class BlogEntity {

    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "title")
    private String title;

    @Column(name = "title_id")
    private Integer titleId;

    @Column(name = "author")
    private String author;

    @Column(name = "date")
    private Date date;

    @Column(name = "column_id")
    private Integer columnId;
    
    / /...
}

Copy the code

Properties Configuration mode

To avoid misdirection, the configuration file is posted at the end, and we’ll start with the exception

java.util.NoSuchElementException: No value bound

This is the first exception that appears. Look inside the exception stack. There are several important hints:

Caused by: java.lang.reflect.InvocationTargetException: null
	at org.apache.shardingsphere.spring.boot.util.PropertyUtil.v2(PropertyUtil.java:111) ~[shardingsphere-jdbc-spring-boot-starter-infra-5.0. 0-alpha.jar:5.0. 0-alpha]
	at org.apache.shardingsphere.spring.boot.util.PropertyUtil.handle(PropertyUtil.java:75) ~[shardingsphere-jdbc-spring-boot-starter-infra-5.0. 0-alpha.jar:5.0. 0-alpha]
	at org.apache.shardingsphere.spring.boot.datasource.DataSourceMapSetter.getDataSourceMap(DataSourceMapSetter.java:66) ~[shardingsphere-jdbc-spring-boot-starter-infra-5.0. 0-alpha.jar:5.0. 0-alpha]

/ / as you can see, the problem of local is org. Apache. Shardingsphere. Spring. The boot. Util. PropertyUtil. V2

// You can trace to the node getDataSourceMap 2 steps up
// This is where we first look: the loading of multiple data sources


// First look at the reason for the exception, then look at the overall logic
public static Map<String, DataSource> getDataSourceMap(final Environment environment) {
    Map<String, DataSource> result = new LinkedHashMap<>();
    Map<String, Object> dataSourceCommonProps = PropertyUtil.handle(environment, COMMON_PREFIX, Map.class);

/ /...

}


COMMON_PREFIX = COMMON_PREFIX = COMMON_PREFIX = COMMON_PREFIX
spring.shardingsphere.datasource.common.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.common.driver-class-name=com.mysql.jdbc.Driver

// To solve the problem, look at the overall logic


Copy the code

3.1 Multiple Data Sources

3.1.1 Loading multiple data sources

/ / core configuration is loaded from the org. Apache. Shardingsphere. Spring. The boot bag, the configuration is as followsC10- SpringBootConfiguration F01- SpringBootPropertiesConfiguration : F02-map <String, dataSourceMap > dataSourceMap Maintains a list of the DataSource M10_01 - shardingSphereDataSource - ShardingSphereDataSourceFactory. CreateDataSource: Incoming Map collections to create a DataSource - > M11_01 M10_02 - ShardingTransactionTypeScanner: transaction related C11 - ShardingSphereDataSourceFactory: M11_01 -createdatasource (Map<String, Datasource >,Collection<RuleConfiguration>, Properties) Create a datasource. create a datasource. create a datasource. create a datasource. create a datasource. create a datasource. create a datasource. create a datasource. create a datasource. create a datasource. create a datasource. - Map<String, DataSource> -> PS_M11_01_1 -new ShardingSphereDataSource(dataSourceMap, configurations, props) -> C12MC
            
/ / M11_01 code
public static DataSource createDataSource(final DataSource dataSource, final Collection<RuleConfiguration> configurations, final Properties props) throws SQLException {
    Map<String, DataSource> dataSourceMap = new HashMap<>(1.1);
    dataSourceMap.put(DefaultSchema.LOGIC_NAME, dataSource);
    return createDataSource(dataSourceMap, configurations, props);
}
            
            
// Build related objects from M11_01C12- ShardingSphereDataSource Mc-shardingspheredatasource - generate a DatabaseType -> M12_01 - build a SchemaContextsBuilder - Set TransactionContexts M12_01- createDatabaseType(Contexts M12_01)finalMap<String, dataSourceMap > dataSourceMap) CreateDatabaseType -> M12_02 - returns the DatabaseType of the last DataSource? - What is the purpose of the FOR loop here? M12_02 -createDatabaseType (M12_02 -createDatabaseType (M12_02 -createDatabaseType (finalDataSource dataSource) ? -Notice, this is2Datasource.getconnection () : getConnect - generates DatabaseType// M12_02 Pseudo-code: obtain DatabaseType from DatabaseTypeRegistry; MySQLDatabaseType is obtained here
private DatabaseType createDatabaseType(final DataSource dataSource) throws SQLException {
    if (dataSource instanceof ShardingSphereDataSource) {
        return ((ShardingSphereDataSource) dataSource).schemaContexts.getDatabaseType();
    }
    try (Connection connection = dataSource.getConnection()) {
        returnDatabaseTypeRegistry.getDatabaseTypeByURL(connection.getMetaData().getURL()); }}Copy the code

PS_M11_01_1: incoming resources depends on the spring shardingsphere. The datasource. The attribute names

As you can see, although I configured in the configuration of the three datasource, but in the end use is dependent on the properties of the spring. Shardingsphere. The datasource. Names.


// dataSourceMap is used to scan the data source in the configuration.

/ / PS: EnvironmentAware interfaces to the realization of the method, the method in ApplicationContextAwareProcessor calls by default
public final void setEnvironment(final Environment environment) {
    dataSourceMap.putAll(DataSourceMapSetter.getDataSourceMap(environment));
}


// Scan the specific DataSource
C- DataSourceMapSetter
    F- private static final String PREFIX = "spring.shardingsphere.datasource.";
    F- private static final String COMMON_PREFIX = "spring.shardingsphere.datasource.common."; M1-getdatasourcemap - Get the Common attribute: Spring.shardingsphere.datasource.com mon. - get Srouce name set - > M2 -, in turn, generate a DataSource in the set - > M3 M2 - getDataSourceNames: Obtain the datasource Name, Name for patchwork - preferential access to the spring. Shardingsphere. The datasource. The name - not for spring. Shardingsphere. The datasource. Names M3 - getDataSource -  Map<String, Object> dataSourceProps = mergedDataSourceProps(...) : Generate attributes - preconditions.checkState (...) : it is legal to have a validator - DataSourceUtil. GetDataSource (...). : create DataSource - followed by a syntax sugar to inject properties -> PS_M3_001/ / PS_M3_001: final statement execution is HikariDataSourcePropertiesSetter # propertiesSet
/ / get a spring in the Environment. Shardingsphere. The datasource. An data - the source - the properties prefix, set the relevant propertiesDataSourcePropertiesSetterHolder.getDataSourcePropertiesSetterByType(dataSourceProps.get(DATA_SOURCE_TYPE).toString()).i fPresent(propsSetter -> propsSetter.propertiesSet(environment, prefix, dataSourceName, result));Copy the code

3.1.2 Summary of multiple data sources

Starting point: SpringBootConfiguration processing core: ShardingSphereDataSourceFactory# createDataSource building blocks: ShardingSphereDataSource scan class: DataSourceMapSetter

In one sentence:

  • SpringBootConfiguration implements the EnvironmentAware method. When the container is loaded, the setEnvironment method in SpringBootConfiguration is called by default
  • The setEnvironment method scans the Datasourse configuration in the configuration file and puts in a dataSourceMap set
  • SpringBootConfiguration uses this Map when loading multiple data sources using shardingSphereDataSource
  • ShardingSphereDataSource method call ShardingSphereDataSourceFactory create a data source
  • Will eventually build ShardingSphereDataSourceFactory ShardingSphereDataSource, identifies a data source

3.2 Configuring database and Table Allocation policies

After the configuration runs through, there is another problem:

java.sql.SQLException: Parameter index out of range (1 > number of parameters, which is 0).

The runtime throws the above exception, which is a SQL problem, but my intuition is that this is a configuration aberration

Then, perform the following steps:

// Step 1 : PreparedStatement # checkBounds
// This is the first step in the stack of exceptions
if ((paramIndex < 1)) {
    throwSQLError.createSQLException(........) ; }else if (paramIndex > this.parameterCount) {
    throwSQLError.createSQLException(.......) ; }...// Step 2: Check the initialization method of the PreparedStatementC- PreparedStatement M-initializeFromParseInfo() - Look at staticSqlStrings and find that the parameter is incorrect, Only one array insert into org. Apache. Shardingsphere. Sharding. Rewrite. The token. Pojo. TableToken @ 3 df8c40 (author, column_id, date, title, title_id, id) values org.apache.shardingsphere.sharding.rewrite.token.pojo.ShardingInsertValuesToken@c1b5afe
// This value is also found to be incorrect, and an exception occurred during table processing
    
    
// Step 3: Check the logic of the tableC79-shardingrouteengine M79_05 -route0 -routedatasources Obtains the DataSource node of the policy judgment -routetables Obtains the table of the policy judgment// StandardShardingStrategy # doSharding
target = shardingAlgorithm.doSharding(availableTargetNames, new PreciseShardingValue(shardingValue.getTableName(), shardingValue.getColumnName(), each));

. / / the debug found here shardingValue getTableName () name is wrong -- -- -- -- -- -- -- > dt_blog_1, should be t_blog_1
// My goodness..... This looks like a configuration problem, check
spring.shardingsphere.rules.sharding.sharding-algorithms.db-algorithm.props.algorithm-expression=dt_blog_$->{title_id % 2}

/ / to
spring.shardingsphere.rules.sharding.sharding-algorithms.db-algorithm.props.algorithm-expression=t_blog_$->{title_id % 2}

// A process to check for exceptions through the source code is over

Copy the code

This is actually a configuration problem, but the exception returned by Sharding is not obvious.

conclusion

In the method C79-ShardinGrouteEngine/M79_05-route0, there are two main methods in the method, and the core judgment of the database table is in this method

Here record the loading path of the policy:

Properties, but the yML loading class is used, so there is no conflict

Specific is what configuration, according to the YamlShardingRuleConfiguration class to the backstepping is probably know


// Configure the mappingC- YamlShardingStrategyConfiguration ? - Data Configuration Indicates that the data is configured in the previous step to the current Configuration. You can directly configure the data using the properties in this class/ / Rule Rule
C- ShardingRuleSpringBootConfiguration
     
C- ShardingRuleAlgorithmProviderConfigurationYamlSwapper

C- ShardingTableRuleConfigurationYamlSwapper
    
// Specifies the injection location of algorithm-expression
C- ShardingRule
    M- ShardingRule(final AlgorithmProvidedShardingRuleConfiguration config, final Collection<String> dataSourceNames) 

Copy the code

3.3 Sub-database sub-table logic

Good, the project is finally running here, but the function of dividing the database and table is not implemented. At runtime, all four tables are created

Bebug found ShardingSpherePreparedStatement result returned to the four data

PS:M74_02_01

So according to the following process to go through the process of database sub-table:

As you can see, the first class is entrance ShardingSpherePreparedStatement

Step 1 : ShardingSpherePreparedStatement

This class is an entry class from which all related operations can be traced:

  • Core 1: The StatementExecuteUnit obtained in M74_01 is the SQL that will eventually be executed, which already contains the libraries that need to be run (see figure above), so when createExecutionContext is created, the relevant data is already generated
  • In the core 2: M74_01 preparedStatementExecutor. ExecuteUpdate initiate execution
C74 - ShardingSpherePreparedStatement M74_01 - executeUpdate () : an insert operation? - It's in this one3-createExecutionContext create an ExecutionContext -> M74_03? - Core logic, To generate the object needs to execute ExecuteUnit getInputGroups obtain a StatementExecuteUnit collection - > M74_02 - preparedStatementExecutor. ExecuteUpdate Execute the current statement M74_02 -getinputGroups ()? - core logic is through the relevant rules to generate the corresponding statement execution rule - to build a call PreparedStatementExecuteGroupEngine PreparedStatementExecuteGroupEngine - The generate method gets the data? - parameters: -- an optional executionContext. GetRouteContext ()? - Parameter 2: executionContext.getExecutionUnits() -> PS:M74_02_01 M74_03- createExecutionContext() - KernelProcessor. GenerateExecutionContext generated -- an optional ExecutionContext - > M75_01 - findGeneratedKey create a primary key/ / M74_02 code
private Collection<InputGroup<StatementExecuteUnit>> getInputGroups() throws SQLException {
    // Maximum number of connections
    int maxConnectionsSizePerQuery = schemaContexts.getProps().<Integer>getValue(ConfigurationPropertyKey.MAX_CONNECTIONS_SIZE_PER_QUERY);
    // 
    return new PreparedStatementExecuteGroupEngine(maxConnectionsSizePerQuery, connection, statementOption,
                schemaContexts.getDefaultSchema().getRules()).generate(executionContext.getRouteContext(), executionContext.getExecutionUnits());
}

Copy the code

Now that the source is in M74_01, keep looking -> M75_01

Step 2: The main processing logic of Rule

// There is only one method in this class
C75- KernelProcessor
    M75_01- generateExecutionContext
        1- Gets the ShardingSphereRule collection2- Create a SQLRouteEngine3- Get a SQLStatementContext: this can be mapped to a database operation4- Get RouteContext: this object determines how many databases/tables will be executed -> M76_01// M75_01  
public ExecutionContext generateExecutionContext(final LogicSQL logicSQL, final ShardingSphereSchema schema, final ConfigurationProperties props) {
        // PS:M75_01_01 rule Object
        Collection<ShardingSphereRule> rules = schema.getRules();
        SQLRouteEngine sqlRouteEngine = newSQLRouteEngine(rules, props); SQLStatementContext<? > sqlStatementContext = logicSQL.getSqlStatementContext();// Core statement: get RouteContext: this object determines how many databases/tables to execute -> M76_01
        RouteContext routeContext = sqlRouteEngine.route(logicSQL, schema);
        SQLRewriteEntry rewriteEntry = new SQLRewriteEntry(schema.getMetaData().getSchemaMetaData().getConfiguredSchemaMetaData(), props, rules);
        SQLRewriteResult rewriteResult = rewriteEntry.rewrite(logicSQL.getSql(), logicSQL.getParameters(), sqlStatementContext, routeContext);
        Collection<ExecutionUnit> executionUnits = ExecutionContextBuilder.build(schema.getMetaData(), rewriteResult, sqlStatementContext);
        return new ExecutionContext(sqlStatementContext, executionUnits, routeContext);
}


Copy the code

PS: M75_01_01 Rule structure

As you can see, the multiple data sources, the sharding rules, are already in there

The rest is easy, just find where you were before

Step 3 Debug Step by Step

C76- SQLRouteEngine M76_01- route: - Create a SQLRouteExecutor? - parameters:newPartialSQLRouteExecutor(rules, props) , Rule -> M77_01 C77- PartialSQLRouteExecutor M77_01- route Sqlrouter-entry.getvalue ().createrouteconText (logicSQL, schema, entry.getKey(), props) Core statement - > M78_01 C78 - ShardingSQLRouter M78_01 createRouteContext - ShardingRouteEngineFactory build a RouteEngine and call the corresponding M79_01 C79 -shardinGrouteEngine M79_01 -route (RouteContext RouteContext, RouteContext, ShardingRule ShardingRule) -getDatanodes Obtain Collection<DataNode> : -> M79_03? -> PS:M79_01_02 FOR loop obtain Nodes, Create RouteUnit M79_02 getDataNodes - createShardingStrategy create strategy M79_03 - routeByShardingConditions? - This will be called separately by Condition difference2A method - route0 - > M79_05 routeByShardingConditionsWithCondition - > M79_04 M79_04 - routeByShardingConditionsWithCondition : Core logic1For- loops through all the conditions, obtaining the policy and ShardingValues, Call route0 m79_05-route0 -routedatasources to obtain the DataSource node of the policy judgment. -routetables To obtain the table M79_06 -routetables - The Strategy class is then called// PS: If there is a problem with the TableRule, you can check to see if there is a problem with the method
private Collection<DataNode> getDataNodes(final ShardingRule shardingRule, final TableRule tableRule) {
    ShardingStrategy databaseShardingStrategy = createShardingStrategy(shardingRule.getDatabaseShardingStrategyConfiguration(tableRule), shardingRule.getShardingAlgorithms());
    ShardingStrategy tableShardingStrategy = createShardingStrategy(shardingRule.getTableShardingStrategyConfiguration(tableRule), shardingRule.getShardingAlgorithms());
    if (isRoutingByHint(shardingRule, tableRule)) {
        return routeByHint(tableRule, databaseShardingStrategy, tableShardingStrategy);
    }
    if (isRoutingByShardingConditions(shardingRule, tableRule)) {
        return routeByShardingConditions(shardingRule, tableRule, databaseShardingStrategy, tableShardingStrategy);
    }
    return routeByMixedConditions(shardingRule, tableRule, databaseShardingStrategy, tableShardingStrategy);
}


// M79_03 source code
private Collection<DataNode> routeByShardingConditions(final ShardingRule shardingRule, final TableRule tableRule, 
                                                           final ShardingStrategy databaseShardingStrategy, final ShardingStrategy tableShardingStrategy) {
    return shardingConditions.getConditions().isEmpty()
        ? route0(tableRule, databaseShardingStrategy, Collections.emptyList(), tableShardingStrategy, Collections.emptyList())
        : routeByShardingConditionsWithCondition(shardingRule, tableRule, databaseShardingStrategy, tableShardingStrategy);
}


C80- StandardShardingStrategy
    M80_01- doSharding
  
Copy the code

Here also is unknown in detail, the debug step by step down, found M79_04 – routeByShardingConditionsWithCondition strategy, with the lack of relevant configuration file writing problem, after completion, all is well

Final configuration file

server.port=8085
# # Jpa configuration
spring.jpa.database=mysql
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=none
# Enable configuration
spring.shardingsphere.enabled=true
# Configure real data sources DS0, DS1,ds2
spring.shardingsphere.datasource.names=ds0,ds1
spring.shardingsphere.datasource.common.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.common.driver-class-name=com.mysql.jdbc.Driver
Configure the first data source
spring.shardingsphere.datasource.ds0.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds0.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds0.jdbc-url=JDBC: mysql: / / 127.0.0.1:3306 / database0? useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&serverTimezone=UTC
spring.shardingsphere.datasource.ds0.username=root
spring.shardingsphere.datasource.ds0.password=123456
# Configure the second data source
spring.shardingsphere.datasource.ds1.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds1.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds1.jdbc-url=JDBC: mysql: / / 127.0.0.1:3306 / database1? useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&serverTimezone=UTC
spring.shardingsphere.datasource.ds1.username=root
spring.shardingsphere.datasource.ds1.password=123456
# configuration table strategy -- ShardingTableRuleConfiguration
spring.shardingsphere.rules.sharding.tables.t_blog.actual-data-nodes=ds$->{0.. 1}.t_blog_$->{0.. 1}
# configuration - KeyGenerateStrategyConfiguration primary key strategies
spring.shardingsphere.rules.sharding.tables.t_blog.key-generate-strategy.column=id
spring.shardingsphere.rules.sharding.tables.t_blog.key-generate-strategy.key-generator-name=snowflake
# configuration StandardShardingStrategyConfiguration table strategy
spring.shardingsphere.rules.sharding.tables.t_blog.binding-tables=t_blog
spring.shardingsphere.rules.sharding.tables.t_blog.table-strategy.standard.sharding-column=title_id
spring.shardingsphere.rules.sharding.tables.t_blog.table-strategy.standard.sharding-algorithm-name=db-algorithm
# configuration StandardShardingStrategyConfiguration depots strategy
spring.shardingsphere.rules.sharding.tables.t_blog.database-strategy.standard.sharding-column=column_id
spring.shardingsphere.rules.sharding.tables.t_blog.database-strategy.standard.sharding-algorithm-name=table-algorithm
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
# ===================== Configure the default policy
# Default insert type
spring.shardingsphere.rules.sharding.default-database-strategy.standard.sharding-column=id
spring.shardingsphere.rules.sharding.default-database-strategy.standard.sharding-algorithm-name=database_inline
# specify algorithms
spring.shardingsphere.rules.sharding.sharding-algorithms.database-inline.type=INLINE
spring.shardingsphere.rules.sharding.sharding-algorithms.database-inline.props.algorithm-expression=ds$->{id % 2}
# Default algorithm
spring.shardingsphere.rules.sharding.key-generators.snowflake.type=SNOWFLAKE
spring.shardingsphere.rules.sharding.key-generators.snowflake.props.worker-id=123
# Sharding strategy
spring.shardingsphere.rules.sharding.sharding-algorithms.db-algorithm.type=INLINE
spring.shardingsphere.rules.sharding.sharding-algorithms.db-algorithm.props.algorithm-expression=t_blog_$->{title_id % 2}
spring.shardingsphere.rules.sharding.sharding-algorithms.table-algorithm.type=INLINE
spring.shardingsphere.rules.sharding.sharding-algorithms.table-algorithm.props.algorithm-expression=ds$->{column_id % 2}
#!!!!!!!!!!! Table T_blog_0 and T_blog_1 correspond to the above two libraries

Copy the code

conclusion

Sharding-JDBC analysis is the most troublesome lombok expressions, debug up to call a trouble, but also to configure one by one, think about before the habit is better.

There are three main nodes in the whole process:

  • SpringBootConfiguration
  • ShardingRouteEngine
  • StandardShardingStrategy

The head and the middle are all here, so if you debug these three nodes, you basically have a problem

Note that Sharding – JDBC generates multiple executeUnits after policy execution. Each ExecuteUnit is a database processing object that will be executed in the corresponding database/data table

I’ll come back to his main logic of distributed transactions and read-write separation, but I’ll remember that much here