【Java】ruoyi框架,添加ShardingJdbc支持分库分表

1、 调研,目前主流的有Mycat、Sharding Jdbc ,准备选用后者;

分库分表,一种是按照时间范围进行,另外一种按照某个字段为分片键;

我这里,选用表数据中的DeptId字段作为分片键,这样能够保证同一个部门下的数据 能够分布到同一个数据库下的同一张表中,避免跨库操作带来性能损失以及跨库操作带来的事物问题;

2、项目实战
2.1 配置项目环境

(1)添加项目pom

<dependency><groupId>org.apache.shardingsphere</groupId><artifactId>sharding-jdbc-spring-boot-starter</artifactId><version>4.1.1</version>
</dependency>
2.2 配置添加

(1)添加配置 application-sharding.yml(这部分主要是为了区分开分库分表的配置文件和其他,当然也可以直接在原有的配置文件基础上添加)

我这边默认按照两个数据库进行操作,其中处理了开票记录表和明细表 如有需要自己添加 ;

我这边分片键按照部门ID进行对2取余数,这样能够保证同一个部门下的数据能够到相同的数据库下相同的表中,避免了跨库操作;分片键可以自己进行调整 。

为什么是对2取余数?因为目前总共分出来2个数据库,dev_0、dev_1 如果是三个 那就是对3取余,总之 能够保证取余之后的范围在 0~n-1 ,n对应的是分出来的库数量。表也是一样的,我这边默认按照和库一样的规则。

spring:shardingsphere:enabled: true # 是否开启分库分表datasource:names: ds0,ds1ds0:type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://127.0.0.1:3306/xxx_dev_0?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=trueusername: rootpassword: rootds1:type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://127.0.0.1:3306/xxx_dev_1?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=trueusername: rootpassword: rootsharding:tables:output_base_invoice_history:name: tableName1database-strategy:  #分库策略inline:sharding-column: dept_id #分片列algorithm-expression: ds$->{dept_id % 2} # 计算数据分到哪个数据库actualDataNodes: ds$->{0..1}.tableName1_$->{0..1} # 映射到 ds0 和 ds1 数据源table-strategy:  #分表策略inline:algorithm-expression: tableName1_$->{dept_id % 2}sharding-column: dept_idoutput_base_history_invoice_items:name: tableName2database-strategy: #分库策略inline:sharding-column: dept_id #分片列algorithm-expression: ds$->{dept_id % 2} # 计算数据分到哪个数据库actualDataNodes: ds$->{0..1}.tableName2_$->{0..1} # 映射到 ds0 和 ds1 数据源table-strategy: #分表策略inline:algorithm-expression: tableName2_$->{dept_id % 2}sharding-column: dept_idprops:sql:show: truedatasource:type: com.alibaba.druid.pool.DruidDataSourcedriverClassName: com.mysql.cj.jdbc.Driverdruid:ds0:enabled: truetype: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://127.0.0.1:3306/xxx_dev_0?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=trueusername: rootpassword: rootds1:enabled: truetype: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://127.0.0.1:3306/xxx_dev_1?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=trueusername: rootpassword: root

(2)在ruoyi-framework工程下 修改DruidConfig类,添加Sharding的动态数据源支持:

首先,添加SHARDING的枚举

/*** 数据源** @author ruoyi*/
public enum DataSourceType {/*** 主库*/MASTER,/*** 从库*/SLAVE,/*** 分库分表*/SHARDING
}

其次,添加sharding规则到动态数据源

   @Bean(name = "dynamicDataSource")@Primarypublic DynamicDataSource dataSource(DataSource masterDataSource){Map<Object, Object> targetDataSources = new HashMap<>();targetDataSources.put(DataSourceType.MASTER.name(), masterDataSource);setDataSource(targetDataSources, DataSourceType.SLAVE.name(), "slaveDataSource");setDataSource(targetDataSources, DataSourceType.SHARDING.name(), "shardingDataSource");return new DynamicDataSource(masterDataSource, targetDataSources);}

之后,新建ShardingJdbc的配置类

