Sharding-JDBC-强制路由

强制路由

简介

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: 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来添加数据源分片键值。
  • 使用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

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 本文原创,使用本文请注明出处。 本文总结较为浅显,有兴趣的同学可直接参考官方文档 背景 为解决关系型数据库面对海量...
    梦娜丽智阅读 13,152评论 1 7
  • 五、因特网的路由选择协议 1.有关路由选择协议的几个基本概念 Ⅰ、理想的路由算法 路由表中的路由是怎样得出的呢?核...
    dmmy大印阅读 2,145评论 0 4
  • 简介 目前,在所有的区块链协议中每个节点存储所有的状态(账户余额,合约代码和存储等等)并且处理所有的交易。这提供了...
    编程狂魔阅读 1,090评论 0 3
  • 庞老师是我在新东方上班时的同事,那时她还是学管师。 对她记忆最深刻的有两点,第一是身高,一米七的个,亭亭玉立;第二...
    小清读书阅读 643评论 0 0
  • 从小,我和爷爷奶奶的感情很深,小时候有点怕爷爷,因为他发怒起来声音很大。所以跟奶奶走得更近,更习以为常在奶奶面前嘻...
    百屡薄冰阅读 621评论 0 0

友情链接更多精彩内容