C# Random 随机数 全面解析

总目录


前言


一、Random 是什么?

1. 简介

表示伪随机数生成器,这是一种能够产生满足某些随机性统计要求的数字序列的算法。

csharp 复制代码
public class Random

继承:Object → Random

2. 构造函数

3. 属性

4. 方法

二、Random 的使用

1. Next() 或 NextInt64()

Next 返回一个非负随机整数。

csharp 复制代码
        static void Main(string[] args)
        {
            var random=new Random();
            for (int i = 0; i < 5; i++) 
            {
                var num = random.Next();
                Console.WriteLine($"{num}");
            }
            Console.ReadKey();
        }

输出结果:

csharp 复制代码
76862089
1371118149
1965820566
1160787942
1644846096

2. Next(Int32) 或 NextInt64(Int64)

  • 返回一个小于所指定最大值的非负随机整数。
csharp 复制代码
        static void Main(string[] args)
        {
            var random=new Random();
            for (int i = 0; i < 5; i++) 
            {
                var num = random.Next(15);
                Console.WriteLine($"{num}");
            }
            Console.ReadKey();
        }

运行结果:

csharp 复制代码
2
9
2
13
11

3. Next(Int32, Int32) 或 NextInt64(Int64, Int64)

  • 返回在指定范围内的任意整数。
  • 注意 :生成的随机数 包括minValue ,但是不包括maxValue
csharp 复制代码
        static void Main(string[] args)
        {
            var random=new Random();
            for (int i = 0; i < 5; i++) 
            {
                var num = random.Next(15,200);
                Console.WriteLine($"{num}");
            }
            Console.ReadKey();
        }

运行结果:

csharp 复制代码
46
78
170
83
58

4. NextSingle() 和 NextDouble() 、Sample()

  • 返回一个大于或等于 0.0 且小于 1.0 的随机浮点数。
  • NextSingle() 支持 .NET 6/7/8/9
csharp 复制代码
        static void Main(string[] args)
        {
            var random=new Random();
            for (int i = 0; i < 5; i++) 
            {
                var num = random.NextDouble();
                Console.WriteLine($"{num}");
            }
            Console.ReadKey();
        }

运行结果:

csharp 复制代码
0.241523597036267
0.0462926887191332
0.585451771312138
0.628924066493718
0.972035988686623

5. NextBytes(Byte[])

  • 用随机数填充指定字节数组的元素。
csharp 复制代码
        static void Main(string[] args)
        {
            var random=new Random();
            byte[] bytes = new byte[10];
            random.NextBytes(bytes);

            foreach (var item in bytes)
            {
                Console.WriteLine(item);
            }
            Console.ReadKey();
        }

运行结果:

csharp 复制代码
82
94
151
251
134
195
217
150
157
129

6. Shuffle<T>(Span<T>)

  • 执行跨度的就地洗牌。

7. Shuffle<T>(T[])

  • 执行数组的就地洗牌。。

三、Random为啥是伪随机数

1. 伪随机数的原因

random是伪随机,同一秒创建的随机对象,所生成的随机队列是一样的,除非不是同一时间产生

csharp 复制代码
        static void Main(string[] args)
        {
            Random random = new Random();
            Random random2 = new Random();
        Place:
            int num = random.Next(0, 11);
            int num2 = random2.Next(0, 11);
            Console.WriteLine($"num={num},num2={num2}");

            Thread.Sleep(1000);
            goto Place;
        }

运行结果:

csharp 复制代码
num=7,num2=7
num=7,num2=7
num=1,num2=1
num=8,num2=8
num=2,num2=2
num=7,num2=7
num=0,num2=0

由以上案例可知,在时间间隔极其接近的时候,生成的随机数是一样的。

2. 生成相对随机的随机数

1. 使用种子值

这里通过上面的案例我们发现:通过使用不同的种子值 初始化 Random 类是可以生成 不是完全一样的两个随机序列。那么现在问题就变成了,如何生成唯一的种子值。

  • 方法1
csharp 复制代码
public static int GenerateRandomSeed()
{
	return unchecked((int)DateTime.Now.Ticks);
}
  • 方法2
csharp 复制代码
using System.Text.RegularExpressions;

