当前位置: 首页 > news >正文

MyBatis一文入门精通,面试题(含答案)

一、MyBatis详细介绍

MyBatis 是一个流行的 Java 持久层框架,主要用于简化 SQL 数据库操作。它的设计初衷是通过 XML 或注解的方式配置和执行 SQL 语句,使得数据库操作更加灵活、方便和高效。相比于传统的 JDBC,MyBatis 提供了一些关键优势:

1. SQL 映射与对象映射

  • MyBatis 允许开发者通过 XML 文件或注解将 SQL 语句与 Java 方法映射起来。在执行 SQL 时,无需手写 SQL 代码或依赖复杂的 ORM 映射,只需调用对应的 Java 方法即可。
  • MyBatis 支持映射数据库结果集到 Java 对象,例如从数据库中查询的数据可以自动转换为 Java 实体类,方便操作和管理。

2. 动态 SQL 支持

  • MyBatis 提供动态 SQL 功能,允许通过 <if>, <choose>, <where>, <foreach> 等标签在 XML 中编写条件语句,从而根据不同条件动态生成 SQL 查询。

3. 自动映射

  • MyBatis 的自动映射功能可以自动将查询结果与 Java 对象的属性进行映射,大大减少了手工映射的代码量。

4. 灵活的配置

  • MyBatis 的 XML 配置文件结构清晰,支持灵活的设置。开发者可以在配置文件中定义数据库连接信息、数据源和 MyBatis 的各种属性。

5. 性能

  • 相比于 ORM 框架(如 Hibernate),MyBatis 更加轻量级,性能开销较小,更加适合那些需要手动优化 SQL 性能的场景。

6. 缓存支持

  • MyBatis 提供了一级缓存(Session 缓存)和二级缓存(Mapper 缓存),可以提高查询效率。

典型应用场景

  • 需要复杂 SQL 的项目:MyBatis 非常适合数据查询和数据操作相对复杂、需要手写 SQL 的场景。
  • 数据库性能优化要求高:MyBatis 不会生成复杂的 SQL 语句,适合数据库优化需求高的场景。

常见组件

  • SqlSession:用于执行持久化操作的接口,MyBatis 提供了openSession()方法来创建SqlSession实例。
  • Mapper Interface:Mapper 是 MyBatis 的核心组件,通常通过 Java 接口定义 SQL 操作方法,然后通过 XML 文件或注解将这些方法与 SQL 语句映射。

示例

假设有一个 User 表和对应的 User 类,可以通过 Mapper 文件配置 SQL 查询:

XML 配置方式
<!-- UserMapper.xml -->
<mapper namespace="com.example.mapper.UserMapper"><select id="getUserById" parameterType="int" resultType="User">SELECT * FROM User WHERE id = #{id}</select>
</mapper>
接口定义
// UserMapper.java
public interface UserMapper {User getUserById(int id);
}
Java 代码调用
SqlSession session = sqlSessionFactory.openSession();
UserMapper mapper = session.getMapper(UserMapper.class);
User user = mapper.getUserById(1);

适用的优劣势

  • 优势:灵活性强,适合数据库操作复杂的系统,SQL 性能控制较好。
  • 劣势:需要手写 SQL,维护 SQL 代码的工作量较大。

MyBatis 非常适合像您正在进行的基于 Spring Boot 和数据库交互的项目,尤其是与复杂 SQL 相关的场景。

二、有哪些常用的用法

MyBatis 的一些常用方法主要集中在 SqlSessionMapper 中。SqlSession 是 MyBatis 中的核心接口,负责执行 SQL 语句、获取映射器(Mapper)、管理事务等。通过这些方法,可以方便地进行增、删、改、查等操作。

以下是一些常用的 MyBatis 方法和用途:

1. 增删改查操作