/*** sharding 配置信息** @author yanjun.hou* <p>* 用法:@DataSource(DataSourceType.SHARDING)* 在对应需要分表操作的service方法上加上注解* 如整个service都需要分表操作, 可直接将该注解加载类上*/
@Configuration
public class ShardingDataSourceConfig {@Value("${spring.shardingsphere.sharding.tables.tableName1.name}")private String historyTable;@Value("${spring.shardingsphere.sharding.tables.tableName1.actualDataNodes}")private String historyTableActualDataNodes;@Value("${spring.shardingsphere.sharding.tables.tableName1.database-strategy.inline.sharding-column}")private String historyDbShardingColumn;@Value("${spring.shardingsphere.sharding.tables.tableName1.database-strategy.inline.algorithm-expression}")private String historyDbAlgorithmExpression;@Value("${spring.shardingsphere.sharding.tables.tableName1.table-strategy.inline.sharding-column}")private String historyTableShardingColumn;@Value("${spring.shardingsphere.sharding.tables.tableName1.table-strategy.inline.algorithm-expression}")private String historyTableAlgorithmExpression;@Value("${spring.shardingsphere.sharding.tables.tableName2.name}")private String historyItemsTable;@Value("${spring.shardingsphere.sharding.tables.tableName2.actualDataNodes}")private String historyItemsTableActualDataNodes;@Value("${spring.shardingsphere.sharding.tables.tableName2.database-strategy.inline.sharding-column}")private String historyItemsDbShardingColumn;@Value("${spring.shardingsphere.sharding.tables.tableName2.database-strategy.inline.algorithm-expression}")private String historyItemsDbAlgorithmExpression;@Value("${spring.shardingsphere.sharding.tables.tableName2.table-strategy.inline.sharding-column}")private String historyItemsTableShardingColumn;@Value("${spring.shardingsphere.sharding.tables.tableName2.table-strategy.inline.algorithm-expression}")private String historyItemsTableAlgorithmExpression;@Bean@ConfigurationProperties("spring.datasource.druid.ds0")@ConditionalOnProperty(prefix = "spring.datasource.druid.ds0", name = "enabled", havingValue = "true")public DataSource order1DataSource(DruidProperties druidProperties) {DruidDataSource dataSource = DruidDataSourceBuilder.create().build();return druidProperties.dataSource(dataSource);}@Bean@ConfigurationProperties("spring.datasource.druid.ds1")@ConditionalOnProperty(prefix = "spring.datasource.druid.ds1", name = "enabled", havingValue = "true")public DataSource order2DataSource(DruidProperties druidProperties) {DruidDataSource dataSource = DruidDataSourceBuilder.create().build();return druidProperties.dataSource(dataSource);}@Bean(name = "shardingDataSource")@ConditionalOnProperty(prefix = "spring.shardingsphere", name = "enabled", havingValue = "true")public DataSource shardingDataSource(@Qualifier("order1DataSource") DataSource order1DataSource, @Qualifier("order2DataSource") DataSource order2DataSource) throws SQLException {Map<String, DataSource> dataSourceMap = new HashMap<>();dataSourceMap.put("ds0", order1DataSource);dataSourceMap.put("ds1", order2DataSource);// 表规则配置TableRuleConfiguration invoiceHistory = new TableRuleConfiguration(historyTable, historyTableActualDataNodes);// 分库策略invoiceHistory.setDatabaseShardingStrategyConfig(new InlineShardingStrategyConfiguration(historyDbShardingColumn, historyDbAlgorithmExpression));// 分表策略invoiceHistory.setTableShardingStrategyConfig(new InlineShardingStrategyConfiguration(historyTableShardingColumn, historyTableAlgorithmExpression));// 表规则配置TableRuleConfiguration invoiceHistoryItems = new TableRuleConfiguration(historyItemsTable, historyItemsTableActualDataNodes);// 分库策略invoiceHistoryItems.setDatabaseShardingStrategyConfig(new InlineShardingStrategyConfiguration(historyItemsDbShardingColumn, historyItemsDbAlgorithmExpression));// 分表策略invoiceHistoryItems.setTableShardingStrategyConfig(new InlineShardingStrategyConfiguration(historyItemsTableShardingColumn, historyItemsTableAlgorithmExpression));// 分片规则ShardingRuleConfiguration shardingRuleConfig = new ShardingRuleConfiguration();Collection<TableRuleConfiguration> tableRuleConfigs = shardingRuleConfig.getTableRuleConfigs();tableRuleConfigs.add(invoiceHistory);tableRuleConfigs.add(invoiceHistoryItems);// 获取数据源对象DataSource dataSource = ShardingDataSourceFactory.createDataSource(dataSourceMap, shardingRuleConfig, getProperties());return dataSource;}/*** 系统参数配置*/private Properties getProperties() {Properties shardingProperties = new Properties();shardingProperties.put("sql.show", true);return shardingProperties;}
}

最后,用法

首先,需要在application.yml中添加激活配置

active: dev,sharding

其次,在对应业务Mapper或者ServiceImpl 或者对应的方法上 添加 @DataSource(DataSourceType.SHARDING) 即可。

第一种
@DataSource(DataSourceType.SHARDING)
public interface xxxMapper {}第二种
@DataSource(DataSourceType.SHARDING)
public class xxxServiceImpl {}第三种
@Override
@DataSource(DataSourceType.SHARDING)public XXX xxx() {return xxx;}

其中,第一种和第二种都表示当前类下的所有方法都默认按照分库分表的规则进行。

重点说明:由于ShardingJdbc不支持修改分片键,所以在mapper的xml更新语句中,需要排除掉分片键的更新。

说明:如果是在老项目上进行分库分表,那么一般会涉及到数据的迁移。

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

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

相关文章

启动vue项目执行npm run serve报错 : error in ./src/element-variables.scss

error in ./src/element-variables.scss 问题原因 node-sass的版本问题 解决方式 我直接更新了一下node-sass&#xff0c;就好了 npm install node-sass 再次执行就可以执行成功了

如何设置WhatsApp Business账号?

WhatsApp Business是WhatsApp为企业打造的一款应用程序&#xff0c;旨在帮助企业与客户更轻松地互动。如果您是一家出海企业&#xff0c;想要更好地与客户沟通&#xff0c;那么WhatsApp Business账号是您不可或缺的工具。 以下是设置WhatsApp Business账号的步骤&#xff1a; …

AIGC绘画关键词 - 写实少女

Unity3D特效百例案例项目实战源码Android-Unity实战问题汇总游戏脚本-辅助自动化Android控件全解手册再战Android系列Scratch编程案例软考全系列Unity3D学习专栏蓝桥系列ChatGPT和AIGC &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff0c;以及各种资源分…

【栈】20. 有效的括号

20. 有效的括号 思路总结 解决这个问题的关键是使用栈&#xff08;Stack&#xff09;这一数据结构。算法的核心思想是&#xff0c;当遍历到一个左括号时&#xff0c;将其压入栈中&#xff1b;当遍历到一个右括号时&#xff0c;尝试从栈顶弹出一个元素&#xff0c;并检查这个栈…

MongoDB黑窗口操作(CRUD)

目录 连接数据库 插入数据 for循环插入数据 根据条件查询 修改数据 删除数据 连接数据库 对应路径下cmd中输入命令mongo即可 插入数据 j{name:"mongo"} t{x:3} 提交&#xff1a;db.things.svae(j);db.things.svae(t); 查询&#xff1a;db.things.find(); …

Maven的settings.xml配置

maven的两大配置文件&#xff1a;settings.xml和pom.xml。其中settings.xml是maven的全局配置文件&#xff0c;pom.xml则是文件所在项目的局部配置 标签servers&#xff1a; 一般&#xff0c;仓库的下载和部署是在pom.xml文件中的repositories和distributionManagement元素中定…

Java面试挂在线程创建后续,不要再被八股文误导了!创建线程的方式只有1种

线程创建之源 OK&#xff01;咱们闲话少叙&#xff0c;直接进入正题&#xff0c;回顾一下通过实现Runnable接口&#xff0c;重写run方法创建线程的方式&#xff0c;真的可以创建一个线程吗&#xff1f;来看下面这段demo。 【代码示例1】 public class Test implements Runnab…

深入理解 Java 方法重载与递归应用

Java 方法重载 方法重载 允许在同一个类中定义多个具有相同名称的方法&#xff0c;但 参数列表 必须不同。 语法&#xff1a; returnType methodName(parameter1, parameter2, ..., parameterN) {// 方法体 }示例&#xff1a; public class Main {// 重载 add 方法&#xf…

信号处理--使用CNN+LSTM实现单通道脑电信号EEG的睡眠分期评估

目录 背景 亮点 环境配置 数据 方法 结果 代码获取 参考文献 背景 睡眠对人体健康很重要。监测人体的睡眠分期对于人体健康和医疗具有重要意义。 亮点 架构在第一层使用两个具有不同滤波器大小的 CNN 和双向 LSTM。 CNN 可以被训练来学习滤波器&#xff0c;以从原始…

redis缓存(穿透, 雪崩, 击穿, 数据不一致, 数据并发竞争 ), 分布式锁(watch乐观锁, setnx, redission)

redis的watch缓存机制 WATCH 机制原理&#xff1a; WATCH 机制&#xff1a;使用 WATCH 监视一个或多个 key , 跟踪 key 的 value 修改情况&#xff0c;如果有key 的 value 值在事务 EXEC 执行之前被修改了&#xff0c;整个事务被取消。EXEC 返回提示信息&#xff0c;表示 事务已…

JavaEE面试题

一、String面试题 1、String s1 "123"; 和 String s2 new String("123");的区别 在Java中&#xff0c;"String s1 "123";"和"String s2 new String("123");"这两行代码有一些重要的区别&#xff1a; "…

Linux安装,配置,启动HBase

Linux安装&#xff0c;配置&#xff0c;启动HBase 一、HBase安装&#xff0c;配置 1、下载HBase安装包 Hbase官方下载地址: http://archive.apache.org/dist/hbase 选择相应的版本点击下载&#xff0c;这里以2.3.5为例 # linux可以通过wget命令下载 wget https://archive…

Windows11安装FFmpeg最新版本

打开终端: 输入 winget install ffmpeg 然后输入 Y 回车后出现如下图: 正在下载FFmpeg 6.1 安装成功 测试

C++知识点总结(23):高级模拟算法真题 ★★★☆☆《骰子游戏》

骰子游戏 1. 审题 題目描述 E r i c Eric Eric 最近在澳门旅游&#xff0c;澳门游乐场有这样一个骰子游戏&#xff0c;他们使用三颗六面骰子&#xff0c;游戏规则如下&#xff1a;点数的优先级是 6 6 6、 5 5 5、 4 4 4、 3 3 3、 2 2 2、 1 1 1&#xff0c;当三个骰子的点数…

STM32CubeIDE基础学习-STM32CubeIDE软件配置下载器方法

STM32CubeIDE基础学习-STM32CubeIDE软件配置下载器方法 文章目录 STM32CubeIDE基础学习-STM32CubeIDE软件配置下载器方法前言第1章 配置ST-LINK下载器第2章 配置DAP下载器总结 前言 这个软件编译完之后&#xff0c;可以使用下载器进行在线下载程序或仿真调试程序&#xff0c;也…

050-WEB攻防-PHP应用文件包含LFIRFI伪协议编码算法无文件利用黑白盒

050-WEB攻防-PHP应用&文件包含&LFI&RFI&伪协议编码算法&无文件利用&黑白盒 #知识点&#xff1a; 1、文件包含-原理&分类&危害-LFI&RFI 2、文件包含-利用-黑白盒&无文件&伪协议 演示案例&#xff1a; ➢文件包含-原理&分类&am…

设计模式(工厂模式)

设计模式&#xff08;工厂模式&#xff09; 一、工厂模式介绍 在工厂模式中&#xff0c;父类决定生成示例的方式&#xff0c;但不决定所要生成的具体的类&#xff0c;具体的处理部分交给子类负责。这样就可以将生成示例的框架和生成示例的类解耦。 二、示例程序 以下示例程…

力扣-数组题

1. 两数之和 找出map中是否有target-nums[i]&#xff0c; class Solution { public:vector<int> twoSum(vector<int>& nums, int target) {unordered_map<int, int> hash;for(int i 0 ;i < nums.size(); i){if(hash.find(target - nums[i]) ! hash…

MongoDB安装教程(附带安装包)

目录 解压安装包 傻瓜式安装 选择安装目录 安装完成 启动验证 验证成功 解压安装包 选择所需要的进行安装 傻瓜式安装 选择安装目录 安装完成 启动验证 mongod --dbpathD:\mongodb\data\db 验证成功

VUE_自适应布局lib-flexible+postcss-pxtorem、lib-flexible + postcss-px2rem,nuxt页面自适配

lib-flexible postcss-pxtorem适配 我采用的是flexable.js和postcss-pxtorem。我一开始用的是postcss-px2rem后来发现和nuxt引入公共css的时候发生了冲突所以改用了postcss-pxtorem。 安装依赖 npm i lib-flexible -S npm install postcss-pxtorem --save 1、lib-flexible.…