Spring Boot下数据隐私守护者:四大脱敏策略实战解析

文章目录

  • SpringBoot数据脱敏的四种实现方案
    • 数据脱敏概述
      • 什么是数据脱敏
      • 数据脱敏的分类
    • Spring Boot 实现数据脱敏的常见方案
      • 统一的脱敏处理工具类
      • 自定义注解与拦截器
      • AOP(面向切面编程)
      • Jackson 自定义序列化
      • MyBatis 拦截器
    • 详细案例
      • 使用自定义注解与拦截器实现数据脱敏
      • 使用AOP实现数据脱敏
      • 使用 Jackson 自定义序列化器实现数据脱敏
      • 使用 MyBatis 拦截器实现数据脱敏
    • 数据脱敏的最佳实践
      • 性能考虑
      • 安全性考虑
      • 维护性考虑

SpringBoot数据脱敏的四种实现方案

在数字化转型的浪潮中,数据隐私和安全成为了企业和组织不可忽视的核心议题。随着诸如GDPR(欧盟通用数据保护条例)和CCPA(加州消费者隐私法案)等法规的出台,对用户数据的妥善管理和保护成为了法律要求。数据脱敏技术作为一项关键的数据保护措施,其作用在于通过修改或隐藏敏感信息来预防数据泄露,进而降低数据被非法利用的风险,确保企业在遵循法规的同时,维护用户隐私的安全。

数据脱敏概述

什么是数据脱敏

数据脱敏是一种数据保护技术,用于修改数据库中的敏感或个人可识别信息(PII),使其在非生产环境中使用时不会泄露真实信息。这种技术通常应用于测试、开发、分析和备份等场景,确保即使数据被非法访问,攻击者也无法获取真实的数据细节。数据脱敏可以保护个人隐私,同时满足数据安全合规性要求。

数据脱敏的分类

数据脱敏可以分为以下几种主要类型:

  1. 静态数据脱敏

    • 描述:静态数据脱敏是在数据复制到目标系统前进行的脱敏操作。例如,在将生产数据复制到测试环境之前,会通过替换、屏蔽、加密等手段对敏感数据进行处理,确保测试环境中的数据不包含真实的个人信息。
    • 应用场景:主要用于测试、开发和报告等非生产环境。
  2. 动态数据脱敏

    • 描述:动态数据脱敏是在查询运行时实时进行的脱敏过程。当用户查询数据时,敏感信息会被即时替换或隐藏,而原始数据保持不变,仅在展示给用户时进行脱敏。
    • 应用场景:适用于生产环境下的数据查询,如报表展示、数据分析等,以防止敏感信息在未经授权的情况下被查看。
  3. 字段级数据脱敏

    • 描述:在特定字段级别上进行的脱敏,即只对数据库表中指定的列进行脱敏处理。这允许其他非敏感字段保留其原始值,而敏感字段则被脱敏。
    • 应用场景:适用于需要在数据集中保留某些字段原始值,而仅对敏感字段进行保护的情况。
  4. 行级数据脱敏

    • 描述:根据访问者的角色或权限,动态决定是否显示敏感数据。这种类型的脱敏基于访问控制策略,只有授权用户才能看到未脱敏的数据。
    • 应用场景:适用于需要根据用户身份或角色限制数据访问的场景,确保不同级别的用户只能访问他们被授权的信息。

Spring Boot 实现数据脱敏的常见方案

统一的脱敏处理工具类

首先,我们创建一个统一的脱敏处理工具类,方便在不同方案中复用。

/*** 敏感数据处理器类,用于处理和脱敏特定类型的数据。*/
public class SensitiveDataHandler {/*** 根据指定的类型对数据进行脱敏处理。** @param data 要进行脱敏处理的原始数据字符串。* @param type 数据的类型,用于确定脱敏规则,支持 "PHONE" 和 "EMAIL"。* @return 返回经过脱敏处理后的数据字符串。*/public static String mask(String data, String type) {// 根据提供的类型判断并执行相应的脱敏操作switch (type) {case "PHONE":// 对电话号码进行脱敏,保留前三位和后四位,中间用星号替代return data.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2");case "EMAIL":// 对电子邮件地址进行脱敏,保留邮箱前两位和最后的域名部分,中间用星号替代return data.replaceAll("(.{2}).+(.{2}@.+)", "$1****$2");default:// 如果类型不匹配任何已知类型,则返回原始数据而不做处理return data;}}
}

自定义注解与拦截器

通过自定义注解和拦截器,可以在接口返回数据时进行脱敏处理。这种方法适用于需要在返回给前端数据之前进行脱敏的场景。

使用方法