查询操作
  • selectOne(String statement, Object parameter):执行查询,返回单条结果。通常用于根据主键查询。

    User user = sqlSession.selectOne("com.example.mapper.UserMapper.getUserById", id);
    
  • selectList(String statement, Object parameter):执行查询,返回多个结果,适合返回列表。

    List<User> users = sqlSession.selectList("com.example.mapper.UserMapper.getUsersByAge", age);
    
  • selectMap(String statement, Object parameter, String mapKey):执行查询,将结果集以 Map 的形式返回。mapKey 参数指定用结果对象的哪个属性作为键。

    Map<Integer, User> userMap = sqlSession.selectMap("com.example.mapper.UserMapper.getAllUsers", "id");
    
插入操作
  • insert(String statement, Object parameter):执行插入操作,返回影响的行数。
    int rows = sqlSession.insert("com.example.mapper.UserMapper.insertUser", user);
    
更新操作
  • update(String statement, Object parameter):执行更新操作,返回影响的行数。
    int rows = sqlSession.update("com.example.mapper.UserMapper.updateUser", user);
    
删除操作
  • delete(String statement, Object parameter):执行删除操作,返回影响的行数。
    int rows = sqlSession.delete("com.example.mapper.UserMapper.deleteUserById", id);
    

2. 事务管理

MyBatis 默认不会自动提交事务。通过以下方法可以手动提交或回滚事务:

  • commit():提交事务。

    sqlSession.commit();
    
  • rollback():回滚事务。

    sqlSession.rollback();
    

3. 批量操作

MyBatis 支持批量操作,适合需要高性能批量处理的场景。例如,批量插入数据可以显著减少数据库连接和事务提交的开销。

  • flushStatements():强制执行未提交的批量操作。
  • clearCache():清空本地缓存(一级缓存)。

4. 缓存管理

MyBatis 提供一级缓存(SqlSession 级别)和二级缓存(Mapper 级别)。可以通过以下方法管理缓存:

  • clearCache():清除 SqlSession 的一级缓存。
  • close():关闭 SqlSession,关闭时会自动提交或回滚事务并清空缓存。

5. 使用 Mapper 接口

使用 Mapper 接口可以简化代码,不需要手动调用 selectOneselectList 等方法。通过 getMapper() 方法获取 Mapper 实例后,可以直接调用接口定义的方法:

UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = mapper.getUserById(1);
List<User> users = mapper.getUsersByAge(25);

示例代码

以下示例展示了如何在增删改查操作中使用 MyBatis:

try (SqlSession sqlSession = sqlSessionFactory.openSession()) {UserMapper mapper = sqlSession.getMapper(UserMapper.class);// 插入数据User newUser = new User("John", 30);mapper.insertUser(newUser);sqlSession.commit();// 查询数据User user = mapper.getUserById(newUser.getId());// 更新数据user.setAge(31);mapper.updateUser(user);sqlSession.commit();// 删除数据mapper.deleteUserById(user.getId());sqlSession.commit();
}

这些方法提供了对数据库操作的基本支持。在实际开发中,配合 Mapper 接口和 XML 文件中的 SQL 配置,MyBatis 可以高效地实现数据库的 CRUD 操作。

三、常见面试题

在 Java 岗位面试中,MyBatis 相关的常见面试题通常围绕其核心概念、配置、使用方式和性能优化等方面。以下是一些针对 MyBatis 的常见面试题及其答案:

1. MyBatis 是什么?有哪些特点?

A:
MyBatis 是一个优秀的持久层框架,用于简化 Java 应用程序与数据库之间的交互。它主要的特点有:

  • 支持 SQL 语句的 XML 配置和注解配置,灵活且易于调试。
  • 支持动态 SQL,可以通过条件语句控制 SQL 逻辑。
  • 支持对象与关系数据库之间的映射(ORM)。
  • 支持一级缓存(SqlSession 级别)和二级缓存(Mapper 级别)。
  • 提供了强大的插件机制,允许用户根据需要扩展功能。

2. MyBatis 中的一级缓存和二级缓存是什么?

A:

  • 一级缓存:一级缓存是基于 SqlSession 级别的缓存。同一个 SqlSession 作用域内,相同的查询会直接从缓存中读取数据,而不是执行数据库查询。当 SqlSession 关闭后,一级缓存也会失效。

  • 二级缓存:二级缓存是基于 Mapper 级别的缓存。不同 SqlSession 可以共享二级缓存,但需要在 MyBatis 配置文件中启用。二级缓存的有效期比一级缓存长,适合共享数据不频繁变化的场景。

