强制路由剖析
# 强制路由剖析
ShardingSphere > 功能 > 数据分片 > 核心概念 > 强制分片路由 (opens new window)
ShardingSphere > 用户手册 > ShardingSphere-JDBC > 特殊 API > 数据分片 > 强制路由 (opens new window)
# 概述
在一些应用场景中,分片条件并不存在于SQL,而存在于外部业务逻辑。因此需要提供一种通过在外部业务代码中指定路由配置的一种方式,在ShardingSphere中叫做Hint。
如果使用Hint指定了强制分片路由,那么SQL将会无视原有的分片逻辑,直接路由至指定的数据节点操作。
HintManager主要使用ThreadLocal
管理分片键信息,进行hint强制路由。在代码中向HintManager
添加的配置信息只能在当前线程内有效。
private static final ThreadLocal<HintManager> HINT_MANAGER_HOLDER = new ThreadLocal();
# Hint 的主要使用场景
- 数据分片操作,如果分片键不存在 SQL 和数据库表结构中,而存在于外部业务逻辑。
- 读写分离操作,强制在主库进行某些数据操作。
- 强制在指定数据库进行某些数据操作。
# 使用方式
# 手动编程
实现Hint 分片算法,即实现HintShardingAlgorithm接口,定义分库或分表路由策略
public class MyHintShardingAlgorithm implements HintShardingAlgorithm<Long> { @Override public Collection<String> doSharding(Collection<String> availableTargetNames, HintShardingValue<Long> shardingValue) { // 添加分库或分表路由逻辑 } }
配置规则,参考配置
rules: - !SHARDING tables: t_order: actualDataNodes: demo_ds_${0..1}.t_order_${0..1} databaseStrategy: hint: algorithmClassName: xxx.xxx.xxx.HintXXXAlgorithm tableStrategy: hint: algorithmClassName: xxx.xxx.xxx.HintXXXAlgorithm defaultTableStrategy: none: defaultKeyGenerateStrategy: type: SNOWFLAKE column: order_id props: sql-show: true
获取 HintManager,指定执行策略值:
- 使用
hintManager.addDatabaseShardingValue
来添加数据源分片键值。 - 使用
hintManager.addTableShardingValue
来添加表分片键值。 - 使用
hintManager.setDatabaseShardingValue
方式添加分片,在分库不分表情况下,强制路由至某一个分库 - 使用
hintManager.setWriteRouteOnly
设置主库路由。
- 使用
清除分片键值,分片键值保存在 ThreadLocal 中,所以需要在操作结束时调用
hintManager.close()
来清除 ThreadLocal 中的内容。HintManager 实现了 AutoCloseable 接口,推荐使用 try with resource 自动关闭。
第三、四步骤代码参考如下:
String sql = "SELECT * FROM t_order";
try (HintManager hintManager = HintManager.getInstance();
Connection conn = dataSource.getConnection();
PreparedStatement preparedStatement = conn.prepareStatement(sql)) {
hintManager.addDatabaseShardingValue("t_order", 1); // 数据源分片键值
hintManager.addTableShardingValue("t_order", 2); // 表分片键值
// hintManager.setDatabaseShardingValue(3); // 强制路由至某一个分库
// hintManager.setWriteRouteOnly(); 强制主库路由
// hintManager.setDataSourceName("ds_0"); 路由至指定数据库
try (ResultSet rs = preparedStatement.executeQuery()) {
while (rs.next()) {
// ...
}
}
}
# SQL注释
SQL Hint 支持使用 Hint 强制主库路由或路由至指定数据库。该功能需要用户提前开启解析注释的配置,设置 sqlCommentParseEnabled
为 true
,目前只支持路由至一个数据源。 注释格式暂时只支持 /* */
,内容需要以 ShardingSphere hint:
开始,如下:
强制主库路由:
/* ShardingSphere hint: writeRouteOnly=true */
SELECT * FROM t_order;
路由至指定数据库
/* ShardingSphere hint: dataSourceName=ds_0 */
SELECT * FROM t_order;
个人不推荐这种用法,建议都用手动编程,代码去控制