  • 创建自定义注解
  • 编写数据脱敏处理类
  • 配置拦截器
// 自定义注解,用于标记需要脱敏处理的字段
@Retention(RetentionPolicy.RUNTIME) // 注解将在运行时保留,以便反射机制可以读取
@Target(ElementType.FIELD) // 注解将应用于类的字段上
public @interface Sensitive {String type(); // 定义一个类型属性,用于指定数据的类型,如 EMAIL 或 PHONE
}// 用户实体类,包含需要脱敏处理的字段
public class User {@Sensitive(type = "EMAIL") // 使用自定义注解标记 email 字段,表明这是一个需要脱敏的字段private String email;// 省略其他属性和方法,如构造函数、getter 和 setter 方法
}// 拦截器配置类,用于在处理请求前对数据进行脱敏处理
@Component // 标记为 Spring Bean 组件,由 Spring 容器管理
public class DataMaskingInterceptor implements HandlerInterceptor {// 在方法调用前执行的拦截器方法@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 判断 handler 是否为 HandlerMethod 类型,即方法级别的控制器if (handler instanceof HandlerMethod) {HandlerMethod method = (HandlerMethod) handler;// 检查方法是否标注了 @ResponseBody 注解,表示该方法的结果将直接返回给客户端if (method.hasMethodAnnotation(ResponseBody.class)) {// 使用反射调用方法获取结果对象Object result = method.getMethod().invoke(handler);// 判断结果对象是否为 User 类型,如果是,则进行脱敏处理if (result instanceof User) {User user = (User) result;// 使用 SensitiveDataHandler 进行数据脱敏,此处以 email 字段为例user.setEmail(SensitiveDataHandler.mask(user.getEmail(), "EMAIL"));}}}// 返回 true 表示处理继续,false 则中断后续处理return true;}
}

AOP(面向切面编程)

使用 Spring AOP 在方法执行前后进行数据脱敏,可以简化代码并提高可维护性。

使用方法

  • 定义切面类
  • 编写切面方法进行脱敏处理
// 使用AOP(面向切面编程)实现数据脱敏
@Aspect // 标记此类为一个切面类,可以用来封装横切关注点的代码
@Component // 标记为Spring Bean组件,由Spring容器管理
public class DataMaskingAspect {/*** 环绕通知方法,用于在标注了 @ResponseBody 的方法执行前后进行脱敏处理。* * @param joinPoint 连接点对象,包含了正在执行的方法的所有信息。* @return 执行方法的结果,可能已经被脱敏处理。* @throws Throwable 如果环绕通知中的方法抛出异常,会向上抛出Throwable。*/@Around("@annotation(org.springframework.web.bind.annotation.ResponseBody)") // 环绕通知,作用于标注了 @ResponseBody 的方法public Object maskData(ProceedingJoinPoint joinPoint) throws Throwable {// 调用原方法,执行业务逻辑Object result = joinPoint.proceed();// 检查方法的返回结果是否为User对象if (result instanceof User) {User user = (User) result;// 调用敏感数据处理器,对email字段进行脱敏处理user.setEmail(SensitiveDataHandler.mask(user.getEmail(), "EMAIL"));}// 返回处理后的结果,可能是已经脱敏的数据return result;}
}

Jackson 自定义序列化

通过 Jackson 的自定义序列化器,可以在序列化对象时对敏感数据进行脱敏。

使用方法