示例: 在 XML 中开启二级缓存:

<mapper namespace="com.example.mapper.UserMapper"><cache />
</mapper>

3. MyBatis 的动态 SQL 是什么?有哪些标签?

A:
MyBatis 的动态 SQL 是指根据条件动态拼接 SQL 语句,以实现更加灵活的查询。常用的动态 SQL 标签有:

  • <if>:根据条件决定是否包含某部分 SQL。
  • <choose><when><otherwise>:类似 Java 中的 switch 语句,选择执行的 SQL 语句。
  • <where>:自动去除多余的 AND/OR,使查询更加简洁。
  • <set>:在更新语句中使用,去除不需要的逗号。
  • <foreach>:用于遍历集合,常用于 IN 查询。

示例: 使用动态 SQL 进行条件查询:

<select id="findUsers" parameterType="User" resultType="User">SELECT * FROM User<where><if test="name != null">AND name = #{name}</if><if test="age != null">AND age = #{age}</if></where>
</select>

4. MyBatis 的 #$ 的区别是什么?

A:

  • #{}:预编译方式,使用占位符防止 SQL 注入。MyBatis 会将 #{} 解析为 ?,并绑定参数,适合传递变量。

  • ${}:直接拼接参数到 SQL 中,不会进行预编译,容易造成 SQL 注入问题。一般用于表名或列名等非用户输入的动态内容。

示例:

<select id="getUser" resultType="User">SELECT * FROM ${tableName} WHERE id = #{id}
</select>

5. MyBatis 映射文件中的 <resultMap> 有什么作用?

A:
<resultMap> 用于定义数据库查询结果与 Java 对象之间的映射关系,适合复杂的映射需求。例如,当数据库表列名与 Java 属性名不一致,或需要映射嵌套对象时,可以使用 <resultMap> 自定义映射。

示例:

<resultMap id="userResultMap" type="User"><id property="id" column="user_id"/><result property="name" column="user_name"/><association property="address" javaType="Address"><id property="id" column="address_id"/><result property="street" column="street"/></association>
</resultMap>

6. 如何在 MyBatis 中执行批量操作?

A:
MyBatis 通过 ExecutorType.BATCH 模式支持批量操作,适合需要高效执行大量插入、更新或删除的场景。使用批量模式后,MyBatis 不会立即执行 SQL,而是将语句缓存起来,在 commit 时一次性发送到数据库。

示例:

SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH);
UserMapper mapper = session.getMapper(UserMapper.class);for (User user : users) {mapper.insertUser(user);
}
session.commit();
session.close();

7. MyBatis 插件机制是如何工作的?

A:
MyBatis 提供了插件机制,允许用户在 SQL 执行的各个阶段(如 ExecutorStatementHandlerParameterHandlerResultSetHandler)插入自定义逻辑。实现插件需要创建类并实现 Interceptor 接口,然后在配置文件中注册插件。

示例:

@Intercepts({@Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class})})
public class ExamplePlugin implements Interceptor {@Overridepublic Object intercept(Invocation invocation) throws Throwable {System.out.println("Before update");Object result = invocation.proceed();System.out.println("After update");return result;}
}

8. MyBatis 如何管理事务?

A:
MyBatis 默认不会自动提交事务,需要手动管理。可以通过 SqlSessioncommit()rollback() 方法来管理事务。通常在 Spring 环境中,事务由 Spring 事务管理器管理,只需在方法上添加 @Transactional 注解即可。

示例:

try (SqlSession sqlSession = sqlSessionFactory.openSession()) {UserMapper mapper = sqlSession.getMapper(UserMapper.class);mapper.insertUser(user);sqlSession.commit(); // 手动提交事务
} catch (Exception e) {sqlSession.rollback(); // 发生异常时回滚
}

9. 如何优化 MyBatis 性能?

