HintShardingStrategy
Hint强制路由
,通过Hint指定分片值而非从SQL中提取分片值的方式进行分片的策略。
在分库分区中,有些特定的SQL,Sharding-jdbc、Mycat、Vitess都不支持(可以查看相关文档各自对哪些SQL不支持),例如:insert into table1 select * from table2 where …这种SQL 路由很麻烦,需要解析table2的路由(是在ds0 /ds1 table2_0/table_1),结果集归并,insert 语句也需要同样的路由解析。这种情况Sharding-jdbc可以使用Hint分片策略来实现各种Sharding-jdbc不支持语法的限制:
- 通过Hint而非SQL解析的方式分片的策略。对于分片字段非SQL决定,而由其他外置条件决定的场景,可使用SQL Hint灵活的注入分片字段
- Hint分片策略是绕过SQL解析的,所以对于这些比较复杂的需要分片的查询,采用Hint分片策略性能可能会更好
- 在读写分离数据库中,Hint 可以通过HintManager.setMasterRouteOnly()方法,强制读主库(主从复制存在一定延时,但在某些特定的业务场景中,可能更需要保证数据的实时性)
- 在读写分离中,Hint 可以
强制读主库
(主从复制是存在一定延时,但在业务场景中,可能更需要保证数据的实时性)
配置
#hint强制路由策略
spring.shardingsphere.sharding.tables.course.table-strategy.hint.algorithm-class-name=com.roy.shardingDemo.algorithem.MyHintTableShardingAlgorithm
注意:这个我们仅设置表相关配置,没有库的,表示全部库
自定义实现类MyHintTableShardingAlgorithm :
package com.roy.shardingDemo.algorithem;
import org.apache.shardingsphere.api.sharding.hint.HintShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.hint.HintShardingValue;
import java.util.Arrays;
import java.util.Collection;
public class MyHintTableShardingAlgorithm implements HintShardingAlgorithm<Integer> {
@Override
public Collection<String> doSharding(Collection<String> availableTargetNames, HintShardingValue<Integer> shardingValue) {
String key = shardingValue.getLogicTableName() + "_" + shardingValue.getValues().toArray()[0];
if(availableTargetNames.contains(key)){
return Arrays.asList(key);
}
throw new UnsupportedOperationException("route "+ key +" is not supported ,please check your config");
}
}
shardingValue 不再从SQL 解析中获取值,而是直接通过hintManager.addTableShardingValue(“course”,2)参数指定
Hint强制路由,顾名思义,就是直接指定路由,不通过sql 分片键进行计算。
测试用例:
@Test
public void queryCourseByHint(){
HintManager hintManager = HintManager.getInstance();
hintManager.addTableShardingValue("course",2);
List<Course> courses = courseMapper.selectList(null);
courses.forEach(course -> System.out.println(course));
hintManager.close();
}
Hint分片策略必须要使用 HintManager工具类