  • 创建自定义序列化器
  • 在实体类中应用自定义序列化器
// 自定义的序列化器,用于在JSON序列化时对敏感数据进行脱敏处理
public class SensitiveSerializer extends JsonSerializer<String> {/*** 重写序列化方法,用于将String类型的值在转换成JSON格式时进行脱敏处理。* * @param value 待序列化的字符串值。* @param gen   JSON生成器,用于生成JSON格式的输出。* @param serializers 序列化提供者,提供序列化所需的上下文信息。* @throws IOException 如果在序列化过程中遇到IO错误。*/@Overridepublic void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException {// 调用敏感数据处理器,对字符串值进行脱敏处理String maskedValue = SensitiveDataHandler.mask(value, "EMAIL");// 使用JSON生成器将脱敏后的字符串值写入输出流gen.writeString(maskedValue);}
}// 用户实体类,包含需要进行脱敏处理的字段
public class User {// 使用自定义注解标记需要脱敏的字段@Sensitive(type = "EMAIL")// 使用@JsonSerialize注解指定自定义的序列化器@JsonSerialize(using = SensitiveSerializer.class)private String email;// 其他属性和方法...
}

MyBatis 拦截器

通过 MyBatis 拦截器在数据查询或保存时进行脱敏处理,可以在持久层实现数据脱敏。

使用方法

  • 编写 MyBatis 拦截器
  • 配置 MyBatis 拦截器
// 定义一个AOP拦截器,用于在MyBatis执行查询后处理结果集中的敏感数据
@Intercepts({@Signature(type = ResultSetHandler.class, method = "handleResultSets", args = {Statement.class})})
public class DataMaskingInterceptor implements Interceptor {/*** 实现Interceptor接口的intercept方法,用于在目标方法执行前后进行拦截操作。* 这里主要用于在查询结果处理完毕后对结果集中包含的敏感数据进行脱敏处理。* * @param invocation 调用对象,包含了待执行的方法和参数等信息。* @return 方法执行的结果。* @throws Throwable 如果在执行过程中出现异常,则抛出Throwable。*/@Overridepublic Object intercept(Invocation invocation) throws Throwable {// 首先调用proceed()执行目标方法(即被拦截的方法),得到原始的查询结果Object result = invocation.proceed();// 检查结果是否为List类型,因为通常查询结果会被封装为Listif (result instanceof List) {// 遍历查询结果中的每个元素for (Object obj : (List<?>) result) {// 检查元素是否为User类型,因为我们只对User对象中的email字段进行脱敏if (obj instanceof User) {// 强制类型转换为User类型User user = (User) obj;// 使用SensitiveDataHandler类的mask方法对email字段进行脱敏处理// 参数"EMAIL"指定了脱敏的类型,这可能会影响脱敏的具体规则user.setEmail(SensitiveDataHandler.mask(user.getEmail(), "EMAIL"));}}}// 返回处理后的结果return result;}
}

详细案例

使用自定义注解与拦截器实现数据脱敏

场景
接口返回的敏感数据需要脱敏处理。

步骤

  • 创建注解 @Sensitive
  • 编写数据脱敏处理类 SensitiveDataHandler
  • 配置拦截器 DataMaskingInterceptor
// 自定义注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Sensitive {String type();
}// 数据脱敏处理类
public class SensitiveDataHandler {public static String mask(String data, String type) {switch (type) {case "PHONE":return data.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2");case "EMAIL":return data.replaceAll("(.{2}).+(.{2}@.+)", "$1****$2");default:return data;}}
}// 实体类
public class User {@Sensitive(type = "EMAIL")private String email;// 省略其他属性和方法
}// 拦截器配置
@Component
public class DataMaskingInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {if (handler instanceof HandlerMethod) {HandlerMethod method = (HandlerMethod) handler;if (method.hasMethodAnnotation(ResponseBody.class)) {// 处理返回值进行脱敏Object result = method.getMethod().invoke(handler);if (result instanceof User) {User user = (User) result;user.setEmail(SensitiveDataHandler.mask(user.getEmail(), "EMAIL"));}}}return true;}
}

效果展示
调用接口时,返回的用户邮箱将会被脱敏处理,例如 user@example.com 将被处理为 us****le@example.com

使用AOP实现数据脱敏

场景
服务层方法返回的敏感数据需要脱敏处理。

步骤

