ShardingSphere集成SpringBoot时如何按角色查询指定分片表
实现方案
两种可行的实现路径,根据你的项目情况选择即可:
方案一:自定义分片策略+线程上下文传参(推荐,无业务侵入)
- 第一步:全局透传当前用户角色
用ThreadLocal封装上下文工具类,在请求拦截器中注入当前登录用户的角色,请求结束后清除避免线程复用污染:public class UserContextHolder { private static final ThreadLocal<String> USER_ROLE = new ThreadLocal<>(); public static void setRole(String role) { USER_ROLE.set(role); } public static String getRole() { return USER_ROLE.get(); } public static void clear() { USER_ROLE.remove(); } } - 第二步:实现自定义分表路由算法
实现ShardingSphere的PreciseShardingAlgorithm接口,路由逻辑直接读取上下文中的角色返回对应实际表:public class OrderRoleShardingAlgorithm implements PreciseShardingAlgorithm<Long> { @Override public String doSharding(Collection<String> availableTables, PreciseShardingValue<Long> shardingValue) { String role = UserContextHolder.getRole(); // 测试角色固定路由到order_1 if ("TEST".equals(role)) { return "order_1"; } // 普通用户默认路由到order_0 return "order_0"; } } - 第三步:修改ShardingSphere配置关联自定义算法
以yml配置为例:spring: shardingsphere: rules: sharding: tables: order: actual-data-nodes: 你的数据源名.order_$->{0..1} table-strategy: standard: sharding-column: user_id # 随便填一个order表中存在的字段即可,算法中不会用到该字段值 sharding-algorithm-name: order-role-alg sharding-algorithms: order-role-alg: type: CLASS_BASED props: strategy: standard algorithm-class-name: 你项目的全类名.OrderRoleShardingAlgorithm
方案二:Hint强制路由(适合不想修改原有分片规则的场景)
直接用切面拦截所有order表的查询操作,根据角色用ShardingSphere的HintManager强制指定路由表,完全不影响原有分片逻辑:
// 查询前设置路由规则 @Before("execution(* com.xxx.mapper.OrderMapper.select*(..))") public void setOrderRoute() { HintManager hintManager = HintManager.getInstance(); String role = UserContextHolder.getRole(); if ("TEST".equals(role)) { hintManager.addTableShardingValue("order", 1); } else { hintManager.addTableShardingValue("order", 0); } } // 查询结束清除路由规则 @After("execution(* com.xxx.mapper.OrderMapper.select*(..))") public void clearOrderRoute() { HintManager.clear(); }
注意事项
- 必须在请求拦截器的
afterCompletion方法中调用UserContextHolder.clear(),避免服务端线程池复用导致角色串用 - 异步查询场景需要手动把角色传递到异步线程,ThreadLocal默认不支持跨线程传值
- 要求高安全性的场景可以额外加MyBatis拦截器校验,测试角色的查询语句如果出现
order_0直接抛出权限异常
内容的提问来源于stack exchange,提问作者rellocs wood
相关产品推荐
相关产品推荐

