MyBatis深入了解
目录
xml 映射文件中,除了常见的select、insert、update、delete 标签之外,还有哪些标签?
Dao 接口的工作原理是什么?Dao 接口里的方法,参数不同时,方法能重载吗?
MyBatis 是如何进行分页的?分页插件的原理是什么?
简述 MyBatis 的插件运行原理,以及如何编写一个插件
MyBatis执行批量插入,能返回数据库主键列表吗?
MyBatis 动态 sql 是做什么的?都有哪些动态 sql?能简述一下动态 sql的执行原理不?
MyBatis 是如何将 sql执行结果封装为目标对象并返回的?都有哪些映射形式?
MyBatis 能执行一对一、一对多的关联查询吗?都有哪些实现方式,以及它们之间的区别
MyBatis 是否支持延迟加载?如果支持,它的实现原理是什么?
MyBatis 的 xml 映射文件中,不同的 xml 映射文件,id 是否可以重复?
MyBatis 中如何执行批处理?
MyBatis 都有哪些 Executor 执行器?它们之间的区别是什么?
MyBatis 中如何指定使用哪一种 Executor 执行器?
MyBatis 是否可以映射 Enum 枚举类?
这边推荐几篇有用的博客:
数据库ACID四大特性到底为了啥,一文带你看通透-CSDN博客
如何解决数据库和缓存不一致的问题-CSDN博客
#{} 和 ${} 的区别是什么?
答:
${}
是 Properties 文件中的变量占位符,它可以用于标签属性值和 sql 内部,属于原样文本替换,可以替换任意内容,比如${driver}会被原样替换为com.mysql.jdbc. Driver
。
一个示例:根据参数按任意字段排序:
select * from users order by ${orderCols}
orderCols
可以是 name
、name desc
、name,sex asc
等,实现灵活的排序。
#{}
是 sql 的参数占位符,MyBatis 会将 sql 中的#{}
替换为? 号,在 sql 执行前会使用 PreparedStatement 的参数设置方法,按序给 sql 的? 号占位符设置参数值,比如 ps.setInt(0, parameterValue),#{item.name}
的取值方式为使用反射从参数对象中获取 item 对象的 name 属性值,相当于param.getItem().getName()
。
xml 映射文件中,除了常见的select、insert、update、delete 标签之外,还有哪些标签?
答:还有很多其他的标签, <resultMap>
、 <parameterMap>
、 <sql>
、 <include>
、 <selectKey>
,加上动态 sql 的 9 个标签, trim|where|set|foreach|if|choose|when|otherwise|bind
等,其中 <sql>
为 sql 片段标签,通过 <include>
标签引入 sql 片段, <selectKey>
为不支持自增的主键生成策略标签。
Dao 接口的工作原理是什么?Dao 接口里的方法,参数不同时,方法能重载吗?
答:最佳实践中,通常一个 xml 映射文件,都会写一个 Dao 接口与之对应。Dao 接口就是人们常说的 Mapper
接口,接口的全限名,就是映射文件中的 namespace 的值,接口的方法名,就是映射文件中 MappedStatement
的 id 值,接口方法内的参数,就是传递给 sql 的参数。 Mapper
接口是没有实现类的,当调用接口方法时,接口全限名+方法名拼接字符串作为 key 值,可唯一定位一个 MappedStatement
,举例:com.mybatis3.mappers. StudentDao.findStudentById
,可以唯一找到 namespace 为 com.mybatis3.mappers. StudentDao
下面 id = findStudentById
的 MappedStatement
。在 MyBatis 中,每一个 <select>
、 <insert>
、 <update>
、 <delete>
标签,都会被解析为一个 MappedStatement
对象。
Dao 接口里的方法,是不能重载的,因为是全限名+方法名的保存和寻找策略。
Dao 接口里的方法可以重载,但是 Mybatis 的 xml 里面的 ID 不允许重复。
Mybatis 版本 3.3.0,亲测如下:
/*** Mapper接口里面方法重载*/
public interface StuMapper {List<Student> getAllStu();List<Student> getAllStu(@Param("id") Integer id);
}
然后在 StuMapper.xml
中利用 Mybatis 的动态 sql 就可以实现。
<select id="getAllStu" resultType="com.pojo.Student">select * from student<where><if test="id != null">id = #{id}</if></where>
</select>
能正常运行,并能得到相应的结果,这样就实现了在 Dao 接口中写重载方法。
Mybatis 的 Dao 接口可以有多个重载方法,但是多个接口对应的映射必须只有一个,否则启动会报错。
Dao 接口的工作原理是 JDK 动态代理,MyBatis 运行时会使用 JDK 动态代理为 Dao 接口生成代理 proxy 对象,代理对象 proxy 会拦截接口方法,转而执行 MappedStatement
所代表的 sql,然后将 sql 执行结果返回。
补充:
Dao 接口方法可以重载,但是需要满足以下条件:
- 仅有一个无参方法和一个有参方法
- 多个有参方法时,参数数量必须一致。且使用相同的
@Param
,或者使用param1
这种
测试如下:
PersonDao.java
Person queryById();Person queryById(@Param("id") Long id);Person queryById(@Param("id") Long id, @Param("name") String name);
PersonMapper.xml
<select id="queryById" resultMap="PersonMap">selectid, name, age, addressfrom person<where><if test="id != null">id = #{id}</if><if test="name != null and name != ''">name = #{name}</if></where>limit 1
</select>
org.apache.ibatis.scripting.xmltags. DynamicContext. ContextAccessor#getProperty
方法用于获取 <if>
标签中的条件值
public Object getProperty(Map context, Object target, Object name) {Map map = (Map) target;Object result = map.get(name);if (map.containsKey(name) || result != null) {return result;}Object parameterObject = map.get(PARAMETER_OBJECT_KEY);if (parameterObject instanceof Map) {return ((Map)parameterObject).get(name);}return null;
}
parameterObject
为 map,存放的是 Dao 接口中参数相关信息。
((Map)parameterObject).get(name)
方法如下
public V get(Object key) {if (!super.containsKey(key)) {throw new BindingException("Parameter '" + key + "' not found. Available parameters are " + keySet());}return super.get(key);
}
queryById()
方法执行时,parameterObject
为 null,getProperty
方法返回 null 值,<if>
标签获取的所有条件值都为 null,所有条件不成立,动态 sql 可以正常执行。queryById(1L)
方法执行时,parameterObject
为 map,包含了id
和param1
两个 key 值。当获取<if>
标签中name
的属性值时,进入((Map)parameterObject).get(name)
方法中,map 中 key 不包含name
,所以抛出异常。queryById(1L,"1")
方法执行时,parameterObject
中包含id
,param1
,name
,param2
四个 key 值,id
和name
属性都可以获取到,动态 sql 正常执行。
MyBatis 是如何进行分页的?分页插件的原理是什么?
答:(1) MyBatis 使用 RowBounds 对象进行分页,它是针对 ResultSet 结果集执行的内存分页,而非物理分页;(2) 可以在 sql 内直接书写带有物理分页的参数来完成物理分页功能,(3) 也可以使用分页插件来完成物理分页。
分页插件的基本原理是使用 MyBatis 提供的插件接口,实现自定义插件,在插件的拦截方法内拦截待执行的 sql,然后重写 sql,根据 dialect 方言,添加对应的物理分页语句和物理分页参数。
举例:select _ from student
,拦截 sql 后重写为:select t._ from (select \* from student)t limit 0,10
简述 MyBatis 的插件运行原理,以及如何编写一个插件
答:MyBatis 仅可以编写针对 ParameterHandler
、 ResultSetHandler
、 StatementHandler
、 Executor
这 4 种接口的插件,MyBatis 使用 JDK 的动态代理,为需要拦截的接口生成代理对象以实现接口方法拦截功能,每当执行这 4 种接口对象的方法时,就会进入拦截方法,具体就是 InvocationHandler
的 invoke()
方法,当然,只会拦截那些你指定需要拦截的方法。
实现 MyBatis 的 Interceptor
接口并复写 intercept()
方法,然后在给插件编写注解,指定要拦截哪一个接口的哪些方法即可,记住,别忘了在配置文件中配置你编写的插件。
MyBatis执行批量插入,能返回数据库主键列表吗?
答:能,JDBC 都能,MyBatis 当然也能。
MyBatis 动态 sql 是做什么的?都有哪些动态 sql?能简述一下动态 sql的执行原理不?
答:MyBatis 动态 sql 可以让我们在 xml 映射文件内,以标签的形式编写动态 sql,完成逻辑判断和动态拼接 sql 的功能。其执行原理为,使用 OGNL 从 sql 参数对象中计算表达式的值,根据表达式的值动态拼接 sql,以此来完成动态 sql 的功能。
MyBatis 提供了 9 种动态 sql 标签:
<if></if>
<where></where>(trim,set)
<choose></choose>(when, otherwise)
<foreach></foreach>
<bind/>
关于 MyBatis 动态 SQL 的详细介绍,请看这篇文章:Mybatis 系列全解(八):Mybatis 的 9 大动态 SQL 标签你知道几个? 。
关于这些动态 SQL 的具体使用方法,请看这篇文章:Mybatis【13】-- Mybatis 动态 sql 标签怎么使用?
MyBatis 是如何将 sql执行结果封装为目标对象并返回的?都有哪些映射形式?
答:第一种是使用 <resultMap>
标签,逐一定义列名和对象属性名之间的映射关系。第二种是使用 sql 列的别名功能,将列别名书写为对象属性名,比如 T_NAME AS NAME,对象属性名一般是 name,小写,但是列名不区分大小写,MyBatis 会忽略列名大小写,智能找到与之对应对象属性名,你甚至可以写成 T_NAME AS NaMe,MyBatis 一样可以正常工作。
有了列名与属性名的映射关系后,MyBatis 通过反射创建对象,同时使用反射给对象的属性逐一赋值并返回,那些找不到映射关系的属性,是无法完成赋值的。
MyBatis 能执行一对一、一对多的关联查询吗?都有哪些实现方式,以及它们之间的区别
答:能,MyBatis 不仅可以执行一对一、一对多的关联查询,还可以执行多对一,多对多的关联查询,多对一查询,其实就是一对一查询,只需要把 selectOne()
修改为 selectList()
即可;多对多查询,其实就是一对多查询,只需要把 selectOne()
修改为 selectList()
即可。
关联对象查询,有两种实现方式,一种是单独发送一个 sql 去查询关联对象,赋给主对象,然后返回主对象。另一种是使用嵌套查询,嵌套查询的含义为使用 join 查询,一部分列是 A 对象的属性值,另外一部分列是关联对象 B 的属性值,好处是只发一个 sql 查询,就可以把主对象和其关联对象查出来。
那么问题来了,join 查询出来 100 条记录,如何确定主对象是 5 个,而不是 100 个?其去重复的原理是 <resultMap>
标签内的 <id>
子标签,指定了唯一确定一条记录的 id 列,MyBatis 根据 <id>
列值来完成 100 条记录的去重复功能, <id>
可以有多个,代表了联合主键的语意。
同样主对象的关联对象,也是根据这个原理去重复的,尽管一般情况下,只有主对象会有重复记录,关联对象一般不会重复。
举例:下面 join 查询出来 6 条记录,一、二列是 Teacher 对象列,第三列为 Student 对象列,MyBatis 去重复处理后,结果为 1 个老师 6 个学生,而不是 6 个老师 6 个学生。
MyBatis 是否支持延迟加载?如果支持,它的实现原理是什么?
答:MyBatis 仅支持 association 关联对象和 collection 关联集合对象的延迟加载,association 指的就是一对一,collection 指的就是一对多查询。在 MyBatis 配置文件中,可以配置是否启用延迟加载 lazyLoadingEnabled=true|false。
它的原理是,使用 CGLIB
创建目标对象的代理对象,当调用目标方法时,进入拦截器方法,比如调用 a.getB().getName()
,拦截器 invoke()
方法发现 a.getB()
是 null 值,那么就会单独发送事先保存好的查询关联 B 对象的 sql,把 B 查询上来,然后调用 a.setB(b),于是 a 的对象 b 属性就有值了,接着完成 a.getB().getName()
方法的调用。这就是延迟加载的基本原理。
当然了,不光是 MyBatis,几乎所有的包括 Hibernate,支持延迟加载的原理都是一样的。
MyBatis 的 xml 映射文件中,不同的 xml 映射文件,id 是否可以重复?
答:不同的 xml 映射文件,如果配置了 namespace,那么 id 可以重复;如果没有配置 namespace,那么 id 不能重复;毕竟 namespace 不是必须的,只是最佳实践而已。
原因就是 namespace+id 是作为 Map<String, MappedStatement>
的 key 使用的,如果没有 namespace,就剩下 id,那么,id 重复会导致数据互相覆盖。有了 namespace,自然 id 就可以重复,namespace 不同,namespace+id 自然也就不同。
MyBatis 中如何执行批处理?
使用 BatchExecutor
完成批处理
MyBatis 都有哪些 Executor 执行器?它们之间的区别是什么?
:MyBatis 有三种基本的 Executor
执行器:
SimpleExecutor
: 每执行一次 update 或 select,就开启一个 Statement 对象,用完立刻关闭 Statement 对象。ReuseExecutor
: 执行 update 或 select,以 sql 作为 key 查找 Statement 对象,存在就使用,不存在就创建,用完后,不关闭 Statement 对象,而是放置于 Map<String, Statement>内,供下一次使用。简言之,就是重复使用 Statement 对象。BatchExecutor
:执行 update(没有 select,JDBC 批处理不支持 select),将所有 sql 都添加到批处理中(addBatch()),等待统一执行(executeBatch()),它缓存了多个 Statement 对象,每个 Statement 对象都是 addBatch()完毕后,等待逐一执行 executeBatch()批处理。与 JDBC 批处理相同。
作用范围:Executor
的这些特点,都严格限制在 SqlSession 生命周期范围内。
MyBatis 中如何指定使用哪一种 Executor 执行器?
在 MyBatis 配置文件中,可以指定默认的 ExecutorType
执行器类型,也可以手动给 DefaultSqlSessionFactory
的创建 SqlSession 的方法传递 ExecutorType
类型参数。
MyBatis 是否可以映射 Enum 枚举类?
MyBatis 可以映射枚举类,不单可以映射枚举类,MyBatis 可以映射任何对象到表的一列上。映射方式为自定义一个 TypeHandler
,实现 TypeHandler
的 setParameter()
和 getResult()
接口方法。 TypeHandler
有两个作用:
- 一是完成从 javaType 至 jdbcType 的转换;
- 二是完成 jdbcType 至 javaType 的转换,体现为
setParameter()
和getResult()
两个方法,分别代表设置 sql 问号占位符参数和获取列查询结果。
相关文章:
MyBatis深入了解
目录 xml 映射文件中,除了常见的select、insert、update、delete 标签之外,还有哪些标签? Dao 接口的工作原理是什么?Dao 接口里的方法,参数不同时,方法能重载吗? MyBatis 是如何进行分页的?分页插件的原理是什么? 简述 …...