  • 定义切面类 DataMaskingAspect
  • 编写切面方法 maskData
@Aspect
@Component
public class DataMaskingAspect {@Around("@annotation(org.springframework.web.bind.annotation.ResponseBody)")public Object maskData(ProceedingJoinPoint joinPoint) throws Throwable {Object result = joinPoint.proceed();if (result instanceof User) {User user = (User) result;user.setEmail(SensitiveDataHandler.mask(user.getEmail(), "EMAIL"));}return result;}
}

效果展示
调用服务层方法时,返回的用户邮箱将会被脱敏处理。

使用 Jackson 自定义序列化器实现数据脱敏

场景
实体类属性的敏感数据需要脱敏处理。

步骤

  • 创建自定义序列化器 SensitiveSerializer
  • 在实体类中应用自定义序列化器
// 自定义序列化器
public class SensitiveSerializer extends JsonSerializer<String> {@Overridepublic void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException {gen.writeString(SensitiveDataHandler.mask(value, "EMAIL"));}
}// 实体类
public class User {@Sensitive(type = "EMAIL")@JsonSerialize(using = SensitiveSerializer.class)private String email;
}

效果展示
序列化对象时,用户邮箱将会被脱敏处理。

使用 MyBatis 拦截器实现数据脱敏

场景
数据库查询结果中的敏感数据需要脱敏处理。

步骤