public static int GenerateRandomSeed()
{
    return Convert.ToInt32(Regex.Match(Guid.NewGuid().ToString(), @"\d+").Value);
}
  • 方法3(推荐)
csharp 复制代码
public static int GenerateRandomSeed()
{
	return Guid.NewGuid().GetHashCode();
}
  • 方法4
csharp 复制代码
using System.Security.Cryptography;

public static int GenerateRandomSeed()
{
    byte[] bytes = new byte[4];
    RNGCryptoServiceProvider rngCSP = new RNGCryptoServiceProvider();
    rngCSP.GetBytes(bytes);
    return BitConverter.ToInt32(bytes, 0);
}

调用和运行结果(随便选择一种种子值的生成方法):

2. 使用Thread.Sleep(1)

在两个Random 实例化中间增加一个时间为1 毫秒的 延迟即可。

四、Random 扩展与应用

1. 生成随机的字符

在某些情况下,随机数只能取一些特殊指定的值,如不连续的数字或指定的一些单词等,此时仅用 Random 无法达到要求,必须借助数组才能实现。

实现思路大概是这样:先把这些特殊的值存到数组中,然后把数组的长度作为 Random 的上限产生随机数,此随机数正是数组的下标,根据该下标取得数组的值。

  • 封装成扩展方法来使用
csharp 复制代码
    public static class RandomExtension
    {
        public static string NextString(this Random random, string[] arr)
        {
            var index = random.Next(arr.Length);
            return arr[index];
        }
    }

调用:

csharp 复制代码
        static void Main(string[] args)
        {
            Random random = new Random();
            for (int i = 0; i < 5; i++)
            {
                var str = random.NextString(new string[] { "张三", "李四", "王五","赵六" });
                //var str = random.NextString(new string[] { "黑", "黄", "绿","红" });
                Console.WriteLine($"{str}");
            }
            Console.ReadKey();
        }

运行结果:

csharp 复制代码
张三
王五
王五
张三
张三

2. 生成随机的布尔值

  • 封装成扩展方法来使用
csharp 复制代码
    public static class RandomExtension
    {
        public static bool NextBool(this Random random)
        {
            bool[] boolArr = new bool[] { true, false };
            var index = random.Next(boolArr.Length);
            return boolArr[index];
        }
    }

调用:

csharp 复制代码
        static void Main(string[] args)
        {
            Random random = new Random();
            for (int i = 0; i < 1115; i++)
            {
                var str = random.NextBool();
                Console.WriteLine($"{str}");
            }
            Console.ReadKey();
        }

3. 生成指定范围内浮点随机数

  • 生成指定范围内浮点随机数
csharp 复制代码
double randomDouble = random.NextDouble() * 100; // 生成0到100之间的随机浮点数
Console.WriteLine(randomDouble);

// 生成特定范围内的随机浮点数
double rangeRandomDouble = random.NextDouble() * (maxValue - minValue) + minValue;
Console.WriteLine(rangeRandomDouble); // 假设maxValue和minValue是之前定义的变量
csharp 复制代码
        static void Main(string[] args)
        {
            var random=new Random();
            int min = 100;
            int max = 285;
            for (int i = 0; i < 5; i++)
            {
                var num = random.NextDouble() * (max - min) + min;
                Console.WriteLine($"{num}");
            }
            Console.ReadKey();
        }

运行结果:

clike 复制代码
126.074954253191
203.064250968427
209.030935270261
208.824055366602
180.678236866686

封装成扩展方法:

csharp 复制代码
    public static class RandomExtension
    {
        public static double NextDouble(this Random random,double min, double max)
        {
            return (random.NextDouble() * (max - min) + min);
        }
    }
  • 生成保留指定小数位数(例如 2 位)的随机数
csharp 复制代码
    public static class RandomExtension
    {
        public static double NextDouble(this Random random, double min, double max,int decimalPlace)
        {
            double randomNum = (random.NextDouble() * (max - min) + min);
            return Convert.ToDouble(randomNum.ToString($"F{decimalPlace}"));
        }
    }

4. 生成一个随机字符串(支持英文大小写字母/数字混合)