语音技术与人工智能:智能语音交互的多场景应用探索
引言 近年来,智能语音技术取得了飞速发展,逐渐渗透到日常生活和各行各业中。从语音助手到智能家居控制,再到企业客服和教育辅导,语音交互正以前所未有的速度改变着人机沟通的方式。这一变革背后,人工智能技术无疑是关键…...

Openwrt @ rk3568平台 固件编译实践(二)- ledeWRT版本
目录 ledeWRT介绍固件编译下载代码修改feed源更新并安装编译第三方软件包制作用于eMMC烧写的rootfs基于lede发行版验证烧写rk3568.img, LEDE wrt启动成功refhttps://blog.csdn.net/zc21463071/article/details/106751361介绍rk3568平台下, lede 大神版 openwrt固件的下载、编译…...
Windows下调试Dify相关组件(1)--前端Web
1. 什么是Dify? 官方介绍:Dify 是一款开源的大语言模型(LLM) 应用开发平台。它融合了后端即服务(Backend as Service)和 LLMOps 的理念,使开发者可以快速搭建生产级的生成式 AI 应用。 这是个组件式框架,即使是非技…...

对话|企业如何构建更完善的容器供应链安全防护体系
对话|企业如何构建更完善的容器供应链安全防护体系 云布道师 随着云计算和 DevOps 的兴起,容器技术和自动化成为软件开发中的必要手段,软件供应链也进入了自动化及 CI/CD 阶段。然而,容器技术和自动化虽然提升了软件的更新速度&…...
HTML5 缩放动画(Zoom In/Out)详解
HTML5 缩放动画(Zoom In/Out)详解 缩放动画是一种常见的视觉效果,用于使网页元素逐渐放大或缩小,从而吸引用户的注意力。下面将介绍如何使用 CSS 和 JavaScript 实现这种动画效果。 1. 使用 CSS 实现缩放动画 可以通过 CSS 的 …...