A:
MyBatis 性能优化方法包括:

  • 启用 二级缓存,缓存不经常改变的数据,减少数据库访问。
  • 使用 批量操作,如批量插入、更新和删除,减少数据库连接次数。
  • 减少 嵌套查询,避免 N+1 问题,可以通过 join 查询减少 SQL 次数。
  • 合理设置 懒加载,只在需要时加载关联数据。
  • 使用合适的 SQL 索引,并优化 SQL 语句。

10. MyBatis 如何处理多对多关系?

A:
在 MyBatis 中处理多对多关系,可以通过关联映射的 <collection> 元素来实现。通常通过中间表将两表关联起来,再使用 <resultMap> 映射数据。

示例:

<resultMap id="UserResultMap" type="User"><id property="id" column="user_id"/><result property="name" column="user_name"/><collection property="roles" ofType="Role"><id property="id" column="role_id"/><result property="name" column="role_name"/></collection>
</resultMap>

这些问题涵盖了 MyBatis 的核心概念和常见应用场景。掌握这些内容可以帮助您在面试中展示对 MyBatis 的深入理解。

相关文章:

MyBatis一文入门精通,面试题(含答案)

一、MyBatis详细介绍 MyBatis 是一个流行的 Java 持久层框架&#xff0c;主要用于简化 SQL 数据库操作。它的设计初衷是通过 XML 或注解的方式配置和执行 SQL 语句&#xff0c;使得数据库操作更加灵活、方便和高效。相比于传统的 JDBC&#xff0c;MyBatis 提供了一些关键优势&…...

Ubuntu18.04服务器非root用户在虚拟环境下的python版本设定

最近需要跑一个python3.9.16版本的代码&#xff0c;Ubuntu18.04服务器上是上次博客中已经定死的python3.8.0版本 需要创建一个虚拟环境&#xff0c;并且在虚拟环境中配置python3.9.16版本 只需要创建一个虚拟环境 conda create -n yyy python3.9.16yyy是你的虚拟环境名字 创建…...

CodeS:构建用于文本到 SQL 的开源语言模型

发布于&#xff1a;2024 年 10 月 29 日 #RAG #Text2 SQL #NL2 SQL 语言模型在将自然语言问题转换为 SQL 查询&#xff08;文本到 SQL &#xff09;的任务中显示出良好的性能。然而&#xff0c;大多数最先进的 &#xff08;SOTA&#xff09; 方法都依赖于强大但闭源的大型语言…...

HTML 基础概念:什么是 HTML ? HTML 的构成 与 HTML 基本文档结构

文章目录 什么是 HTML &#xff1f;HTML 的构成 &#xff1f;什么是 HTML 元素&#xff1f;HTML 元素的组成部分HTML 元素的特点 HTML 基本文档结构如何打开新建的 HTML 文件代码查看 什么是 HTML &#xff1f; HTML&#xff08;超文本标记语言&#xff0c;HyperText Markup L…...

18 Docker容器集群网络架构:一、etcd 概述

文章目录 Docker容器集群网络架构:一、etcd概述1.1 etcd 的基本概念和特点1.1.1 定义1.1.2 特点1.2 etcd 在 Docker 集群网络中的作用1.3 etcd 集群的架构和原理1.3.1 架构1.3.2 原理Docker容器集群网络架构:一、etcd概述 etcd是一个高可用的分布式键值存储系统,它主要用于…...

R语言贝叶斯分层、层次(Hierarchical Bayesian)模型房价数据空间分析

原文链接&#xff1a;https://tecdat.cn/?p38077 本文主要探讨了贝叶斯分层模型在分析区域数据方面的应用&#xff0c;以房价数据为例&#xff0c;详细阐述了如何帮助客户利用R进行模型拟合、分析及结果解读&#xff0c;展示了该方法在处理空间相关数据时的灵活性和有效性。&a…...

SpringBoot 在初始化加载无法使用@Value的时候读取配置文件教程

