SpringCloud配置nacos,alibaba.druid分库处理方式

 更新时间:2026年11月04日 15:08:28   作者:dingcho  
还在为数据库分表发愁?本文详细讲解如何根据分组策略进行分表处理,涵盖分表核心步骤、方案设计和常见问题,掌握分组分表技巧,轻松应对大数据量挑战,提升系统性能

SpringCloud配置nacos,alibaba.druid分库

spring:
  autoconfigure:
    # 添加 排除 DruidDataSourceAutoConfigure
    exclude: com.alibaba.druid.spring.boot3.autoconfigure.DruidDataSourceAutoConfigure
  datasource:
    driver-class-name: org.apache.shardingsphere.driver.ShardingSphereDriver
    url: jdbc:shardingsphere:classpath:sharding.yaml
dataSources:
  ds_0:
    dataSourceClassName: com.alibaba.druid.pool.DruidDataSource
    driverClassName: com.mysql.cj.jdbc.Driver
    username: yourusername
    password: yourpassword
    url: jdbc:mysql://king-mysql:3306/yourdb?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowMultiQueries=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true&allowPublicKeyRetrieval=true
rules:
  - !SINGLE
    tables:
      - "*.*"
  - !SHARDING
    tables:
      stock_history_day:
        actualDataNodes: ds_0.data_history_day_10$->{1..12}
        tableStrategy:
          standard:
            shardingAlgorithmName: table-inline
            shardingColumn: method
    shardingAlgorithms:
      table-inline:
        props:
          algorithm-expression: data_history_day_$->{group_name}
        type: INLINE
props:
  sql-show: true
private final int MAX_GROUP_NUMBER = 15;
private final ExecutorService executorService = Executors.newFixedThreadPool(MAX_THREAD_POOL_NUMBER);



// 获取所有代码
List<String> codeList = stockList.stream().map(Stock::getCode).collect(Collectors.toList());
// 将代码分组
List<List<String>> stockGroupList = ListsUtils.fixedGrouping(codeList, MAX_GROUP_NUMBER * 2);
CountDownLatch countDownLatch = new CountDownLatch(stockGroupList.size());


stockGroupList.forEach(list -> {
    executorService.submit(() -> {
        list.forEach(code -> {
            // todo     
            EntityObj obj = new EntityObj();
            
            this.saveDb(obj);               
        });
        countDownLatch.countDown();
    });
    try {
        // 等待,避免读取过快导致数据方屏蔽
        Thread.sleep(1500);
    } catch (Exception e) {
    }
});
executorService.shutdown();
countDownLatch.await();

package com.kingbal.king.dmp.utils;

import com.google.common.collect.Maps;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.ObjectUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <b>Function: </b> todo
 *
 * @program: ListUtils
 * @Package: com.kingbal.king.dmp.utils
 * @author: dingcho
 * @date: 2023/05/05
 * @version: 1.0
 * @Copyright: 2023 www.kingbal.com Inc. All rights reserved.
 */
public class ListsUtils {

	/**
	 * 将一组数据平均分成n组
	 *
	 * @param source 要分组的数据源
	 * @param n      平均分成n组
	 * @param <T>
	 * @return
	 */
	public static <T> List<List<T>> averageAssign(List<T> source, int n) {
		List<List<T>> result = new ArrayList<>();
		int remainder = source.size() % n;  //(先计算出余数)
		int number = source.size() / n;  //然后是商
		int offset = 0;//偏移量
		for (int i = 0; i < n; i++) {
			List<T> value = null;
			if (remainder > 0) {
				value = source.subList(i * number + offset, (i + 1) * number + offset + 1);
				remainder--;
				offset++;
			} else {
				value = source.subList(i * number + offset, (i + 1) * number + offset);
			}
			result.add(value);
		}
		return result;
	}

