From 7f43276d3fb39383d7d3cf6d2d8e07cdac7ac5d9 Mon Sep 17 00:00:00 2001 From: D <3066417822@qq.com> Date: Wed, 24 Apr 2024 01:40:39 +0800 Subject: [PATCH] =?UTF-8?q?=E9=9B=86=E6=88=90=E4=BA=86=E5=88=86=E8=A1=A8?= =?UTF-8?q?=E6=93=8D=E4=BD=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/resources/application-druid.yml | 14 +++ .../ruoyi/common/enums/DataSourceType.java | 10 +- ruoyi-framework/pom.xml | 12 +- .../ruoyi/framework/config/DruidConfig.java | 6 + .../config/ShardingDataSourceConfig.java | 110 ++++++++++++++++++ 5 files changed, 146 insertions(+), 6 deletions(-) create mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/config/ShardingDataSourceConfig.java diff --git a/ruoyi-admin/src/main/resources/application-druid.yml b/ruoyi-admin/src/main/resources/application-druid.yml index fbf50ab..4c67198 100644 --- a/ruoyi-admin/src/main/resources/application-druid.yml +++ b/ruoyi-admin/src/main/resources/application-druid.yml @@ -16,6 +16,20 @@ spring: url: username: password: + sharding: + # 分库分表开关/默认关闭 + enabled: false + order1: + enabled: false + url: + username: + password: + order2: + enabled: false + url: + username: + password: + # 初始连接数 initialSize: 5 # 最小连接池数量 diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/enums/DataSourceType.java b/ruoyi-common/src/main/java/com/ruoyi/common/enums/DataSourceType.java index 0d945be..f380fc6 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/enums/DataSourceType.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/enums/DataSourceType.java @@ -5,8 +5,7 @@ package com.ruoyi.common.enums; * * @author ruoyi */ -public enum DataSourceType -{ +public enum DataSourceType { /** * 主库 */ @@ -15,5 +14,10 @@ public enum DataSourceType /** * 从库 */ - SLAVE + SLAVE, + + /** + * 分库分表 + */ + SHARDING } diff --git a/ruoyi-framework/pom.xml b/ruoyi-framework/pom.xml index bd73a96..783ba29 100644 --- a/ruoyi-framework/pom.xml +++ b/ruoyi-framework/pom.xml @@ -1,7 +1,6 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> ruoyi com.ruoyi @@ -18,7 +17,7 @@ - + org.springframework.boot spring-boot-starter-web @@ -35,6 +34,13 @@ druid-spring-boot-3-starter + + + org.apache.shardingsphere + sharding-jdbc-core + 4.1.1 + + pro.fessional diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/DruidConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/DruidConfig.java index 73fc26c..18a0f4b 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/DruidConfig.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/DruidConfig.java @@ -6,6 +6,8 @@ import java.util.Map; import javax.sql.DataSource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.web.servlet.FilterRegistrationBean; @@ -36,6 +38,8 @@ import jakarta.servlet.ServletResponse; @Configuration public class DruidConfig { + Logger logger = LoggerFactory.getLogger(DruidConfig.class); + @Bean @ConfigurationProperties("spring.datasource.druid.master") public DataSource masterDataSource(DruidProperties druidProperties) { @@ -57,6 +61,7 @@ public class DruidConfig { Map 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); } @@ -72,6 +77,7 @@ public class DruidConfig { DataSource dataSource = SpringUtils.getBean(beanName); targetDataSources.put(sourceName, dataSource); } catch (Exception e) { + logger.error("Failed to register a data source:{}", beanName); } } diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ShardingDataSourceConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ShardingDataSourceConfig.java new file mode 100644 index 0000000..5b79d62 --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ShardingDataSourceConfig.java @@ -0,0 +1,110 @@ +package com.ruoyi.framework.config; + +import java.sql.SQLException; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +import javax.sql.DataSource; + +import org.apache.shardingsphere.api.config.sharding.KeyGeneratorConfiguration; +import org.apache.shardingsphere.api.config.sharding.ShardingRuleConfiguration; +import org.apache.shardingsphere.api.config.sharding.TableRuleConfiguration; +import org.apache.shardingsphere.api.config.sharding.strategy.InlineShardingStrategyConfiguration; +import org.apache.shardingsphere.shardingjdbc.api.ShardingDataSourceFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import com.alibaba.druid.pool.DruidDataSource; +import com.alibaba.druid.spring.boot3.autoconfigure.DruidDataSourceBuilder; +import com.ruoyi.common.utils.spring.SpringUtils; +import com.ruoyi.framework.config.properties.DruidProperties; + +/** + * sharding 配置信息 + * + * @author ruoyi + */ +@Configuration +@ConditionalOnProperty(prefix = "spring.datasource.druid.sharding", name = "enabled", havingValue = "true") +public class ShardingDataSourceConfig { + + Logger logger = LoggerFactory.getLogger(ShardingDataSourceConfig.class); + + @Bean + @ConfigurationProperties("spring.datasource.druid.sharding.order1") + @ConditionalOnProperty(prefix = "spring.datasource.druid.sharding.order1", name = "enabled", havingValue = "true") + public DataSource order1DataSource(DruidProperties druidProperties) { + DruidDataSource dataSource = DruidDataSourceBuilder.create().build(); + return druidProperties.dataSource(dataSource); + } + + @Bean + @ConfigurationProperties("spring.datasource.druid.sharding.order2") + @ConditionalOnProperty(prefix = "spring.datasource.druid.sharding.order2", name = "enabled", havingValue = "true") + public DataSource order2DataSource(DruidProperties druidProperties) { + DruidDataSource dataSource = DruidDataSourceBuilder.create().build(); + return druidProperties.dataSource(dataSource); + } + + /** + * 设置数据源 + * + * @param targetDataSources 备选数据源集合 + * @param sourceName 数据源名称 + * @param beanName bean名称 + */ + public void setDataSource(Map targetDataSources, String sourceName, String beanName) { + try { + DataSource dataSource = SpringUtils.getBean(beanName); + targetDataSources.put(sourceName, dataSource); + } catch (Exception e) { + logger.error("Failed to register a sharding data source:{}", beanName); + } + } + + @Bean(name = "shardingDataSource") + public DataSource shardingDataSource() throws SQLException { + Map dataSourceMap = new HashMap<>(); + + // 添加数据源 + setDataSource(dataSourceMap, "order1", "order1DataSource"); + setDataSource(dataSourceMap, "order2", "order2DataSource"); + + // 配置分片规则 + ShardingRuleConfiguration shardingRuleConfig = new ShardingRuleConfiguration(); + // 表规则配置 示例: + // 添加order1.sys_order_0,order2.sys_order_0,order1.sys_order_1,order2.sys_order_1 + TableRuleConfiguration orderTableRuleConfig = new TableRuleConfiguration( + "sys_user", "order$->{1..2}.sys_order_$->{0..1}"); + // 配置分库策略 + // 示例: 根据user_id分库,user_id为单数去order1库,偶数去order2库 + orderTableRuleConfig.setDatabaseShardingStrategyConfig( + new InlineShardingStrategyConfiguration("user_id", "order$->{user_id % 2 + 1}")); + // 配置分表策略 + // 示例: 根据order_id分表,order_id为偶数分到sys_order_0表,奇数分到sys_order_1表 + orderTableRuleConfig.setTableShardingStrategyConfig( + new InlineShardingStrategyConfiguration("order_id", "sys_order_$->{order_id % 2}")); + // 分布式主键 + orderTableRuleConfig.setKeyGeneratorConfig(new KeyGeneratorConfiguration("SNOWFLAKE", "order_id")); + shardingRuleConfig.getTableRuleConfigs().add(orderTableRuleConfig); + + // 获取数据源对象 + DataSource dataSource = ShardingDataSourceFactory.createDataSource(dataSourceMap, shardingRuleConfig, + getProperties()); + return dataSource; + } + + /** + * 系统参数配置 + */ + private Properties getProperties() { + Properties shardingProperties = new Properties(); + shardingProperties.put("sql.show", true); + return shardingProperties; + } +} \ No newline at end of file