怀旧网个人博客地址&#xff1a;怀旧网&#xff0c;博客详情&#xff1a;SpringBoot 在初始化加载无法使用Value的时候读取配置文件教程 读取数据库数据案例 // 创建YamlPropertiesFactoryBean对象 YamlPropertiesFactoryBean factory new YamlPropertiesFactoryBean(); // …...

基于MATLAB的身份证号码识别系统

课题介绍 本课题为基于连通域分割和模板匹配的二代居民身份证号码识别系统&#xff0c;带有一个GUI人机交互界面。可以识别数十张身份证图片。 首先从身份证图像上获取0&#xff5e;9和X共十一个号码字符的样本图像作为后续识别的字符库样本&#xff0c;其次将待测身份证图像…...

【人工智能-初级】练习题:matplotlib基础练习30例

练习 1: 画折线图 import matplotlib.pyplot as plt x = [1, 2, 3, 4, 5] y = [10, 20, 25, 30, 40] 使用 plt.plot() 画出折线图,适用于连续数据的可视化 plt.plot(x, y) plt.xlabel(‘X 轴’) plt.ylabel(‘Y 轴’) plt.title(‘简单折线图’) plt.show() 练习 2: 画散…...

【002】基于SpringBoot+thymeleaf实现的蓝天幼儿园管理系统

基于SpringBootthymeleaf实现的蓝天幼儿园管理系统 文章目录 系统说明技术选型成果展示账号地址及其他说明源码获取 系统说明 基于SpringBootthymeleaf实现的蓝天幼儿园管理系统是为幼儿园提供的一套管理平台&#xff0c;可以提高幼儿园信息管理的准确性&#xff0c;系统将信息…...

nvm详解

本文借鉴转载于 nvm文档手册 文章目录 1.nvm是什么&#xff1f;2.nvm安装2.1 window上安装下载链接安装步骤 2.2 Mac上安装使用homebrew 安装 nvm 3.nvm使用指令 1.nvm是什么&#xff1f; nvm&#xff08;Node Version Manager&#xff09;是一个用于管理和切换不同版本 Node.…...

Lucene的概述与应用场景(1)

文章目录 第1章 Lucene概述1.1 搜索的实现方案1.1.1 传统实现方案1.1.2 Lucene实现方案 1.2 数据查询方法1.1.1 顺序扫描法1.1.2 倒排索引法 1.3 Lucene相关概念1.3.1 文档对象1.3.2 域对象1&#xff09;分词2&#xff09;索引3&#xff09;存储 1.3.3 常用的Field种类 1.4 分词…...

11.3笔记

在C#中&#xff0c;静态类和普通类&#xff08;实例类&#xff09;有一些关键的区别&#xff1a; 实例化&#xff1a; 普通类&#xff1a;可以被实例化&#xff0c;即创建对象。每个对象都有自己的状态和方法。静态类&#xff1a;不能被实例化&#xff0c;它们不包含构造函数&a…...

数据结构之线段树

线段树 线段树&#xff08;Segment Tree&#xff09;是一种高效的数据结构&#xff0c;广泛应用于计算机科学和算法中&#xff0c;特别是在处理区间查询和更新问题时表现出色。以下是对线段树的详细解释&#xff1a; 一、基本概念 线段树是一种二叉搜索树&#xff0c;是算法竞…...

vue 快速入门

文章目录 一、插值表达式 {{}}二、Vue 指令2.1 v-text 和 v-html&#xff1a;2.2 v-if 和 v-show&#xff1a;2.3 v-on&#xff1a;2.4 v-bind 和 v-model&#xff1a;2.5 v-for&#xff1a; 三、生命周期四、Vue 组件库 Element五、Vue 路由 本文章适用于后端人员&#xff0c;…...

iframe视频宽度高度自适应( pc+移动都可以用,jq写法 )

注意&#xff1a;要引入jquery 可以直接使用弹框播放iframe 一、创建 index.html <!DOCTYPE html> <html><head><meta charset"utf-8"><title></title><style>.modal {/* 默认隐藏 */display: none;position: fixed;z-i…...

Observability:OpenTelemetry Elastic 分发简介