	/**
	 * 将一组数据固定分组,每组n个元素
	 *
	 * @param source 要分组的数据源
	 * @param n      每组n个元素
	 * @param <T>
	 * @return
	 */
	public static <T> List<List<T>> fixedGrouping(List<T> source, int n) {
		if (null == source || source.size() == 0 || n <= 0)
			return null;
		List<List<T>> result = new ArrayList<>();
		int sourceSize = source.size();
		int size = (source.size() / n) + 1;
		for (int i = 0; i < size; i++) {
			List<T> subset = new ArrayList<T>();
			for (int j = i * n; j < (i + 1) * n; j++) {
				if (j < sourceSize) {
					subset.add(source.get(j));
				}
			}
			result.add(subset);
		}
		return result;
	}

	/**
	 * 将一组数据固定分组,每组n个元素
	 *
	 * @param source 要分组的数据源
	 * @param n      每组n个元素
	 * @param <T>
	 * @return
	 */
	public static <T> List<List<T>> fixedGrouping2(List<T> source, int n) {
		if (null == source || source.size() == 0 || n <= 0)
			return null;
		List<List<T>> result = new ArrayList<>();
		int remainder = source.size() % n;
		int size = (source.size() / n);
		for (int i = 0; i < size; i++) {
			List<T> subset = source.subList(i * n, (i + 1) * n);
			result.add(subset);
		}
		if (remainder > 0) {
			List<T> subset = source.subList(size * n, size * n + remainder);
			result.add(subset);
		}
		return result;
	}

	/**
	 * 指定数字转换为集合
	 *
	 * @param number
	 * @return
	 */
	public static List<Integer> fixedList(int number) {
		List<Integer> list = Lists.newArrayList();
		for (int i = 1; i <= number; i++) {
			list.add(i);
		}
		return list;
	}

	/**
	 * 指定数字转换为集合
	 * @param minInt
	 * @param maxInt
	 * @return
	 */
	public static List<Integer> fixedMinMaxList(int minInt, int maxInt) {
		List<Integer> list = Lists.newArrayList();
		for (int i = minInt; i <= maxInt; i++) {
			list.add(i);
		}
		return list;
	}

	/**
	 * 二维集合
	 *
	 * @param number
	 * @param number2
	 * @return
	 */
	public static List<String> fixedList(int number, int number2) {
		List<String> list = Lists.newArrayList();
		for (int i = 1; i <= number; i++) {
			for (int k = 1; k <= number2; k++) {
				list.add(i + "-" + k);
			}
		}
		return list;
	}

	/**
	 * 获取时间分组
	 *
	 * @return
	 */
	public static Map<Integer, Integer> getTimesGroup() {
		Map<Integer, Integer> map = Maps.newHashMap();
		int table = 10;
		int year = 1990;
		for (int i = 1; i <= table; i++) {
			if (i > 1 && i <= 8) {
				for (int k = 0; k < 3; k++) {
					map.put(year++, 100 + i);
				}
			} else if (i > 8) {
				for (int k = 0; k < 2; k++) {
					if (i > 9) {
						map.put(year++, 1000 + i);
					} else {
						map.put(year++, 100 + i);
					}
				}
			} else {
				for (int k = 0; k < 10; k++) {
					map.put(year++, 100 + i);
				}
			}
		}
		return map;
	}

	/**
	 * 根据已有数据进行数字分组
	 * @param list
	 * @return
	 */
	public static Map<String, Integer> getNumberGroup(List<Long> list) {
		Map<String, Integer> map = Maps.newHashMap();
		list = list.stream().distinct().collect(Collectors.toList());
		Collections.sort(list);
		List<Long> list2 = Lists.newArrayList();
		List<Long> list3 = Lists.newArrayList();
		for (int i = 0; i < list.size(); i++) {
			StringBuffer key = new StringBuffer();
			if (i % 2 == 0) {
				list2.add(list.get(i));
			} else {
				list3.add(list.get(i));
			}
		}
		if (list.size() % 2 != 0) {
			list3.add(Collections.max(list));
		}
		for (int i = 0; i < list2.size(); i++) {
			map.put(list2.get(i) + "~" + list3.get(i), 0);
		}
		return map;
	}