csharp 复制代码
    public static class RandomExtension2
    {
        /// <summary>
        /// 生成随机字符串
        /// </summary>
        /// <param name="random">Random 实例</param>
        /// <param name="digits">字符串的长度</param>
        /// <param name="number">是否包括数字</param>
        /// <param name="lowercase">是否包含小写字母</param>
        /// <param name="capital">是否包含大写字母</param>
        /// <param name="special">是否包含特殊字符</param>
        /// <returns></returns>
        public static string GetRandomCharacters(this Random random, int digits = 10, bool number = true, bool lowercase = true, bool capital = true, bool special = false)
        {
            string CapitalLetters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
            string LowercaseLetters = "abcdefghijklmnopqrstuvwxyz";
            string Numbers = "0123456789";
            string SpecialCharacters = "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~";

            StringBuilder tmp = new StringBuilder();
            string characters = (capital ? CapitalLetters : null) + (number ? Numbers : null) + (lowercase ? LowercaseLetters : null) + (special ? SpecialCharacters : null);
            if (characters.Length < 1) return null;
            for (int i = 0; i < digits; i++)
            {
                tmp.Append(characters[random.Next(characters.Length)].ToString());
            }
            return (tmp.ToString());
        }
    }

csharp 复制代码
        /// <summary>
        /// 生成一个随机字符串。
        /// </summary>
        /// <param name="length">生成的字符串长度。</param>
        /// <param name="useUppercase">是否包含大写字母。</param>
        /// <param name="useLowercase">是否包含小写字母。</param>
        /// <param name="useDigits">是否包含数字。</param>
        /// <param name="useSpecialChars">是否包含特殊字符。</param>
        /// <returns>生成的随机字符串。</returns>
        public static string GenerateRandomString(this Random random, int length = 10, bool useUppercase = true, bool useLowercase = true, bool useDigits = true, bool useSpecialChars = false)
        {
            if (length <= 0)
                throw new ArgumentException("长度必须大于零。", nameof(length));

            // 定义字符集合
            var charPool = new StringBuilder();
            if (useUppercase) charPool.Append("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
            if (useLowercase) charPool.Append("abcdefghijklmnopqrstuvwxyz");
            if (useDigits) charPool.Append("0123456789");
            if (useSpecialChars) charPool.Append("!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~");

            if (charPool.Length == 0)
                throw new ArgumentException("至少需要选择一种字符类型。");

            // 生成随机字符串
            var chars = new char[length];
            for (int i = 0; i < length; i++)
            {
                int index = random.Next(0, charPool.Length);
                chars[i] = charPool[index];
            }

            return new string(chars);
        }

调用:

csharp 复制代码
        static void Main(string[] args)
        {
            Random random = new Random();
            for (int i = 0; i < 5; i++)
            {
                var str = random.GenerateRandomString(useSpecialChars:true);
                Console.WriteLine($"{str}");
            }
            Console.ReadKey();
        }

运行结果:

csharp 复制代码
Bz4./WFDM,
mNl0]`p3sL
K&|Vgh"HXV
njXyt3,uit
Ii!fQKm/-;

可以通过方法中的参数配置,生成的字符串的长度以及是否包含大小写字母,特殊字符等,但是并不能保证,一定包含,因此该方法有优化空间。

优化后:

csharp 复制代码
    public static class RandomExtension
    {
        /// <summary>
        /// 生成一个随机字符串。
        /// </summary>
        /// <param name="random">Random 实例</param>
        /// <param name="length">生成的字符串长度。</param>
        /// <param name="useUppercase">是否包含大写字母。</param>
        /// <param name="useLowercase">是否包含小写字母。</param>
        /// <param name="useDigits">是否包含数字。</param>
        /// <param name="useSpecialChars">是否包含特殊字符。</param>
        /// <returns>生成的随机字符串。</returns>
        public static string GenerateRandomString(this Random random, int length = 10, bool useUppercase = true, bool useLowercase = true, bool useDigits = true, bool useSpecialChars = false)
        {
            string CapitalLetters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
            string LowercaseLetters = "abcdefghijklmnopqrstuvwxyz";
            string Numbers = "0123456789";
            string SpecialCharacters = "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~";

            if (length <= 0)
                throw new ArgumentException("长度必须大于零。", nameof(length));

            // 定义字符集合
            var charPool = new StringBuilder();
            var requiredChars = new StringBuilder();

            if (useUppercase)
            {
                charPool.Append(CapitalLetters);
                // 确保至少有一个大写字母,固定值A
                //requiredChars.Append('A'); 
                // 确保至少有一个大写字母,随机值
                requiredChars.Append(CapitalLetters[random.Next(CapitalLetters.Length)]);
            }
            if (useLowercase)
            {
                charPool.Append(LowercaseLetters);
                // 确保至少有一个小写字母,固定值a
                //requiredChars.Append('a'); 
                // 确保至少有一个小写字母,随机值
                requiredChars.Append(LowercaseLetters[random.Next(LowercaseLetters.Length)]);
            }
            if (useDigits)
            {
                charPool.Append(Numbers);
                // 确保至少有一个数字,固定值1
                //requiredChars.Append('1'); 
                // 确保至少有一个数字,随机值
                requiredChars.Append(Numbers[random.Next(Numbers.Length)]);
            }
            if (useSpecialChars)
            {
                charPool.Append(SpecialCharacters);
                // 确保至少有一个特殊字符,固定值!
                //requiredChars.Append('!'); 
                // 确保至少有一个特殊字符,随机值
                requiredChars.Append(SpecialCharacters[random.Next(SpecialCharacters.Length)]);
            }

            if (charPool.Length == 0)
                throw new ArgumentException("至少需要选择一种字符类型。");

            if (requiredChars.Length > length)
                throw new ArgumentException("所需的字符类型数量超过了指定的字符串长度。");

            // 构建确保包含所有必要字符的初始部分
            var result = new StringBuilder();
            foreach (char c in requiredChars.ToString())
            {
                int index = charPool.ToString().IndexOf(c);
                if (index != -1)
                {
                    result.Append(charPool[index]);
                    charPool = charPool.Remove(index, 1); // 移除已使用的字符以避免重复
                }
            }

            // 填充剩余的字符
            for (int i = requiredChars.Length; i < length; i++)
            {
                int index = random.Next(0, charPool.Length);
                result.Append(charPool[index]);
            }

            // 将结果打乱顺序,确保随机性
            var shuffledResult = random.Shuffle(result.ToString());
            return shuffledResult;
        }

        /// <summary>
        /// 打乱字符串中的字符顺序。
        /// </summary>
        /// <param name="random">Random 实例</param>
        /// <param name="input">要打乱的字符串。</param>
        /// <returns>打乱后的字符串。</returns>
        public static string Shuffle(this Random random, string input)
        {
            char[] array = input.ToCharArray();
            for (int i = array.Length - 1; i > 0; i--)
            {
                int j = random.Next(i + 1);
                char temp = array[i];
                array[i] = array[j];
                array[j] = temp;
            }
            return new string(array);
        }
    }

扩展方法:打乱字符串中的字符顺序,也比较实用哦!

调用:

csharp 复制代码
        static void Main(string[] args)
        {
            Random random = new Random();
            for (int i = 0; i < 115; i++)
            {
                var str = random.GenerateRandomString(useSpecialChars:true);
                Console.WriteLine($"{str}");
            }
            Console.ReadKey();
        }

运行结果:

csharp 复制代码
sB9:JtsF-8
M<(:gcW\a3
u>QL&9q3DI
h;#Vmz}aP3
wXbu2L&1B}
2R)[ouG?*q
U)$`28mX3<
LW)}U/t6z`
^P1Q7tl"KZ
4p,@=Y|EV\
=Z%;3mNB\X
]BxY3S.F$r
$-'B~8E;sb
0$V~%N<w;L
eqngCI0Pv.

5. 生成不重复的随机数

1. 基础用法

csharp 复制代码
    public static class RandomExt
    {
        public static int NextUnique(this Random random,Hashtable hashtable,int maxValue)
        {
            if (hashtable == null) throw new ArgumentException("hashtable 不可为空。");
            int num = random.Next(maxValue);
            //不重复,则添加进Hashtable 并返回
            if (!hashtable.ContainsValue(num))
            {
                hashtable.Add(num,num);
                return num;
            }
            //重复,则继续调用自身生成不重复的随机数
            return NextUnique(random,hashtable,maxValue);
        }
    }

调用:

csharp 复制代码
        static void Main(string[] args)
        {
            Hashtable hashtable = new Hashtable();
            Random random = new Random();
            for (int i = 0; hashtable.Count < 20; i++)
            {
                int num = random.NextUnique(hashtable,20);
                Console.WriteLine($"{num}");
            }
        }

2. 进阶用法

基于第四小节的方法,新增一个GenerateRandomStringUnique 方法负责保存和检查唯一性。

csharp 复制代码
    public static class RandomExtension
    {
        /// <summary>
        /// 生成一个随机字符串。
        /// </summary>
        /// <param name="random">Random 实例</param>
        /// <param name="length">生成的字符串长度。</param>
        /// <param name="useUppercase">是否包含大写字母。</param>
        /// <param name="useLowercase">是否包含小写字母。</param>
        /// <param name="useDigits">是否包含数字。</param>
        /// <param name="useSpecialChars">是否包含特殊字符。</param>
        /// <returns>生成的随机字符串。</returns>
        /// <summary>
        /// 生成一个随机字符串。
        /// </summary>
        /// <param name="random">Random 实例</param>
        /// <param name="length">生成的字符串长度。</param>
        /// <param name="useUppercase">是否包含大写字母。</param>
        /// <param name="useLowercase">是否包含小写字母。</param>
        /// <param name="useDigits">是否包含数字。</param>
        /// <param name="useSpecialChars">是否包含特殊字符。</param>
        /// <returns>生成的随机字符串。</returns>
        public static string GenerateRandomString(this Random random, int length = 10, bool useUppercase = true, bool useLowercase = true, bool useDigits = true, bool useSpecialChars = false)
        {
            string CapitalLetters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
            string LowercaseLetters = "abcdefghijklmnopqrstuvwxyz";
            string Numbers = "0123456789";
            string SpecialCharacters = "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~";

            if (length <= 0)
                throw new ArgumentException("长度必须大于零。", nameof(length));

            // 定义字符集合
            var charPool = new StringBuilder();
            var requiredChars = new StringBuilder();

            if (useUppercase)
            {
                charPool.Append(CapitalLetters);
                // 确保至少有一个大写字母,固定值A
                //requiredChars.Append('A'); 
                // 确保至少有一个大写字母,随机值
                requiredChars.Append(CapitalLetters[random.Next(CapitalLetters.Length)]);
            }
            if (useLowercase)
            {
                charPool.Append(LowercaseLetters);
                // 确保至少有一个小写字母,固定值a
                //requiredChars.Append('a'); 
                // 确保至少有一个小写字母,随机值
                requiredChars.Append(LowercaseLetters[random.Next(LowercaseLetters.Length)]);
            }
            if (useDigits)
            {
                charPool.Append(Numbers);
                // 确保至少有一个数字,固定值1
                //requiredChars.Append('1'); 
                // 确保至少有一个数字,随机值
                requiredChars.Append(Numbers[random.Next(Numbers.Length)]);
            }
            if (useSpecialChars)
            {
                charPool.Append(SpecialCharacters);
                // 确保至少有一个特殊字符,固定值!
                //requiredChars.Append('!'); 
                // 确保至少有一个特殊字符,随机值
                requiredChars.Append(SpecialCharacters[random.Next(SpecialCharacters.Length)]);
            }

            if (charPool.Length == 0)
                throw new ArgumentException("至少需要选择一种字符类型。");

            if (requiredChars.Length > length)
                throw new ArgumentException("所需的字符类型数量超过了指定的字符串长度。");

            // 构建确保包含所有必要字符的初始部分
            var result = new StringBuilder();
            foreach (char c in requiredChars.ToString())
            {
                int index = charPool.ToString().IndexOf(c);
                if (index != -1)
                {
                    result.Append(charPool[index]);
                    charPool = charPool.Remove(index, 1); // 移除已使用的字符以避免重复
                }
            }

            // 填充剩余的字符
            for (int i = requiredChars.Length; i < length; i++)
            {
                int index = random.Next(0, charPool.Length);
                result.Append(charPool[index]);
            }

            // 将结果打乱顺序,确保随机性
            var shuffledResult = random.Shuffle(result.ToString());
            return shuffledResult;
        }
        /// <summary>
        /// 打乱字符串中的字符顺序。
        /// </summary>
        /// <param name="random">Random 实例</param>
        /// <param name="input">要打乱的字符串。</param>
        /// <returns>打乱后的字符串。</returns>
        public static string Shuffle(this Random random, string input)
        {
            char[] array = input.ToCharArray();
            for (int i = array.Length - 1; i > 0; i--)
            {
                int j = random.Next(i + 1);
                char temp = array[i];
                array[i] = array[j];
                array[j] = temp;
            }
            return new string(array);
        }

        public static string GenerateRandomStringUnique(this Random random, Hashtable hashtable, int length = 10, bool useUppercase = true, bool useLowercase = true, bool useDigits = true, bool useSpecialChars = false)
        {
            if (hashtable == null) throw new ArgumentException("hashtable 不可为空。");
            string str = random.GenerateRandomString(length, useUppercase, useLowercase, useDigits, useSpecialChars);
            if (!hashtable.ContainsValue(str))
            {
                hashtable.Add(str, str);
                return str;
            }
            return GenerateRandomStringUnique(random, hashtable, length, useUppercase, useLowercase, useDigits, useSpecialChars);
        }
    }

调用

csharp 复制代码
        static void Main(string[] args)
        {
            Hashtable hashtable = new Hashtable();
            Random random = new Random();
            // 只生成 1 个长度的只包含数字的 随机数的时候,只可能生成9个值,超过会报错
            // 只生成 2 个长度的只包含数字的 随机数的时候,只可能生成10~99之间的值,总共89个值,超过会报错
            for (int i = 0; hashtable.Count < 89; i++)
            {
                string result = random.GenerateRandomStringUnique(hashtable,2,false,false,true,false);
                Console.WriteLine($"{result}");
            }
        }

正常调用,生成长度10的包含大小写字母,包含数字,不含特殊字符的随机数

csharp 复制代码
        static void Main(string[] args)
        {
            Hashtable hashtable = new Hashtable();
            Random random = new Random();
            for (int i = 0; hashtable.Count < 15; i++)
            {
                string result = random.GenerateRandomStringUnique(hashtable);
                Console.WriteLine($"{result}");
            }
        }

运行结果:

csharp 复制代码
lf41aCkdME
jFyHlT1UAr
Ni4y2JjAiQ
XJWbG2wK9e
Rn7j5bhFTO
hl7IWQ2LGC
016VCkgYzJ
D1KIgJeMQt
9TQJ5U4xTR
VcCVXJU76N
5wKRz1JrXI
RpJEn9MWhz
PiUQK4Xm7C
JfqK5pIadf
08Xy5SrQpp

结语

回到目录页: C# 知识汇总

希望以上内容可以帮助到大家,如文中有不对之处,还请批评指正。


参考资料:
.NET文档 - Random 类
C# Random类详解:生成随机数的实用指南
总结全网C#取随机数方法(整型,浮点型,字符串)
C# Random 随机数
C#产生指定范围随机数(整数、小数、字符、布尔,相对不重复的和唯一的)的几种方法

相关推荐
小池先生4 分钟前
springboot启动不了 因一个spring-boot-starter-web底下的tomcat-embed-core依赖丢失
java·spring boot·后端
CodeClimb7 分钟前
【华为OD-E卷-木板 100分(python、java、c++、js、c)】
java·javascript·c++·python·华为od
odng10 分钟前
IDEA自己常用的几个快捷方式(自己的习惯)
java·ide·intellij-idea
CT随18 分钟前
Redis内存碎片详解
java·开发语言
brrdg_sefg27 分钟前
gitlab代码推送
java
anlog27 分钟前
C#在自定义事件里传递数据
开发语言·c#·自定义事件
hanbarger1 小时前
mybatis框架——缓存,分页
java·spring·mybatis
cdut_suye1 小时前
Linux工具使用指南:从apt管理、gcc编译到makefile构建与gdb调试
java·linux·运维·服务器·c++·人工智能·python
苹果醋31 小时前
2020重新出发,MySql基础,MySql表数据操作
java·运维·spring boot·mysql·nginx
小蜗牛慢慢爬行1 小时前
如何在 Spring Boot 微服务中设置和管理多个数据库
java·数据库·spring boot·后端·微服务·架构·hibernate