ShardingSphere之ShardingJDBC客户端分库分表下

目录

ShardingJDBC实战

STANDARD标准分片策略

COMPLEX_INLINE复杂分片策略

 CLASS_BASED自定义分片策略

 HINT_INLINE强制分片策略


ShardingJDBC实战

       上篇已经将需要用到的类、数据库表都准备好了,本篇主要介绍分片配置文件。

STANDARD标准分片策略

       如果按照上篇文章所讲,使用INLINE分片算法是不能支持Between查找的,如果使用会报错。

    @Testpublic void queryCourseRange(){//select * from course where cid between xxx and xxxQueryWrapper<Course> wrapper = new QueryWrapper<>();wrapper.between("cid",957742087095189504L,957742088538030080L);List<Course> courses = courseMapper.selectList(wrapper);courses.forEach(course -> System.out.println(course));}

修改添加以下配置即可支持范围查找

# 允许在inline策略中使用范围查询。
spring.shardingsphere.rules.sharding.sharding-algorithms.course_tbl_alg.props.allow-range-query-with-inline-sharding=true

 虽然可以查询出数据,但是走的是全表扫描通过union联表查询。

以上案例使用STANDARD标准分片策略和INLINE分片算法来完成。


COMPLEX_INLINE复杂分片策略

 之前只可以根据cid进行分片查询,现在我们通过以下这种分片策略可以实现多字段分片查询。

配置文件如下:

# 指定对应的库
spring.shardingsphere.datasource.names=m0,m1spring.shardingsphere.datasource.m0.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.m0.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.m0.url=jdbc:mysql://localhost:3306/coursedb?serverTimezone=UTC
spring.shardingsphere.datasource.m0.username=root
spring.shardingsphere.datasource.m0.password=123456spring.shardingsphere.datasource.m1.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.m1.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.m1.url=jdbc:mysql://localhost:3306/coursedb2?serverTimezone=UTC
spring.shardingsphere.datasource.m1.username=root
spring.shardingsphere.datasource.m1.password=123456# 雪花算法,生成Long类型主键。
spring.shardingsphere.rules.sharding.key-generators.alg_snowflake.type=SNOWFLAKE
spring.shardingsphere.rules.sharding.key-generators.alg_snowflake.props.worker.id=1
# 指定分布式主键生成策略
spring.shardingsphere.rules.sharding.tables.course.key-generate-strategy.column=cid
spring.shardingsphere.rules.sharding.tables.course.key-generate-strategy.key-generator-name=alg_snowflake
#-----------------------配置实际分片节点m0,m1
spring.shardingsphere.rules.sharding.tables.course.actual-data-nodes=m$->{0..1}.course_$->{1..2}
#MOD分库策略
spring.shardingsphere.rules.sharding.tables.course.database-strategy.standard.sharding-column=cid
spring.shardingsphere.rules.sharding.tables.course.database-strategy.standard.sharding-algorithm-name=course_db_algspring.shardingsphere.rules.sharding.sharding-algorithms.course_db_alg.type=MOD
spring.shardingsphere.rules.sharding.sharding-algorithms.course_db_alg.props.sharding-count=2#给course表指定分表策略  complex-按多个分片键进行组合分片
spring.shardingsphere.rules.sharding.tables.course.table-strategy.complex.sharding-columns=cid,user_id
spring.shardingsphere.rules.sharding.tables.course.table-strategy.complex.sharding-algorithm-name=course_tbl_alg
# 分表策略-COMPLEX:按多个分片键组合分表
spring.shardingsphere.rules.sharding.sharding-algorithms.course_tbl_alg.type=COMPLEX_INLINE
spring.shardingsphere.rules.sharding.sharding-algorithms.course_tbl_alg.props.algorithm-expression=course_$->{(cid+user_id+1)%2+1}

配置中说明,通过cid和user_id实现多字段分片,如果存储数据不是按照这种分片策略和算法,那么需要灵活调整,配置文件中的调整为course_$->{(cid+user_id+1)%2+1}

    @Testpublic void queryCourseComplexSimple(){QueryWrapper<Course> wrapper = new QueryWrapper<Course>();
//        wrapper.orderByDesc("user_id");wrapper.in("cid",957742087095189504L,957742088538030080L);
//        wrapper.between("cid",799020475735871489L,799020475802980353L);wrapper.eq("user_id",1001L);List<Course> course = courseMapper.selectList(wrapper);//select * fro couse where cid in (xxx) and user_id between(8,3)System.out.println(course);}

执行结果如下:


 CLASS_BASED自定义分片策略

       如果我们希望在对user_id进行范围查询时,能够提前判断一些不合理的查询条件。而具体的判断规则,比如在对user_id进行between范围查询时,要求查询的下限不能超过查询上限,并且查询的范围必须包括1001L这个值。如果不满足这样的规则,那么就希望这个SQL语句就不要去数据库执行了。因为明显是不可能有数据的,还非要去数据库查一次,明显是浪费性能。那么这种情况就可以通过自定义分片策略来实现相当于快速失败的逻辑。比如像以下这种查询我们就希望快速失败。

    @Testpublic void queryCourdeComplex(){QueryWrapper<Course> wrapper = new QueryWrapper<Course>();wrapper.in("cid",957742087095189504L,957742088538030080L);wrapper.between("user_id",3L,8L);
//        wrapper.between("user_id",3L,3L);List<Course> course = courseMapper.selectList(wrapper);//select * fro couse where cid in (xxx) and user_id between(8,3)System.out.println(course);}

像上述中的user_id范围在3-8,在库中是明显不存在的,因为库中的user_id的值都为1001。

通过自定义来实现快速失败

配置文件

spring.shardingsphere.datasource.names=m0,m1spring.shardingsphere.datasource.m0.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.m0.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.m0.url=jdbc:mysql://localhost:3306/coursedb?serverTimezone=UTC
spring.shardingsphere.datasource.m0.username=root
spring.shardingsphere.datasource.m0.password=123456spring.shardingsphere.datasource.m1.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.m1.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.m1.url=jdbc:mysql://localhost:3306/coursedb2?serverTimezone=UTC
spring.shardingsphere.datasource.m1.username=root
spring.shardingsphere.datasource.m1.password=123456
#------------------------分布式序列算法配置
# 雪花算法,生成Long类型主键。
#spring.shardingsphere.rules.sharding.key-generators.alg_snowflake.type=COSID_SNOWFLAKE
spring.shardingsphere.rules.sharding.key-generators.alg_snowflake.type=SNOWFLAKE
spring.shardingsphere.rules.sharding.key-generators.alg_snowflake.props.worker.id=1
# 指定分布式主键生成策略
spring.shardingsphere.rules.sharding.tables.course.key-generate-strategy.column=cid
spring.shardingsphere.rules.sharding.tables.course.key-generate-strategy.key-generator-name=alg_snowflake
#-----------------------配置实际分片节点m0,m1
spring.shardingsphere.rules.sharding.tables.course.actual-data-nodes=m$->{0..1}.course_$->{1..2}
#MOD分库策略
spring.shardingsphere.rules.sharding.tables.course.database-strategy.standard.sharding-column=cid
spring.shardingsphere.rules.sharding.tables.course.database-strategy.standard.sharding-algorithm-name=course_db_algspring.shardingsphere.rules.sharding.sharding-algorithms.course_db_alg.type=MOD
spring.shardingsphere.rules.sharding.sharding-algorithms.course_db_alg.props.sharding-count=2#给course表指定分表策略  complex-按多个分片键进行组合分片
spring.shardingsphere.rules.sharding.tables.course.table-strategy.complex.sharding-columns=cid,user_id
spring.shardingsphere.rules.sharding.tables.course.table-strategy.complex.sharding-algorithm-name=course_tbl_alg# 使用CLASS_BASED分片算法- 不用配置SPI扩展文件
spring.shardingsphere.rules.sharding.sharding-algorithms.course_tbl_alg.type=CLASS_BASED
# 指定策略 STANDARD|COMPLEX|HINT
spring.shardingsphere.rules.sharding.sharding-algorithms.course_tbl_alg.props.strategy=COMPLEX
# 指定算法实现类。这个类必须是指定的策略对应的算法接口的实现类。 STANDARD-> StandardShardingAlgorithm;COMPLEX->ComplexKeysShardingAlgorithm;HINT -> HintShardingAlgorithm
spring.shardingsphere.rules.sharding.sharding-algorithms.course_tbl_alg.props.algorithmClassName=com.shardingDemo.algorithm.MyComplexAlgorithm

通过这种方式,需要自定义算法来实现,算法如下:

public class MyComplexAlgorithm implements ComplexKeysShardingAlgorithm<Long> {private static final String SHARING_COLUMNS_KEY = "sharding-columns";private Properties props;//保留配置的分片键。在当前算法中其实是没有用的。private Collection<String> shardingColumns;@Overridepublic void init(Properties props) {this.props = props;this.shardingColumns = getShardingColumns(props);}/*** 实现自定义分片算法* @param availableTargetNames 在actual-nodes中配置了的所有数据分片* @param shardingValue 组合分片键* @return 目标分片*/@Overridepublic Collection<String> doSharding(Collection<String> availableTargetNames, ComplexKeysShardingValue<Long> shardingValue) {//select * from cid where cid in (xxx,xxx,xxx) and user_id between {lowerEndpoint} and {upperEndpoint};Collection<Long> cidCol = shardingValue.getColumnNameAndShardingValuesMap().get("cid");Range<Long> userIdRange = shardingValue.getColumnNameAndRangeValuesMap().get("user_id");//拿到user_id的查询范围Long lowerEndpoint = userIdRange.lowerEndpoint();Long upperEndpoint = userIdRange.upperEndpoint();//如果下限 》= 上限if(lowerEndpoint >= upperEndpoint){//抛出异常,终止去数据库查询的操作throw new UnsupportedShardingOperationException("empty record query","course");//如果查询范围明显不包含1001}else if(upperEndpoint<1001L || lowerEndpoint>1001L){//抛出异常,终止去数据库查询的操作throw new UnsupportedShardingOperationException("error range query param","course");
//            return result;}else{List<String> result = new ArrayList<>();//user_id范围包含了1001后,就按照cid的奇偶分片String logicTableName = shardingValue.getLogicTableName();//操作的逻辑表 coursefor (Long cidVal : cidCol) {String targetTable = logicTableName+"_"+(cidVal%2+1);if(availableTargetNames.contains(targetTable)){result.add(targetTable);}}return result;}}private Collection<String> getShardingColumns(final Properties props) {String shardingColumns = props.getProperty(SHARING_COLUMNS_KEY, "");return shardingColumns.isEmpty() ? Collections.emptyList() : Arrays.asList(shardingColumns.split(","));}public void setProps(Properties props) {this.props = props;}@Overridepublic Properties getProps() {return this.props;}@Overridepublic String getType(){return "MYCOMPLEX";}
}

执行上述案例结果如下


 HINT_INLINE强制分片策略

强制指定查询的表

配置文件如下:

# 之前配置都一样,只更改分表策略
#给course表指定分表策略  hint-与SQL无关的方式进行分片
spring.shardingsphere.rules.sharding.tables.course.table-strategy.hint.sharding-algorithm-name=course_tbl_alg
# 分表策略-HINT:用于SQL无关的方式分表,使用value关键字。
spring.shardingsphere.rules.sharding.sharding-algorithms.course_tbl_alg.type=HINT_INLINE
spring.shardingsphere.rules.sharding.sharding-algorithms.course_tbl_alg.props.algorithm-expression=course_$->{value}
    @Testpublic void queryCourseByHint(){//强制只查course_1表HintManager hintManager = HintManager.getInstance();// 强制查course_1表
//        hintManager.setDatabaseShardingValue(1L);hintManager.addTableShardingValue("course","1");//select * from course;List<Course> courses = courseMapper.selectList(null);courses.forEach(course -> System.out.println(course));//线程安全,所有用完要注意关闭。hintManager.close();//hintManager关闭的主要作用是清除ThreadLocal,释放内存。HintManager实现了AutoCloseable接口,所以建议使用try-resource的方式,用完自动关闭。//try(HintManager hintManager = HintManager.getInstance()){ xxxx }}

 执行结果如下

 可以看到数据查询的两个数据库中course1表。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/651401.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

golang版本使用令牌桶算法来实现限流的策略

代码 package mainimport ("fmt""sync""time" )// 令牌桶结构体 type TokenBucket struct {tokens chan struct{}rate time.Duration// 桶容量limit int }// 创建令牌桶 func NewTokenBucket(rate time.Duration, limit int) *TokenBucket {r…

纳斯达克户外大屏背景配什么颜色效果最好-大舍传媒

纳斯达克户外大屏背景配什么颜色效果最好 引言 纳斯达克大屏是世界闻名的户外广告媒体之一&#xff0c;通过高清大屏呈现的广告内容吸引了众多目光。大舍传媒作为纳斯达克大屏的提供商和运营商之一&#xff0c;致力于创造最佳的视觉效果来吸引观众的注意力。在纳斯达克大屏投…

C语言“++”和“--”运算符需要注意些什么?

一、问题 “”和“--”运算符经常被应⽤&#xff0c;使⽤这两种运算符需要注意些什么&#xff1f; 二、解答 在使用C语言中的自增&#xff08;&#xff09;和自减&#xff08;--&#xff09;运算符时&#xff0c;需要注意以下几点&#xff1a; 1、运算规则 运算符有两种形式&…

cs2系统提升思路

思路/战术 > 道具 > 练枪 思路/战术 通用的思路 > 针对性学习每一张图的思路 注意&#xff0c;休闲中人数较多&#xff0c;战术的体现不多&#xff0c;不要休闲打习惯了适应不了竞技 地图理解 / 分析 根据地形分析攻防 &#xff08;比如dust2&#xff0c;所有道路…

HCIA学习作业四

要求&#xff1a; 1、AR3还回为3.3.3.0/24 2、其他基于192.168.1.0/24进行合理划分 3、AR1和AR2均存在两个环回 4、整个网络运行RIP v2 但是不能直接宣告AR3的环回 5、全网可达&#xff0c;保障更新安全&#xff0c;尽量减少路由条目&#xff0c;避免环路 拓扑图&#xf…

EXP脚本编写

EXP脚本的编写与POC脚本编写一样&#xff0c;只需要修改_attack部分&#xff0c;替换成漏洞 利用的脚本即可。要利用Flask漏洞&#xff0c;需要用到Python的特性。关于如何在Jinja2模 板中执行Python代码&#xff0c;官方给出的方法是在模板环境中注册函数就可以进行调 用。 J…

java servlet运输公司管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 java Web运输公司管理系统是一套完善的java web信息管理系统 serlvetdaobean mvc 模式开发 &#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主 要采用B/S模式开发。开发环境为TOMCAT7.0,Myeclipse8.5…

Multi-label classification复现

摘要 存在 theoretical results show that SA and HL are conflicting measures 1 介绍 an algorithm usually performs well on some measures while poorly on others.There are a few works studying the behavior of various measures.Although they provide valuable i…

【网站项目】基于SSM的246品牌手机销售信息系统

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

多路复用简述

1、概念 多路复用是一种计算机编程和通信领域的技术,用于有效地处理多个输入/输出任务或连接,提高系统的性能和响应性。它的主要目的是在一个单一的线程或进程中同时处理多个任务,而不是为每个任务创建一个独立的线程或进程。 在网络编程中,多路复用通常通过以下几种机制来…

cmake工具的安装

1、简介 CMake 是一个开源的、跨平台的自动化建构系统。它用配置文件控制编译过程的方式和Unix的make相似&#xff0c;只是CMake并不依赖特定的编译器。CMake并不直接建构出最终的软件&#xff0c;而是产生标准的建构文件&#xff08;如 Unix 的 Makefile 或 Windows Visual C …

自述20年的痛:一个读书人的知识与自恋,自古文人多清高

自述20年的痛&#xff1a;一个读书人的知识与自恋&#xff0c;自古文人多清高 20年读书的痛&#xff1a;你就是书读太多了&#xff0c;想法太多了&#xff0c;没必要20年读错了书&#xff1a;这些知识没有帮助我培养竞争力&#xff0c;而只是增强了我的自恋 20年读书的痛&#…

常见命令及参数

目录 rpm yum rpm rpm是基本的管理软件的指令。用于互联网下载包的打包及安装工具&#xff0c;它包含在某些Linux分发版中。它生成具有.RPM扩展名的文件。 安装软件&#xff1a;rpm –ivh filename.rpm 升级软件&#xff1a;rpm –Uvh filename.rpm 卸载软件&#xff1a…

使用Apache POI 创建和读取excel表

目录 1. Apache POI 中文使用手册 1.1 Apache POI 项目介绍 1.2 处理组件 1.2.1 Excel 文件处理组件 1.2.2 Word 文件处理组件 1.2.3 PPT 文件处理组件 1.2.4 文档属性组件 1.2.5 Visio 文件处理组件 1.2.6 Microsoft Publisher 98&#xff08;-2007&#xff09;文件处…

kotlin data clas 数据类

data class 介绍 kotlin 中 data class 是一种持有数据的特殊类 编译器自动从主构造函数中声明的所有属性导出以下成员&#xff1a; .equals()/.hashCode() 对 .toString() 格式是 "User(nameJohn, age42)" .componentN() 函数 按声明顺序对应于所有属性。…

mac配置L2TP连接公司内网

1. 打开系统设置 2. 打开网络 3. 点击网络页面其他服务右下角三个点&#xff0c;添加VPN配置中的L2TP 4. 配置VPN&#xff0c;服务器填写公司的服务器ip&#xff0c;共享密钥没有可以随便填写 5. 打开终端编辑文件 sudo vim /etc/ppp/opt…

机电制造ERP软件有哪些品牌?哪家的机电制造ERP系统比较好

机电制造过程比较复杂&#xff0c;涵盖零配件、采购、图纸设计、工艺派工、生产计划、物料需求计划、委外加工等诸多环节。而供应链涉及供应商的选择、材料采购价格波动分析、材料交货、品质检验等过程&#xff0c;其中某个环节出现问题都可能会影响产品交期和经营效益。 近些…

在Vue的模块开发中使用GPT的体验及总结

我这一周都在忙着实现一个页面&#xff0c;这个页面是通过vue基于element-ui来实现的。在这个过程中&#xff0c;我把页面拆分成多个组件&#xff0c;而组件的生成是通过Chat-GPT3来实现的。 这又是一次使用AI来协同开发的体验&#xff0c;觉得有必要总结一下&#xff1a; 遵循…

概念抽取:构建认知基础的关键步骤

目录 前言1 概念抽取任务定义1.1 概念知识图谱的关系定义1.2 实体与概念的紧密关联1.3 多样的概念关系 2 概念在认知中的重要角色2.1 语言理解的基础2.2 上下位关系的深化理解 3 概念抽取方法3.1 基于模板的抽取3.2 基于百科的抽取3.3 基于机器学习的方法 4 应用4.1 自然语言理…

Java基础面试题-5day

泛型 什么是泛型&#xff1f;有什么用&#xff1f; 泛型是jdk5引入的新特性&#xff0c;通过泛型可以提高代码的可读性和稳定性&#xff1b;当我们使用泛型时&#xff0c;传入的对象类型必须是指定的泛型类型&#xff0c;否则就会报错 泛型的使用方式有哪些&#xff1f; 一…