	/**
	 * 获取多个list最大的size
	 * @param lists
	 * @return
	 */
	public static Integer getMaxSize(List<?>... lists) {
		if (ObjectUtils.isEmpty(lists)) {
			return 0;
		}
		List<Integer> maxSizeList = new ArrayList<>();
		for (List<?> list : lists) {
			maxSizeList.add(ObjectUtils.isEmpty(list) ? 0 : list.size());
		}
		return ObjectUtils.isEmpty(maxSizeList) ? 0 : Collections.max(maxSizeList);
	}

	/**
	 * 填充空值
	 * @param list
	 * @param maxSize
	 * @param <T>
	 * @return
	 */
	public static <T> List<T> fillValue(List<T> list, int maxSize) {
		if(list.size() < maxSize){
			for (int i = 0; i < maxSize-list.size() +1; i++) {
				list.add(null);
			}
		}
		return list;
	}

}

根据分组策略

进行分表处理

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • mybatis plus怎么忽略映射字段

    mybatis plus怎么忽略映射字段

    这篇文章主要介绍了mybatis plus怎么忽略映射字段,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-10-10
  • 使用RabbitMQ实现延时消息自动取消的案例详解

    使用RabbitMQ实现延时消息自动取消的案例详解

    这篇文章主要介绍了使用RabbitMQ实现延时消息自动取消的简单案例,案例代码包括导包的过程和相关配置文件,本文结合代码给大家讲解的非常详细,需要的朋友可以参考下
    2024-03-03
  • SpringBoot里使用Servlet进行请求的实现示例

    SpringBoot里使用Servlet进行请求的实现示例

    这篇文章主要介绍了SpringBoot里使用Servlet进行请求的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-01-01
  • 在SpringBoot中更改默认端口的方法总结

    在SpringBoot中更改默认端口的方法总结

    在本文中,小编将带大家学习如何在 Spring Boot 中更改默认端口,默认情况下,嵌入式 Web 服务器使用 8080端口来启动 Spring 引导应用程序,有几种方法可以更改该端口,文中介绍的非常详细,需要的朋友可以参考下
    2023-07-07
  • MyBatis批量添加数据2种实现方法

    MyBatis批量添加数据2种实现方法

    这篇文章主要介绍了MyBatis批量添加数据2种实现方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-06-06
  • 教你怎么用Springboot自定义Banner图案

    教你怎么用Springboot自定义Banner图案

    今天给大家带来的是Java的相关知识,文章围绕着怎么用Springboot自定义Banner图案展开,文中有非常详细的介绍及代码示例,需要的朋友可以参考下
    2021-06-06
  • IDEA Ultimate2020.2版本配置Tomcat详细教程

    IDEA Ultimate2020.2版本配置Tomcat详细教程

    这篇文章主要介绍了IDEA Ultimate2020.2版本配置Tomcat教程,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-09-09
  • MyBatis的SQL执行结果和客户端执行结果不一致问题排查

    MyBatis的SQL执行结果和客户端执行结果不一致问题排查

    本文主要介绍了MyBatis的SQL执行结果和客户端执行结果不一致问题排查,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-04-04
  • 简单说说JVM堆区的相关知识

    简单说说JVM堆区的相关知识

    今天给大家带来的是关于Java虚拟机的相关知识,文章围绕着JVM堆区展开,文中有非常详细的介绍及代码示例,需要的朋友可以参考下
    2021-06-06
  • Java语法基础之选择结构的if语句、switch语句详解

    Java语法基础之选择结构的if语句、switch语句详解

    这篇文章主要为大详细介绍了Java语法基础之选择结构的if语句、switch语句,感兴趣的小伙伴们可以参考一下
    2016-09-09

最新评论