Sub-database sub-table combat and middleware (4)
In some application scenarios, sharding conditions do not exist in SQL, but in external business logic. Therefore, it is necessary to provide a way to specify routing configuration in external business code, which is called Hint in ShardingSphere. If Hint is used to specify a mandatory sharding route, then SQL will ignore the original sharding logic and directly route to the specified data node operation.
Hint usage scenarios
- Data sharding operation, if the sharding key is not in the SQL or data table, but in the business logic code
- Read and write separation operations, if some data operations are forced to be performed on the main library
In the read-write separation structure, in order to avoid the master-slave synchronization data delay to obtain the newly added or updated data in time, you can use forced routing to query real-time data through the master database, and use hintManager.setMasterRouteOnly to set the route of the master database.
how to use
Just like our previous custom sharding strategy, sharding also provides us with an interface to implement the HintShardingAlgorithm interface and write sharding or sharding routing strategies.
Here we configure two databases, test0 and test1, and the two databases are divided into two tables position_master_slave0 and position_master_slave1
We enforce the routing policy on its modulo 2
/**
* hint 分片策略
*/
public class HintStrategyConfig implements HintShardingAlgorithm<Long> {
@Override
public Collection<String> doSharding(
Collection<String> collection, //库或者表集合
HintShardingValue<Long> hintShardingValue//路由key
) {
List<String> result = new ArrayList<>();
for (String table : collection) {
Collection<Long> values = hintShardingValue.getValues();
for (Long value : values) {
//这儿指定路由规则 我们这儿对库取模 后缀是多少进行选择库
if (table.endsWith(String.valueOf(value % 2))){
result.add(table);
}
}
}
return result;
}
}
复制代码
configuration
#打印shardingsphere sql
spring.shardingsphere.props.sql.show=true
# 分库信息配置
spring.shardingsphere.datasource.names=test0,test1
#配置数据库信息
#配置连接池
spring.shardingsphere.datasource.test0.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.test0.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.test0.jdbc-url=jdbc:mysql://localhost:3306/test0
spring.shardingsphere.datasource.test0.username=root
spring.shardingsphere.datasource.test0.password=root
#配置连接池
spring.shardingsphere.datasource.test1.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.test1.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.test1.jdbc-url=jdbc:mysql://localhost:3306/test1
spring.shardingsphere.datasource.test1.username=root
spring.shardingsphere.datasource.test1.password=root
#hint 强制指定库 路由
#强制路由库和表
## 指定库路由
spring.shardingsphere.sharding.tables.position_master_slave.database-strategy.hint.algorithm-class-name=com.udeam.hint.HintStrategyConfig
## 指定表路由
spring.shardingsphere.sharding.tables.position_master_slave.table-strategy.hint.algorithm-class-name=com.udeam.hint.HintStrategyConfig
spring.shardingsphere.sharding.tables.position_master_slave.actual-data-nodes=test$->{0..1}.position_master_slave$->{0..1}
# 表 雪花算法id
spring.shardingsphere.sharding.tables.position_master_slave.key-generator.column=id
#对应主键类getType返回内容
spring.shardingsphere.sharding.tables.position_master_slave.key-generator.type=SNOWFLAKE
复制代码
Responsive libraries and tables are ready here
force routing library
HintManager hintManager = HintManager.getInstance();
//选择库的路由 主库进行 0在我们自定义的路由算法中 对 两个库(test0,test1) % 2 操作 就是选择第一个库 即主库test0
hintManager.setDatabaseShardingValue(0L); // 强制路由库
System.out.println("记录数: " + positionMasterSlaveRepository.findAll().size());
复制代码
You can see that all tables in test0 are queried
Route a table in a library
@org.junit.Test
public void hintTest() {
/**
* 2 对某个库中表进行路由
*/
HintManager hintManagerTable = HintManager.getInstance();
//指定库
hintManagerTable.addDatabaseShardingValue("position_master_slave",0L);
//选择库中某个表进行路由,这儿设置对主库中 position_master_slave 表查询
hintManagerTable.addTableShardingValue("position_master_slave",0L);
System.out.println("记录数: " + positionMasterSlaveRepository.findAll().size());
}
复制代码
If not specified, all libraries and tables will be rolled over
HintManager hintManagerTable = HintManager.getInstance();
System.out.println("记录数: " + positionMasterSlaveRepository.findAll().size());
复制代码
Source code analysis
to be written...