HintShardingStrategy
不需要分片键的强制分片策略。这个分片策略,简单来理解就是说,他的分片键不再跟SQL语句相关联,而是用程序另行指定。对于一些复杂的情况,例如select count(*) from (select userid from t_user where userid in (1,3,5,7,9))这样的SQL语句,就没法通过SQL语句来指定一个分片键。这个时候就可以通过程序,给他另行执行一个分片键,例如在按userid奇偶分片的策略下,可以指定
1作为分片键,然后自行指定他的分片策略。
配置参数:hint.algorithm-class-name 分片算法实现类。
sql和源码
https://gitee.com/zhangjijige/shardingjdbc.git
配置文件
spring:
main:
allow-bean-definition-overriding: true
shardingsphere:
# 参数配置,显示 sql
props:
sql:
show: true
datasource:
# 数据源别名
names: db0, db1, db2, db3
# db0数据源信息
db0:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/order_db_0?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT
username: root
password: root
db1:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/order_db_1?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT
username: root
password: root
db2:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/order_db_2?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT
username: root
password: root
db3:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/order_db_3?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT
username: root
password: root
sharding:
default-database-strategy:
hint:
algorithm-class-name: com.example.shardingjdbc.sharding.algorithm.HintShardingTableAlgorithm
tables:
# 逻辑表名
tbl_order:
# 指定数据节点
actual-data-nodes: db$->{0..3}.tbl_order_$->{0..3}
# 分库策略
database-strategy:
hint:
algorithm-class-name: com.example.shardingjdbc.sharding.algorithm.HintShardingDataBaseKeyAlgorithm
# 分表策略
table-strategy:
hint:
algorithm-class-name: com.example.shardingjdbc.sharding.algorithm.HintShardingTableKeyAlgorithm
mybatis:
mapper-locations: classpath:mapper/*.xml
HintShardingDataBaseKeyAlgorithm 分库策略
public class HintShardingDataBaseKeyAlgorithm implements HintShardingAlgorithm {
/**
* 自定义Hint 实现算法
* 能够保证绕过Sharding-JDBC SQL解析过程
* @param availableTargetNames
* @param shardingValue 不再从SQL 解析中获取值,而是直接通过hintManager.addTableShardingValue("t_order", 1)参数指定
* @return
*/
@Override
public Collection<String> doSharding(Collection availableTargetNames, HintShardingValue shardingValue){
System.out.println(shardingValue.toString());
return Lists.newArrayList("db0");
}
}
HintShardingTableKeyAlgorithm 分表策略
public class HintShardingTableKeyAlgorithm implements HintShardingAlgorithm {
/**
* 自定义Hint 实现算法
* 能够保证绕过Sharding-JDBC SQL解析过程
* @param availableTargetNames
* @param shardingValue 不再从SQL 解析中获取值,而是直接通过hintManager.addTableShardingValue("t_order", 1)参数指定
* @return
*/
@Override
public Collection<String> doSharding(Collection availableTargetNames, HintShardingValue shardingValue){
System.out.println(shardingValue.toString());
return Lists.newArrayList(shardingValue.getLogicTableName()+"_0");
}
}
数据查询示例
public void getOrderHint(){
//hint的策略规则是通过ThreadLocal方式,通过线程传递参数
//首先将上一次策略删除掉
HintManager.clear();
//创建instance
HintManager instance = HintManager.getInstance();
//不管是分库还是分表第一个参数都要是表的名称
instance.addDatabaseShardingValue("tbl_order","1");
instance.addTableShardingValue("tbl_order","2");
Long orderId = 1418875911339507713L;
OrderDto queryOrderDto = new OrderDto();
queryOrderDto.setOrderId(orderId);
List<OrderDto> orderDtoList = orderMapper.getOrdersComplex(queryOrderDto);
System.out.println(orderDtoList.toString());
//删除策略
instance.close();
}
Hint的特点就是不在需要依赖sql了,首先确定要分哪个表,比如这里是tbl_order表,去配置文件中查找tbl_order的配置,分库分表个子的algorithm-class-name