SpringBoot 整合 Sharding-JDBC

article/2025/9/13 9:07:05

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 一、sharding-jdbc简介
  • 二、使用步骤
    • 1.新建项目、引入依赖
    • 2.代码实战
  • 总结





前言

SpringBoot 整合 Sharding-JDBC


提示:以下是本篇文章正文内容,下面案例可供参考




一、Sharding-JDBC简介

是轻量级的 java 框架,是增强版的 JDBC 驱动,就是简化分库分表后对数据相关操作




二、使用步骤




1.初始化环境

   项目需求就是银行流水信息入mysql,水平按照流水时间分片分库分表

   新建springboot项目引入下面依赖

   按照水平分表的方式,创建数据库和数据库表 

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.1.20</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><dependency><groupId>org.apache.shardingsphere</groupId><artifactId>sharding-jdbc-spring-boot-starter</artifactId><version>4.0.0-RC1</version></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.0.5</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency>
</dependencies>
CREATE TABLE `bank_flow_2021`.money_flow_202201 (
id INT(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
flow_id VARCHAR(50) NOT NULL COMMENT '流水id',
money DECIMAL(10,4) NOT NULL COMMENT '金额',
create_time TIMESTAMP COMMENT '创建时间',
flow_time  TIMESTAMP NOT NULL COMMENT '流水时间',
sharding_time BIGINT(20) NOT NULL COMMENT '分片时间'
)

 准备工作已经完成下面我们看下代码




2.实战

 首先我们需要修改配置文件,可以参考官网Spring Boot配置 :: ShardingSphere

 

# shardingjdbc 分片策略
# 配置数据源,给数据源起名称
spring.shardingsphere.datasource.names=bank2021,bank2022# 一个实体类对应多张表,覆盖
spring.main.allow-bean-definition-overriding=true#配置数据源具体内容,包含连接池,驱动,地址,用户名和密码
spring.shardingsphere.datasource.bank2021.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.bank2021.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.bank2021.jdbc-url=jdbc:mysql://127.0.0.1:3306/bank_flow_2021?autoReconnect=true&allowMultiQueries=true
spring.shardingsphere.datasource.bank2021.username=root
spring.shardingsphere.datasource.bank2021.password=123456#配置数据源具体内容,包含连接池,驱动,地址,用户名和密码
spring.shardingsphere.datasource.bank2022.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.bank2022.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.bank2022.jdbc-url=jdbc:mysql://127.0.0.1:3306/bank_flow_2022?autoReconnect=true&allowMultiQueries=true
spring.shardingsphere.datasource.bank2022.username=root
spring.shardingsphere.datasource.bank2022.password=123456#指定 money_flow 表分布情况,配置表在哪个数据库里面,表名称都是什么
spring.shardingsphere.sharding.tables.money_flow.actual-data-nodes=bank2021.money_flow_20210${1..9},bank2021.money_flow_20211${0..2},bank2022.money_flow_20220${1..9},bank2022.money_flow_20221${0..2}#指定数据库 表分片策略 数据库和表都用这个字段分片
spring.shardingsphere.sharding.tables.money_flow.database-strategy.standard.sharding-column=sharding_time
spring.shardingsphere.sharding.tables.money_flow.table-strategy.standard.sharding-column=sharding_time#数据库分片策略
spring.shardingsphere.sharding.tables.money_flow.database-strategy.standard.preciseAlgorithmClassName=com.example.demo.config.PreciseDatabaseShardingAlgorithm
spring.shardingsphere.sharding.tables.money_flow.database-strategy.standard.rangeAlgorithmClassName=com.example.demo.config.RangeDatabaseShardingAlgorithm#数据表分片策略
spring.shardingsphere.sharding.tables.money_flow.table-strategy.standard.preciseAlgorithmClassName=com.example.demo.config.PreciseTableShardingAlgorithm
spring.shardingsphere.sharding.tables.money_flow.table-strategy.standard.rangeAlgorithmClassName=com.example.demo.config.RangeTableShardingAlgorithm# 打开 sql 输出日志
spring.shardingsphere.props.sql.show=true

分片策略也就是通过分片字段怎么找的所需表,需要代码,数据库和表相关分片策略见下面代码

  • 精确分片算法用于处理使用单一键作为分片键的=与IN进行分片的场景

/*** 库精确分片算法**/
public class PreciseDatabaseShardingAlgorithm implements PreciseShardingAlgorithm<Long> {/*** 库精确分片算法** @param availableTargetNames 所有配置的库列表* @param shardingValue        分片值* @return 所匹配库的结果*/@Overridepublic String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<Long> shardingValue) {// 分片键值Long value = shardingValue.getValue();// 库后缀String yearStr = ShardingAlgorithmUtil.getYearByMillisecond(value);if (value <= 0) {throw new UnsupportedOperationException("preciseShardingValue is null");}for (String availableTargetName : availableTargetNames) {if (availableTargetName.endsWith(yearStr)) {return availableTargetName;}}throw new UnsupportedOperationException();}
}
  • 范围分片算法用于处理使用单一键作为分片键的BETWEEN AND、>、<、>=、<=进行分片的场景 

/*** 库范围分片算法**/
public class RangeDatabaseShardingAlgorithm implements RangeShardingAlgorithm<Long> {/*** 库范围分片算法** @param availableTargetNames 所有配置的库列表* @param rangeShardingValue   分片值,也就是save_time_com的值,范围分片算法必须提供开始时间和结束时间* @return 所匹配库的结果*/@Overridepublic Collection<String> doSharding(Collection<String> availableTargetNames,RangeShardingValue<Long> rangeShardingValue) {ArrayList<String> result = new ArrayList<>();Range<Long> range = rangeShardingValue.getValueRange();// 起始年和结束年int startYear = Integer.parseInt(ShardingAlgorithmUtil.getYearByMillisecond(range.lowerEndpoint()));int endYear = Integer.parseInt(ShardingAlgorithmUtil.getYearByMillisecond(range.upperEndpoint()));return startYear == endYear ? theSameYear(String.valueOf(startYear), availableTargetNames, result): differentYear(startYear, endYear, availableTargetNames, result);}/*** 同一年,说明只需要一个库*/private Collection<String> theSameYear(String startTime, Collection<String> availableTargetNames,ArrayList<String> result) {for (String availableTargetName : availableTargetNames) {if (availableTargetName.endsWith(startTime))result.add(availableTargetName);}return result;}/*** 跨年*/private Collection<String> differentYear(int startYear, int endYear, Collection<String> availableTargetNames,ArrayList<String> result) {for (String availableTargetName : availableTargetNames) {for (int i = startYear; i <= endYear; i++) {if (availableTargetName.endsWith(String.valueOf(i)))result.add(availableTargetName);}}return result;}
}


/*** 表精确分片算法*/
public class PreciseTableShardingAlgorithm implements PreciseShardingAlgorithm<Long> {/*** 表精确分片算法** @param availableTargetNames 所有配置的表列表,这里代表所匹配到库的所有表* @param shardingValue        分片值* @return 所匹配表的结果*/@Overridepublic String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<Long> shardingValue) {// 分片键值long value = shardingValue.getValue();if (value <= 0) {throw new UnsupportedOperationException("preciseShardingValue is null");}String yearJoinMonthStr = ShardingAlgorithmUtil.getYearJoinMonthByMillisecond(value);for (String availableTargetName : availableTargetNames) {if (availableTargetName.endsWith(yearJoinMonthStr)) {return availableTargetName;}}throw new UnsupportedOperationException();}
}

/*** 表范围分片算法**/
public class RangeTableShardingAlgorithm implements RangeShardingAlgorithm<Long> {/*** 表范围分片算法*/@Overridepublic Collection<String> doSharding(Collection<String> availableTargetNames,RangeShardingValue<Long> rangeShardingValue) {Range<Long> range = rangeShardingValue.getValueRange();long startMillisecond = range.lowerEndpoint();long endMillisecond = range.upperEndpoint();return getMonthBetween(startMillisecond, endMillisecond, availableTargetNames);}/*** 计算有效的库表名*/public static Collection<String> getMonthBetween(long minTime, long maxTime,Collection<String> availableTargetNames) {Collection<String> result = new ArrayList<>();Calendar min = Calendar.getInstance();Calendar max = Calendar.getInstance();min.setTime(new Date(minTime));min.set(min.get(Calendar.YEAR), min.get(Calendar.MONTH), 1);max.setTime(new Date(maxTime));max.set(max.get(Calendar.YEAR), max.get(Calendar.MONTH), 2);SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM");while (min.before(max)) {String yyyyMM = sdf.format(min.getTime());availableTargetNames.forEach(availableTargetName -> {if (availableTargetName.endsWith(yyyyMM)) {result.add(availableTargetName);}});min.add(Calendar.MONTH, 1);}return result;}
}

/*** 分片算法工具类*/
public class ShardingAlgorithmUtil {/*** 获取年份*/public static String getYearByMillisecond(long millisecond) {return new SimpleDateFormat("yyyy").format(new Date(millisecond));}/*** 获取年月*/public static String getYearJoinMonthByMillisecond(long millisecond) {return new SimpleDateFormat("yyyyMM").format(new Date(millisecond));}
}

新建实体类


@Data
@TableName(value = "money_flow")
public class BankFlow {private Long id;private String flowId;private BigDecimal money;private Instant flowTime;private Instant createTime;private Long shardingTime;
}

新建mapper

@Repository
public interface BankFlowMapper extends BaseMapper<BankFlow> {}

代码测试下


@SpringBootTest
class DemoApplicationTests {@Autowiredprivate BankFlowMapper bankFlowMapper;@Testvoid saveFlow() {BankFlow bankFlow = new BankFlow();bankFlow.setId(100L);bankFlow.setCreateTime(Instant.now());bankFlow.setFlowTime(Instant.now());bankFlow.setFlowId("ceshi");bankFlow.setMoney(new BigDecimal("888.88"));bankFlow.setShardingTime(new Date().getTime());bankFlowMapper.insert(bankFlow);}}


 数据已经进入相关的库表里面了




总结

以上就是今天要讲的内容,范围的分片之前查询的时候使用分片字段使用between..and ..就可以了


http://chatgpt.dhexx.cn/article/MUV4ZBym.shtml

相关文章

关东升的iOS实战系列图书 《iOS实战:传感器卷(Swift版)》已经上市

&#xfeff;&#xfeff; 承蒙广大读者的厚爱我的 《iOS实战&#xff1a;传感器卷&#xff08;Swift版&#xff09;》京东上市了&#xff0c;欢迎广大读者提出宝贵意见。http://item.jd.com/11760248.html 欢迎关注关东升新浪微博tony_关东升。 关注智捷课堂微信公共平台&…

Java从小白到大牛第1篇 Java基础-关东升-专题视频课程

Java从小白到大牛第1篇 Java基础—3042人已学习 课程介绍 本视频是智捷课堂推出的一套“Java语言学习立体教程”的视频第一部分&#xff0c;读者以及观看群是初级小白&#xff0c;通过本视频的学习能够成为Java大牛。本主要内容包括&#xff1a;Java语法基础、Java编码规范…

Sharding-JDBC 基础

Sharding-JDBC 是当当网开源的适用于微服务的分布式数据访问基础类库&#xff0c;完整的实现了分库分表&#xff0c;读写分离和分布式主键功能&#xff0c;并初步实现了柔性事务。 从 2016 年开源至今&#xff0c;在经历了整体架构的数次精炼以及稳定性打磨后&#xff0c;如今…

python从小白到大牛pdf 下载 资源共享_Kotlin从小白到大牛 (关东升著) 中文pdf高清版[12MB]...

本书是一本Kotlin语言学习立体教程&#xff0c;主要内容包括&#xff1a;Kotlin语法基础、Kotlin编码规范、数据类型、字符串、运算符、程序流程控制、函数、面向对象基础、继承与多态、抽象类与接口、高阶函数、Lambda表达式、数组、集合、函数式编程API、异常处理、线程、协程…

Java从小白到大牛第4篇项目实战1——PetStore宠物商店-关东升-专题视频课程

Java从小白到大牛第4篇项目实战1——PetStore宠物商店—1764人已学习 课程介绍 PetStore是Sun&#xff08;现在Oracle&#xff09;公司为了演示自己的Java EE技术&#xff0c;而编写的一个基于Web宠物店项目。PetStore是典型的电子商务项目&#xff0c;是现在很多电商平台的…

Sharding-JDBC(二)- Sharding-JDBC介绍

文章目录 一、Sharding-JDBC介绍1. Sharding-JDBC介绍2. Sharding-JDBC与JDBC性能对比 二、Sharding-JDBC快速入门1. 需求说明2. 环境搭建2.1 环境说明2.2 创建数据库2.3 引入maven依赖 3. 编写程序3.1 分片规则配置3.2.数据操作3.3.测试 4. 流程分析5. 其他集成方式5.1 Spring…

2022年适合初学者的Python书籍推荐

一、前言 网上有很多Python书或者视频&#xff0c;种类繁多该怎么选择&#xff1f; 看书全是文字看就了眼睛累&#xff0c;也容易厌倦&#xff0c;看视频有时候又觉得讲的慢&#xff0c;有其他方案吗&#xff1f; 其实&#xff0c;关于自学python&#xff0c;找一本浅显易懂&…

师傅带徒弟学:Python游戏开发引擎cocos2d-python-关东升-专题视频课程

师傅带徒弟学&#xff1a;Python游戏开发引擎cocos2d-python—299人已学习 课程介绍 Python语言之所以受欢迎&#xff0c;很大的原因是有很多可以使用的库&#xff0c;Python社区也有很多游戏开发库&#xff0c;其中较为优秀有&#xff1a;Cocos2d、Pyglet和Pygame&#xf…

关东升的《从零开始学Swift》即将出版

大家好&#xff1a; 苹果2015WWDC大会发布了Swift2.0&#xff0c;它较之前的版本Swift1.x有很大的变化&#xff0c;所以我即将出版《从零开始学Swift》《从零开始学Swift》将在《Swift开发指南》第1版的基础上添加Swift2.0的内容&#xff0c;同时摒弃第1版的一些不合理的内容&a…

最新出炉!《看漫画学Python 2》电子版火爆来袭,300页全新版PDF开放下载,零基础小白入门首选!

很多刚开始接触Python的朋友都会有一个共同的烦恼&#xff0c;自学好无聊&#xff0c;好枯燥&#xff0c;不想坚持了……所以秉持着让学Python好玩有趣的态度&#xff0c;给大家推荐一本最新出炉的“漫画书”《看漫画学Python 2》&#xff01; 图书简介&#xff1a;Python是一门…

关东升的《iOS实战:图形图像、动画和多媒体卷(Swift版)》上市了

关东升的《iOS实战&#xff1a;图形图像、动画和多媒体卷&#xff08;Swift版&#xff09;》上市了 承蒙广大读者的厚爱我的《iOS实战&#xff1a;图形图像、动画和多媒体卷&#xff08;Swift版&#xff09;》京东上市了&#xff0c;欢迎广大读者提出宝贵意见。。http://item.j…

关东升 IOS

51CTO博客大赛我的参赛主页http://blog.51cto.com/contest2013/701759期待您的一票&#xff01; 同时有好礼相送&#xff0c;欢迎学习iOS的小伙伴观看我的iOS入门免费系列课程如下&#xff1a; Objective C编程基础 &#xff08;24课时&#xff09; 只要4金币 iOS开发基础入门 …

Shell Date命令

shell Date命令 1、Date命令 date %Y 以四位数字格式打印年份 date %y 以二位数字格式打印年份 date %m 月份 date %d 日期 date %H 小时 date %M 分钟 date %S 秒 date %w 星期&#xff0c;如果结果显示0&#xff0c;则表示周日前一天的日期 date -d "-1 day" %d前…

Linux命令date命令

A.将日期转换为Unix时间戳 将当前时间以Unix时间戳表示&#xff1a; date %s 转换指定日期为Unix时间戳&#xff1a; date -d 2018-05-25 18:20 %s B.将Unix时间戳转换为日期时间 不指定日期时间的格式&#xff1a; date -d 1361542596 指定日期格式的转换&#xff1a; …

linux date输出时分秒,linux的date命令

date命令 在linux里面shell脚本打印时间。 date语法 date (选项)(参数)(date后面必须加空格)。 选项有下面几种 -d"字符串"&#xff1a;显示字符串所指定的时间&#xff1b; -s"字符串"&#xff1a;根据字符串设置时间&#xff1b; -u:显示GMT&#xff1b;…

Linux date命令

date命令是Linux中常用的一个命令&#xff0c;主要作用就是显示本机当前时间。如下&#xff1a; 在本人Linux操作系统中&#xff0c;date命令默认实现格式为年月日-星期-时分秒&#xff0c;然后是CST中央标准时间。不过&#xff0c;你也可以自行修改显示格式&#xff0c;如&…

Bash中的Date命令

Date命令可以用于显示时间和修改系统时间 这个就是查看当前时间 Date有很多时间代表符&#xff0c;而且各个代表符之间可以自定义多种符号 Linux有两个时钟&#xff0c;硬件时钟和系统时钟 clock是硬件时钟&#xff0c;而且clock只有root可以操作 clock与date之间可能会有差异&…

Linux命令之date命令详细讲解

一、date命令简介   Linux date命令可以用来显示或设定系统的日期与时间。在显示方面使用者可以设定欲显示的格式&#xff0c;格式设定为一个加号后接数个标记。在备份文件的时候我们常结合此命令生成当前日期和时间的文件名。格式符前面以加号开头&#xff0c;若是不以加号作…

Linux命令之date命令

一、date命令简介 Linux date命令可以用来显示或设定系统的日期与时间。在显示方面使用者可以设定欲显示的格式&#xff0c;格式设定为一个加号后接数个标记。在备份文件的时候我们常结合此命令生成当前日期和时间的文件名。格式符前面以加号开头&#xff0c;若是不以加号作为开…

turtle科赫雪花的源码分析

python turtle&#xff0c;科赫雪花源码 #KochDrawV1.py #导入海龟画图的基本库 import turtle #koch函数是是对科赫函数的基本绘制 def koch(size,n):if n 0:turtle.fd(size)else:for angle in [0,60,-120,60]:turtle.left(angle)koch(size/3, n-1) #main函数是对科赫函数的…