  • 编写 MyBatis 拦截器 DataMaskingInterceptor
  • 配置 MyBatis 拦截器
@Intercepts({@Signature(type = ResultSetHandler.class, method = "handleResultSets", args = {Statement.class})})
public class DataMaskingInterceptor implements Interceptor {@Overridepublic Object intercept(Invocation invocation) throws Throwable {Object result = invocation.proceed();if (result instanceof List) {for (Object obj : (List<?>) result) {if (obj instanceof User) {User user = (User) obj;user.setEmail(SensitiveDataHandler.mask(user.getEmail(), "EMAIL"));}}}return result;}
}

效果展示
查询数据库时,返回的用户邮箱将会被脱敏处理。

数据脱敏是在不破坏数据结构和功能的前提下,对敏感信息进行变形处理的过程,以保护个人隐私和企业机密。在实施数据脱敏策略时,确实需要从性能、安全性和维护性三个关键方面进行考虑。以下是针对这些方面的最佳实践建议:

数据脱敏的最佳实践

性能考虑

使用高效的脱敏算法:
选择快速且资源消耗低的数据脱敏算法至关重要。例如,对于简单的字符串替换,可以采用正则表达式匹配;而对于更复杂的数据类型如日期或地理位置,应使用专门优化过的算法。

异步处理与批量脱敏:
为了减少对在线系统的影响,数据脱敏可以安排在非高峰时段进行,或者在独立的批处理环境中运行。对于大量数据的脱敏,批量处理比单条记录处理更高效。

缓存已脱敏数据:
如果同一数据集需要频繁脱敏,可以考虑缓存已脱敏的数据,避免重复计算。但要注意,缓存策略不应影响数据的安全性。

安全性考虑

加密存储脱敏密钥:
如果使用可逆的脱敏技术,如加密,确保加密密钥的安全性至关重要。使用现代的加密标准,并将密钥存储在安全的地方,如硬件安全模块(HSM)或加密密钥管理服务。

最小权限原则:
只有授权的人员才能访问未脱敏数据和脱敏算法。确保所有访问都有审计跟踪,以便监控任何潜在的滥用。

数据隔离:
确保生产环境和测试/开发环境的数据严格分离。测试环境只能访问经过脱敏处理的数据,而不能访问原始敏感数据。

维护性考虑

文档化脱敏策略:
清晰地记录哪些数据需要脱敏,如何脱敏,以及为什么选择特定的脱敏方法。这有助于新成员理解流程,并在未来进行维护和改进。

自动化脱敏过程:
开发自动化脚本或使用专门的脱敏工具,减少手动干预,避免人为错误,并确保一致性。

定期审查和更新:
随着法规变化和技术进步,脱敏策略也应定期审查和更新。确保它们符合最新的合规要求和技术标准。

可逆性与不可逆性:
根据数据用途选择适当的脱敏方法。对于需要保留数据恢复能力的场景,使用可逆的脱敏技术;对于不需要恢复原数据的情况,使用不可逆的脱敏技术,如哈希或伪随机替换。

遵循以上最佳实践,可以帮助确保数据脱敏既有效又安全,同时保持系统的高性能和易于维护。

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

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

相关文章

textblob文本处理、词性分析与情感分析

1 前言 textBlob 是一個简单易用的 NLP库&#xff0c;基于 NLTK 和 pattern库&#xff0c; 提供了文本处理和情感分析等功能。 安装 textblob0.18.0 nltk3.8.1测试环境&#xff1a;Python3.10.9 使用前&#xff0c;先运行下面代码先下载些文件 import nltk nltk.download…

C#医学影像管理系统源码 PACS系统源码带三维重建,全院级数字医学影像系统

C#医学影像管理系统源码 医学影像存储与传输系统源码 PACS系统源码带三维重建&#xff0c;三甲以下医院都能满足。 PACS系统模块组成 &#xff1a; 工作站&#xff1a; 分诊工作站、超声工作站、放射工作站、内镜工作站、病理工作站。 基本信息维护&#xff1a; 输入模板、输入…

C语言从头学37——struct 指针

在前文学习结构体变量的声明时&#xff0c;曾介绍过结构体指针变量的使用。这里介绍结构体指针&#xff0c;目的是找出在函数中处理作为参数的结构体变量的方法。 一、先看一个普通结构体变量作为参数的程序 typedef struct { int a; } myInt; //定义结构体别名&#xff08;别…

Milvus 核心组件(3)--- MinIO详解

目录 背景 MinIO 安装 docker desktop 安装 Ubuntu UI 在 docker 中的安装 Minio 下载及安装 启动minio docker image 保存 启动 minio web 网页 下一次启动 MinIO基本概念 基本概述 主要特性 应用场景 MinIO 使用 连接server 创建bucket 查询bucket 上传文件…

Springboot集成Nacos配置

参考文档 Nacos 融合 Spring Boot&#xff0c;成为注册配置中心 | Nacos 官网​​​​​​​ 版本 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.1.RELE…

Layer2区块链扩容方案(1)——总述

写在前面 这篇文章作为一个简单介绍&#xff0c;很多技术只是大致提及或者引用&#xff0c;之后会在详细学习后逐项解释。 补充知识 在了解扩容方案之前&#xff0c;我们最好了解一些相关的知识概念 EVM “EVM” 是“Ethereum Virtual Machine”&#xff08;以太坊虚拟机&…

相机的内参与外参

目录 一、相机的内参二、相机的外参 一、相机的内参 如下图所示是相机的针孔模型示意图&#xff1a; 光心O所处平面是相机坐标系(O&#xff0c;P)&#xff0c;像素平面所在坐标系为像素坐标系(O’&#xff0c;P’)。 焦距f&#xff1a;O到O’的距离 相机的内参表示的是相机坐标…

100个python的基本语法知识【上】

0. 变量和赋值&#xff1a; x 5 name “John” 1. 数据类型&#xff1a; 整数&#xff08;int&#xff09; 浮点数&#xff08;float&#xff09; 字符串&#xff08;str&#xff09; 布尔值&#xff08;bool&#xff09; 2. 注释&#xff1a; # 这是单行注释 ""…

SQL Server数据迁移新纪元:数据库数据泵(Data Pump)使用指南

SQL Server数据迁移新纪元&#xff1a;数据库数据泵&#xff08;Data Pump&#xff09;使用指南 在数据管理的世界里&#xff0c;数据迁移是一个常见且复杂的过程。SQL Server提供了一个强大的工具——数据库数据泵&#xff08;Data Pump&#xff09;&#xff0c;它可以帮助我…

mysql面试(三)

MVCC机制 MVCC&#xff08;Multi-Version Concurrency Control&#xff09; 即多版本并发控制&#xff0c;了解mvcc机制&#xff0c;需要了解如下这些概念 事务id 事务每次开启时&#xff0c;都会从数据库获得一个自增长的事务ID&#xff0c;可以从事务ID判断事务的执行先后…

QT 信号槽机制

核心函数为 QMetaObject::Connection QObject::connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type Qt::AutoConnection) 参数为 1.信号发生对象 2.信号发生对象的信号 3.槽对象 4.槽对象的槽函…

嵌入式linux系统中压力测试的方法

在Linux环境下,确保系统各项资源充分且稳定地运行对任何系统管理员来说都至关重要。特别是在生产环境中,理解如何对系统资源进行基准测试和压力测试可以帮助预防未来的问题,同时也能够优化现有系统的性能。 在本文中,我们将探讨如何使用命令行工具来对Linux系统的CPU、内存…

C语言 ——— 函数指针的定义 函数指针的使用

目录 何为函数指针 打印 函数名的地址 及 &函数名的地址 函数指针的代码&#xff08;如何正确存储函数地址&#xff09; 函数指针的使用 何为函数指针 类比&#xff1a; 整型指针 - 指向整型数据的指针&#xff0c;整型指针存放的是整型数据的地址 字符指针 - 指向字…

SQLynx数据库管理工具

背景&#xff1a;业主对网络安全要求比较高&#xff0c;不提供VPN等远程工具&#xff0c;也不能开放3306端口到互联网。那怎么样运维数据库就是个难题&#xff1f;找到了SQLynx这个可以网页访问的数据库管理工具&#xff0c;给大家分享一下。 1.介绍 SQLynx原名SQL Studio&…

防抖总结——OIS/EIS/HIS/DIS/机械防抖

文章目录 防抖总结OIS工作原理优缺点应用场景 电子防抖工作原理优缺点应用场景 混合防抖工作原理优缺点应用场景 数字防抖工作原理优缺点应用场景 机械防抖工作原理优缺点应用场景实例 防抖总结 防抖技术工作原理优点缺点适用场景光学防抖&#xff08;OIS&#xff09;通过内置…

[论文笔记] pai-megatron-patch Qwen2-72B/7B/1.5B 长文本探路

[论文笔记] Pai-megatron-patch cpu-offload 改到 Qwen2-CSDN博客 Pai-Megatron-Patch (mcore代码) 长文本限制: 开SP之后,72B能开到16K,7B能开到32K。 但是72B开16K,或者7B开32K时,如果训练时训练样本中有长文本的话,则还是会OOM。 code: 相对于原repo加了一些代…

平面五杆机构运动学仿真matlab simulink

1、内容简介 略 89-可以交流、咨询、答疑 2、内容说明 略 ] 以 MATLAB 程序设计语言为平台 , 以平面可调五杆机构为主要研究对象 , 给定机构的尺寸参数 , 列出所 要分析机构的闭环矢量方程 , 使用 MATLAB 软件中 SIMULINK 仿真工具 , 在 SIMULINK 模型窗口下建立数…

麦田物语第十三天

系列文章目录 麦田物语第十三天 文章目录 系列文章目录一、实现根据物品详情显示 ItemTooltip1.ItemTooltips脚本编写二、制作 Player 的动画一、实现根据物品详情显示 ItemTooltip 1.ItemTooltips脚本编写 首先创建Scripts->Inventory->UI->ItemTooltip脚本,然后…

深入浅出WebRTC—LossBasedBweV2

WebRTC 同时使用基于丢包的带宽估计算法和基于延迟的带宽估计算法那&#xff0c;能够实现更加全面和准确的带宽评估和控制。基于丢包的带宽估计算法主要依据网络中的丢包情况来动态调整带宽估计&#xff0c;以适应网络状况的变化。本文主要讲解最新 LossBasedBweV2 的实现。 1…

docker 安装MySQL 8.4.1

拉取MySQL镜像 docker pull mysql:8.4.1 查看本地镜像 docker images 通过镜像生成容器 docker run -itd --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD123456 mysql:8.4.1 查看目录运行中的容器列表 docker ps 进入容器内简单测试 docker exec -it mysql /bin/b…