強(qiáng)制路由
簡(jiǎn)介
ShardingSphere使用ThreadLocal管理分片鍵值進(jìn)行Hint強(qiáng)制路由劳坑。可以通過(guò)編程的方式向HintManager中添加分片值入篮,該分片值僅在當(dāng)前線程內(nèi)生效谨垃。 Hint方式主要使用場(chǎng)景:
1.分片字段不存在SQL中、數(shù)據(jù)庫(kù)表結(jié)構(gòu)中墓拜,而存在于外部業(yè)務(wù)邏輯港柜。
2.強(qiáng)制在主庫(kù)進(jìn)行某些數(shù)據(jù)操作。
基于暗示(Hint)的數(shù)據(jù)分片
配置Hint分片算法
Hint分片算法需要用戶(hù)實(shí)現(xiàn)org.apache.shardingsphere.api.sharding.hint.HintShardingAlgorithm
接口咳榜。ShardingSphere在進(jìn)行Routing時(shí)夏醉,如果發(fā)現(xiàn)LogicTable的TableRule
采用了 Hint的分片算法,將會(huì)從HintManager
中獲取分片值進(jìn)行路由操作涌韩。
參考配置如下:
shardingRule:
tables:
t_order:
actualDataNodes: demo_ds_${0..1}.t_order_${0..1}
databaseStrategy:
hint:
algorithmClassName: yourHintShardingAlgorithm
tableStrategy:
hint:
algorithmClassName: yourHintShardingAlgorithm
defaultDatabaseStrategy:
inline:
shardingColumn: user_id
algorithmExpression: demo_ds_${user_id % 2}
defaultTableStrategy:
none:
defaultKeyGenerator:
type: SNOWFLAKE
props:
sql.show: true
獲取HintManager
HintManager hintManager = HintManager.getInstance();
添加分片鍵值
- 使用hintManager.addDatabaseShardingValue來(lái)添加數(shù)據(jù)源分片鍵值畔柔。
- 使用hintManager.addTableShardingValue來(lái)添加表分片鍵值。
分庫(kù)不分表情況下臣樱,強(qiáng)制路由至某一個(gè)分庫(kù)時(shí)靶擦,可使用
hintManager.setDatabaseShardingValue
方式添加分片。通過(guò)此方式添加分片鍵值后雇毫,將跳過(guò)SQL解析和改寫(xiě)階段玄捕,從而提高整體執(zhí)行效率。
清除分片鍵值
分片鍵值保存在ThreadLocal中棚放,所以需要在操作結(jié)束時(shí)調(diào)用hintManager.close()來(lái)清除ThreadLocal中的內(nèi)容枚粘。
hintManager實(shí)現(xiàn)了AutoCloseable接口,可推薦使用try with resource自動(dòng)關(guān)閉飘蚯。
完整代碼示例
// 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)的強(qiáng)制主庫(kù)路由
獲取HintManager
與基于暗示(Hint)的數(shù)據(jù)分片相同馍迄。
設(shè)置主庫(kù)路由
- 使用hintManager.setMasterRouteOnly設(shè)置主庫(kù)路由。
清除分片鍵值
與基于暗示(Hint)的數(shù)據(jù)分片相同局骤。
完整代碼示例
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()) {
// ...
}
}
}