C语言——文件IO 【文件IO和标准IO区别,操作文件IO】open,write,read,dup2,access,stat
1.思维导图 2.练习 1:使用C语言编写一个简易的界面,界面如下 1:标准输出流 2:标准错误流 3:文件流 要求:按1的时候,通过printf输出数据,按2的时候,通过p…...

【C++习题】22.随机链表的复制
文章目录 题目:138. 随机链表的复制 - 力扣(LeetCode)代码: 题目:138. 随机链表的复制 - 力扣(LeetCode) 链接🔗:138. 随机链表的复制 - 力扣(LeetCode&…...

备考蓝桥杯:数据结构概念浅谈
目录 1数据结构的概念 什么是数据结构: 为什么要有数据结构 2.数据结构的三个组成要素 1.逻辑结构 2.存储结构 3.数据运算 3。算法好坏的度量(时间复杂度和空间复杂度) 时间复杂度计算 最优和平均和最差时间复杂度 计算时间复杂度例子 空间复…...

【TI毫米波雷达】DCA1000不使用mmWave Studio的数据采集方法,以及自动化实时数据采集
【TI毫米波雷达】DCA1000不使用mmWave Studio的数据采集方法,以及自动化实时数据采集 mmWave Studio提供的功能完全够用了 不用去纠结用DCA1000低延迟、无GUI传数据 速度最快又保证算力无非就是就是Linux板自己写驱动做串口和UDP 做雷达产品应用也不会采用DCA1000的…...
创建型模式3.建造者模式
创建型模式 工厂方法模式(Factory Method Pattern)抽象工厂模式(Abstract Factory Pattern)建造者模式(Builder Pattern)原型模式(Prototype Pattern)单例模式(Singleto…...

【集成学习】Boosting算法详解
文章目录 1. 集成学习概述2. Boosting算法详解3. Gradient Boosting算法详解3.1 基本思想3.2 公式推导 4. Python实现 1. 集成学习概述 集成学习(Ensemble Learning)是一种通过结合多个模型的预测结果来提高整体预测性能的技术。相比于单个模型…...

【Orca】Orca - Graphlet 和 Orbit 计数算法
Orca(ORbit Counting Algorithm)是一种用于对网络中的小图进行计数的有效算法。它计算网络中每个节点的节点和边缘轨道(4 节点和 5 节点小图)。 orca是一个用于图形网络分析的工具,主要用于计算图中的 graphlets&#…...

58. Three.js案例-创建一个带有红蓝配置的半球光源的场景
58. Three.js案例-创建一个带有红蓝配置的半球光源的场景 实现效果 本案例展示了如何使用Three.js创建一个带有红蓝配置的半球光源的场景,并在其中添加一个旋转的球体。通过设置不同的光照参数,可以观察到球体表面材质的变化。 知识点 WebGLRenderer …...

【Git原理和使用】Git 分支管理(创建、切换、合并、删除、bug分支)
一、理解分支 我们可以把分支理解为一个分身,这个分身是与我们的主身是相互独立的,比如我们的主身在这个月学C,而分身在这个月学java,在一个月以后我们让分身与主身融合,这样主身在一个月内既学会了C,也学…...
义乌购的反爬虫机制怎么应对?
在面对义乌购的反爬虫机制时,可以采取以下几种策略来应对: 1. 使用代理IP 义乌购可能会对频繁访问的IP地址进行限制,因此使用代理IP可以有效地隐藏爬虫的真实IP地址,避免被封禁。可以构建一个代理IP池,每次请求时随机…...

消息中间件面试
RabbitMQ 如何保证消息不丢失 消息重复消费 死信交换机 消息堆积怎么解决 高可用机制 Kafka 如何保证消息不丢失 如何保证消息的顺序性 高可用机制 数据清理机制 实现高性能的设计...

基于CLIP和DINOv2实现图像相似性方面的比较
概述 在人工智能领域,CLIP和DINOv2是计算机视觉领域的两大巨头。CLIP彻底改变了图像理解,而DINOv2为自监督学习带来了新的方法。 在本文中,我们将踏上一段旅程,揭示定义CLIP和DINOv2的优势和微妙之处。我们的目标是发现这些模型…...
利用Python爬虫获取API接口:探索数据的力量
引言 在当今数字化时代,数据已成为企业、研究机构和个人获取信息、洞察趋势和做出决策的重要资源。Python爬虫作为一种高效的数据采集工具,能够帮助我们自动化地从互联网上获取大量的数据。而API接口作为数据获取的重要途径之一,为我们提供了…...

【LeetCode】力扣刷题热题100道(1-5题)附源码 链表 子串 中位数 回文子串(C++)
目录 1.两数之和 2.两数相加-链表 3.无重复字符的最长子串 4.寻找两个正序数组的中位数 5.最长回文子串 1.两数之和 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。…...

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)
题目:3442. 奇偶频次间的最大差值 I 思路 :哈希,时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况,哈希表这里用数组即可实现。 C版本: class Solution { public:int maxDifference(string s) {int a[26]…...

接口测试中缓存处理策略
在接口测试中,缓存处理策略是一个关键环节,直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性,避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明: 一、缓存处理的核…...
在软件开发中正确使用MySQL日期时间类型的深度解析
在日常软件开发场景中,时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志,到供应链系统的物流节点时间戳,时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库,其日期时间类型的…...
STM32+rt-thread判断是否联网
一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...
【Go】3、Go语言进阶与依赖管理
前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课,做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程,它的核心机制是 Goroutine 协程、Channel 通道,并基于CSP(Communicating Sequential Processes࿰…...

CocosCreator 之 JavaScript/TypeScript和Java的相互交互
引擎版本: 3.8.1 语言: JavaScript/TypeScript、C、Java 环境:Window 参考:Java原生反射机制 您好,我是鹤九日! 回顾 在上篇文章中:CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...

令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍
文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结: 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析: 实际业务去理解体会统一注…...
【python异步多线程】异步多线程爬虫代码示例
claude生成的python多线程、异步代码示例,模拟20个网页的爬取,每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程:允许程序同时执行多个任务,提高IO密集型任务(如网络请求)的效率…...
安卓基础(aar)
重新设置java21的环境,临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的: MyApp/ ├── app/ …...

搭建DNS域名解析服务器(正向解析资源文件)
正向解析资源文件 1)准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2)服务端安装软件:bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...