作者&#xff1a;来自 Elastic Alexander Wert•Miguel Luna•Bahubali Shetti Elastic 自豪地推出了 Elastic Distributions of OpenTelemetry (EDOT)&#xff0c;其中包含 Elastic 版本的 OpenTelemetry Collector 和多种语言 SDK&#xff0c;如 Python、Java、.NET 和 NodeJ…...

golang的RSA加密解密

参考&#xff1a;https://blog.csdn.net/lady_killer9/article/details/118026802 1.加密解密工具类PasswordUtil.go package utilimport ("crypto/rand""crypto/rsa""crypto/x509""encoding/pem""fmt""log"&qu…...

深度学习-梯度消失/爆炸产生的原因、解决方法

在深度学习模型中&#xff0c;梯度消失和梯度爆炸现象是限制深层神经网络有效训练的主要问题之一&#xff0c;这两个现象从本质上来说是由链式求导过程中梯度的缩小或增大引起的。特别是在深层网络中&#xff0c;若初始梯度在反向传播过程中逐层被放大或缩小&#xff0c;最后导…...

MVC(Model-View-Controller)模式概述

MVC&#xff08;Model-View-Controller&#xff09;是一种设计模式&#xff0c;最初由 Trygve Reenskaug 在 1970 年代提出&#xff0c;并在 Smalltalk 编程环境中得到了广泛应用。MVC 模式旨在实现用户界面和业务逻辑的分离&#xff0c;以增强应用程序的可维护性、可扩展性和复…...

Zustand 状态管理库:极简而强大的解决方案

Zustand 是一个轻量级、快速和可扩展的状态管理库&#xff0c;特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...

shell脚本--常见案例

1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件&#xff1a; 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...

Debian系统简介

目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版&#xff…...

linux arm系统烧录

1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 &#xff08;忘了有没有这步了 估计有&#xff09; 刷机程序 和 镜像 就不提供了。要刷的时…...

【项目实战】通过多模态+LangGraph实现PPT生成助手

PPT自动生成系统 基于LangGraph的PPT自动生成系统&#xff0c;可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析&#xff1a;自动解析Markdown文档结构PPT模板分析&#xff1a;分析PPT模板的布局和风格智能布局决策&#xff1a;匹配内容与合适的PPT布局自动…...

让回归模型不再被异常值“带跑偏“,MSE和Cauchy损失函数在噪声数据环境下的实战对比

在机器学习的回归分析中&#xff0c;损失函数的选择对模型性能具有决定性影响。均方误差&#xff08;MSE&#xff09;作为经典的损失函数&#xff0c;在处理干净数据时表现优异&#xff0c;但在面对包含异常值的噪声数据时&#xff0c;其对大误差的二次惩罚机制往往导致模型参数…...

JVM虚拟机:内存结构、垃圾回收、性能优化

1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...

vulnyx Blogger writeup

信息收集 arp-scan nmap 获取userFlag 上web看看 一个默认的页面&#xff0c;gobuster扫一下目录 可以看到扫出的目录中得到了一个有价值的目录/wordpress&#xff0c;说明目标所使用的cms是wordpress&#xff0c;访问http://192.168.43.213/wordpress/然后查看源码能看到 这…...

Vue ③-生命周期 || 脚手架

生命周期 思考&#xff1a;什么时候可以发送初始化渲染请求&#xff1f;&#xff08;越早越好&#xff09; 什么时候可以开始操作dom&#xff1f;&#xff08;至少dom得渲染出来&#xff09; Vue生命周期&#xff1a; 一个Vue实例从 创建 到 销毁 的整个过程。 生命周期四个…...

在golang中如何将已安装的依赖降级处理,比如:将 go-ansible/v2@v2.2.0 更换为 go-ansible/@v1.1.7

在 Go 项目中降级 go-ansible 从 v2.2.0 到 v1.1.7 具体步骤&#xff1a; 第一步&#xff1a; 修改 go.mod 文件 // 原 v2 版本声明 require github.com/apenella/go-ansible/v2 v2.2.0 替换为&#xff1a; // 改为 v…...