提交sharding集成使用实例

pull/136/head
瞿佐鹏 2024-08-28 11:33:37 +08:00
parent 51a37f885b
commit 92afe23a42
7 changed files with 212 additions and 3 deletions

View File

@ -17,12 +17,12 @@
<module>yudao-module-member</module>
<module>yudao-module-bpm</module>
<module>yudao-module-pay</module>
<module>yudao-module-report</module>
<!-- <module>yudao-module-report</module>-->
<module>yudao-module-mp</module>
<module>yudao-module-mall</module>
<module>yudao-module-crm</module>
<module>yudao-module-erp</module>
<module>yudao-module-ai</module>
<!-- <module>yudao-module-ai</module>-->
</modules>
<name>${project.artifactId}</name>

View File

@ -152,6 +152,13 @@
<artifactId>hutool-extra</artifactId> <!-- 邮件 -->
</dependency>
<!-- 分表 -->
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId>
<version>5.2.1</version>
</dependency>
</dependencies>
<build>

View File

@ -6,9 +6,11 @@ import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogPageReqDTO;
import cn.iocoder.yudao.module.system.controller.admin.logger.vo.operatelog.OperateLogPageReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.logger.OperateLogDO;
import com.baomidou.dynamic.datasource.annotation.DS;
import org.apache.ibatis.annotations.Mapper;
@Mapper
@DS("sharding")
public interface OperateLogMapper extends BaseMapperX<OperateLogDO> {
default PageResult<OperateLogDO> selectPage(OperateLogPageReqVO pageReqDTO) {

View File

@ -0,0 +1,90 @@
package cn.iocoder.yudao.module.system.framework.sharding;
import cn.hutool.core.date.DateUtil;
import cn.iocoder.yudao.framework.common.exception.ServiceException;
import com.google.common.collect.Range;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.apache.shardingsphere.sharding.api.sharding.standard.PreciseShardingValue;
import org.apache.shardingsphere.sharding.api.sharding.standard.RangeShardingValue;
import org.apache.shardingsphere.sharding.api.sharding.standard.StandardShardingAlgorithm;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Properties;
/**
* @Description
* ,,selectPagempcount,
*
* @Date 2024/6/13 10:07
* @Author tom
**/
@Getter
@Slf4j
public class DataPreciseShardingAlgorithm implements StandardShardingAlgorithm<LocalDateTime> {
@Override
public Collection<String> doSharding(Collection<String> collection, RangeShardingValue<LocalDateTime> rangeShardingValue) {
Range<LocalDateTime> valueRange = rangeShardingValue.getValueRange();
LocalDateTime lowerEndpoint = valueRange.lowerEndpoint();
LocalDateTime upperEndpoint = valueRange.upperEndpoint();
// 逻辑表名
String logicTableName = rangeShardingValue.getLogicTableName();
List<String> tables = new ArrayList<>();
LocalDateTime now = LocalDateTime.now();
if (upperEndpoint.getYear() > now.getYear() || upperEndpoint.getMonthValue() > now.getMonthValue()) {
log.warn("时间区间异常 不能查询未来数据 {} {}",lowerEndpoint,upperEndpoint);
throw new ServiceException(40001,"不能查询未来数据");
}
while (lowerEndpoint.compareTo(upperEndpoint) <= 0) {
// 添加到集合
tables.add(buildTable(logicTableName, lowerEndpoint));
// 往后加一个月
lowerEndpoint = lowerEndpoint.plusMonths(1).withDayOfMonth(1);
}
return tables;
}
private String buildTable(String logicTableName, LocalDateTime startTime) {
String timeStr = DateUtil.formatLocalDateTime(startTime);
String year = timeStr.substring(2, 4);
String month = timeStr.substring(5, 7);
return logicTableName + "_" + year + month;
}
@Override
public String doSharding(Collection<String> collection, PreciseShardingValue<LocalDateTime> preciseShardingValue) {
String timeStr = DateUtil.formatLocalDateTime(preciseShardingValue.getValue());
String year = timeStr.substring(2, 4);
String month = timeStr.substring(5, 7);
String tableSuffix = year + month;
for (String s : collection) {
if (s.contains(tableSuffix)){
return s;
}
}
return null;
}
@Override
public Properties getProps() {
return null;
}
@Override
public void init(Properties properties) {
}
@Override
public String getType() {
return "HIS_DATA_SPI_BASED";
}
}

View File

@ -0,0 +1,73 @@
package cn.iocoder.yudao.module.system.framework.sharding;
import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
import com.baomidou.dynamic.datasource.creator.DefaultDataSourceCreator;
import com.baomidou.dynamic.datasource.provider.AbstractDataSourceProvider;
import com.baomidou.dynamic.datasource.provider.DynamicDataSourceProvider;
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceProperties;
import jakarta.annotation.Resource;
import org.apache.shardingsphere.driver.jdbc.core.datasource.ShardingSphereDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Configuration
public class MyDataSourceConfiguration {
@Resource
private DynamicDataSourceProperties properties;
/**
* : shardingDataSource
* : masterSlaveDataSource
*
*/
// @Lazy
// @Resource
// private MasterSlaveDataSource masterSlaveDataSource;
// @Lazy
@Resource
private ShardingSphereDataSource shardingSphereDataSource;
@Bean
public DynamicDataSourceProvider dynamicDataSourceProvider(DefaultDataSourceCreator dataSourceCreator) {
return new AbstractDataSourceProvider(dataSourceCreator) {
@Override
public Map<String, DataSource> loadDataSources() {
Map<String, DataSource> dataSourceMap = new HashMap<>();
dataSourceMap.put("sharding", shardingSphereDataSource);
//下面的代码可以把 shardingJdbc 内部管理的子数据源也同时添加到动态数据源里 (根据自己需要选择开启+注解了@Lazy被代理了不可以)
// Map<String, DataSource> shardingInnerDataSources = shardingSphereDataSource();
// dataSourceMap.putAll(shardingInnerDataSources);
return dataSourceMap;
}
};
}
/**
*
* spring,
* shardingjdbc
* 3.4.0使, -
*/
@Primary
@Bean
public DataSource dataSource(List<DynamicDataSourceProvider> providers) {
DynamicRoutingDataSource dataSource = new DynamicRoutingDataSource(providers);
dataSource.setPrimary(properties.getPrimary());
dataSource.setStrict(properties.getStrict());
dataSource.setStrategy(properties.getStrategy());
dataSource.setSeata(properties.getSeata());
dataSource.setP6spy(properties.getP6spy());
dataSource.setSeata(properties.getSeata());
return dataSource;
}
}

View File

@ -0,0 +1 @@
cn.iocoder.yudao.module.system.framework.sharding.DataPreciseShardingAlgorithm

View File

@ -73,7 +73,43 @@ spring:
url: jdbc:mysql://127.0.0.1:3306/ruoyi-vue-pro?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true
username: root
password: 123456
## sharding 配置
shardingsphere:
props:
sql:
show: true
sql-show: true
datasource:
names: db-0
db-0:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: 123456
url: jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&zeroDateTimeBehavior=convertToNull&serverTimezone=GMT%2b8&rewriteBatchedStatements=true
rules:
sharding:
tables:
system_operate_log:
key-generator:
column: id
type: SNOWFLAKE
#分片策略
actual-data-nodes: db-0.system_operate_log_${24..50}0${1..9},db-0.system_operate_log_${24..50}1${0..2}
table-strategy: #表分片策略
standard:
sharding-column: create_time
sharding-algorithm-name: his_month_sharding
# 配置分片算法
sharding-algorithms:
# person_sync_record_inline:
# type: INLINE
# props:
# algorithm-expression: person_sync_record_$->{id % 16}
# 分片算法名称
his_month_sharding:
# 分片算法类型这个type是我们的分片算法实现类中 getType()的返回值SPI适用于这种方式
type: HIS_DATA_SPI_BASED
# Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优
data:
redis: