简介
ShardingSphere 应用 ThreadLocal 治理分片键值进行 Hint 强制路由。能够通过编程的形式向 HintManager 中增加分片值,该分片值仅在以后线程内失效。
Hint 形式次要应用场景:
1. 分片字段不存在 SQL 中、数据库表构造中,而存在于内部业务逻辑。
2. 强制在主库进行某些数据操作。
基于暗示 (Hint) 的数据分片
配置 Hint 分片算法
Hint 分片算法须要用户实现 org.apache.shardingsphere.api.sharding.hint.HintShardingAlgorithm
接口。ShardingSphere 在进行 Routing 时,如果发现 LogicTable 的 TableRule
采纳了
Hint 的分片算法,将会从HintManager
中获取分片值进行路由操作。
参考配置如下:
shardingRule:
tables:
t_order:
actualDataNodes: demo_ds_${0..1}.t_order_${0..1}
databaseStrategy:
hint:
algorithmClassName: org.apache.shardingsphere.userAlgo.HintAlgorithm
tableStrategy:
hint:
algorithmClassName: org.apache.shardingsphere.userAlgo.HintAlgorithm
defaultTableStrategy:
none:
defaultKeyGenerator:
type: SNOWFLAKE
column: order_id
props:
sql.show: true
获取 HintManager
HintManager hintManager = HintManager.getInstance();
增加分片键值
- 应用 hintManager.addDatabaseShardingValue 来增加数据源分片键值。
- 应用 hintManager.addTableShardingValue 来增加表分片键值。
分库不分表状况下,强制路由至某一个分库时,可应用
hintManager.setDatabaseShardingValue
形式增加分片。通过此形式增加分片键值后,将跳过 SQL 解析和改写阶段,从而进步整体执行效率。
革除分片键值
分片键值保留在 ThreadLocal 中,所以须要在操作完结时调用 hintManager.close()来革除 ThreadLocal 中的内容。
hintManager 实现了 AutoCloseable 接口,可举荐应用 try with resource 主动敞开。
残缺代码示例
// Sharding database and table with using hintManager.
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);
try (ResultSet rs = preparedStatement.executeQuery()) {while (rs.next()) {// ...}
}
}
// Sharding database without sharding table and routing to only one database with using hintManger.
String sql = "SELECT * FROM t_order";
try (HintManager hintManager = HintManager.getInstance();
Connection conn = dataSource.getConnection();
PreparedStatement preparedStatement = conn.prepareStatement(sql)) {hintManager.setDatabaseShardingValue(3);
try (ResultSet rs = preparedStatement.executeQuery()) {while (rs.next()) {// ...}
}
}
基于暗示 (Hint) 的强制主库路由
获取 HintManager
与基于暗示 (Hint) 的数据分片雷同。
设置主库路由
- 应用 hintManager.setMasterRouteOnly 设置主库路由。
革除分片键值
与基于暗示 (Hint) 的数据分片雷同。
残缺代码示例
String sql = "SELECT * FROM t_order";
try (HintManager hintManager = HintManager.getInstance();
Connection conn = dataSource.getConnection();
PreparedStatement preparedStatement = conn.prepareStatement(sql)) {hintManager.setMasterRouteOnly();
try (ResultSet rs = preparedStatement.executeQuery()) {while (rs.next()) {// ...}
}
}
example
hint-example