MyBatis面试题总结,详细(2024最新)

面试必须要看看

1、MyBatis 中的一级缓存和二级缓存是什么?它们的区别是什么?
MyBatis 中的一级缓存是指 SqlSession 对象内部的缓存,它是默认开启的。一级缓存的生命周期是与 SqlSession 对象绑定的,当 SqlSession 关闭时,缓存也会自动清空。一级缓存的作用是减少对数据库的查询次数,提高查询效率。
MyBatis 中的二级缓存是指 SqlSessionFactory 对象内部的缓存,它需要手动开启和配置。二级缓存的生命周期是与 SqlSessionFactory 对象绑定的,当应用程序关闭时,缓存也会自动清空。二级缓存的作用是在多个 SqlSession 之间共享缓存,提高查询效率。二级缓存可以使用 Ehcache、Redis 等第三方缓存框架来实现。

2、MyBatis 中的事务是如何控制的?
MyBatis 中的事务是由 JDBC 控制的。在 Mapper 接口方法中,可以使用 @Transactional 注解来声明事务的范围。MyBatis 支持声明式事务和编程式事务两种方式,可以根据实际需求选择适合的方式来控制事务。

3、MyBatis 中的多数据源是如何实现的?
MyBatis 中的多数据源可以通过配置多个 SqlSessionFactory 对象来实现。在 Mapper 接口中,可以使用 @MapperScan 注解来指定要扫描的 Mapper 接口所在的包,从而将多个数据源与不同的 Mapper 接口关联起来。

4、MyBatis 中的缓存失效是如何处理的?
MyBatis 中的缓存失效可以通过以下几种方式来处理:

手动清除缓存:在 Mapper 接口中,可以使用 @CacheEvict 注解来手动清除缓存。

设置缓存过期时间:可以在映射文件或 Mapper 接口中,设置缓存的过期时间,从而实现缓存的自动失效。

在 SQL 语句中添加 FOR UPDATE 子句:可以在 SQL 语句中添加 FOR UPDATE 子句,从而实现缓存的失效和锁定。

5、MyBatis 中的动态 SQL 是什么?它的作用是什么?
MyBatis 中的动态 SQL 是指根据条件动态生成 SQL 语句的技术。它的作用是可以根据实际条件生成相应的 SQL 语句,从而实现更加灵活的查询操作。MyBatis 中可以使用动态 SQL 来实现 if、choose、when、otherwise、foreach 等语句块。

6、MyBatis 中的 SQL 解析是如何实现的?
MyBatis 中的 SQL 解析是通过 OGNL(Object-Graph Navigation Language)表达式实现的。在映射文件或 Mapper 接口中,可以使用 OGNL 表达式来动态生成 SQL 语句和参数。OGNL 表达式可以访问 Java 对象和集合,以实现复杂的查询操作。

7、MyBatis 中的 TypeHandler 是什么?它的作用是什么
MyBatis 中的 TypeHandler 是用于实现 Java 类型与 JDBC 类型之间的转换的组件。它的作用是可以自定义数据类型的转换规则,从而实现更加灵活的数据映射。MyBatis 中内置了许多常见的 TypeHandler,同时也可以自定义 TypeHandler。

8、MyBatis 中的注解和 XML 配置文件有什么区别?它们的优缺点是什么?
MyBatis 中的注解和 XML 配置文件都可以用来配置 Mapper 接口和 SQL 语句。它们的区别在于,注解方式是通过 Java 代码来实现配置,而 XML 配置文件是通过 XML 文件来实现配置。注解方式相对于 XML 配置文件来说,更加简洁和方便,但是可读性和可维护性可能会差一些。XML 配置文件相对于注解方式来说,可读性和可维护性更好,但是相对繁琐一些。另外,注解方式不支持动态 SQL,而 XML 配置文件支持动态 SQL。

9、MyBatis 中的 Mapper 接口和 Mapper 映射文件是如何关联的?
在 MyBatis 中,Mapper 接口和 Mapper 映射文件是通过一个相同的命名空间来关联的。在 Mapper 接口中定义的方法名必须与 Mapper 映射文件中定义的语句的 id 属性值相同。同时,Mapper 映射文件中的 namespace 属性值必须与 Mapper 接口的全限定名相同。

10、MyBatis 中的事务是如何控制的?
在 MyBatis 中,事务是通过 SqlSession 来控制的。在默认情况下,MyBatis 中的事务是开启的,且事务的隔离级别为 REPEATABLE READ。如果需要自定义事务的隔离级别,可以在 SqlSessionFactory 中配置事务管理器和数据源,从而实现自定义事务的控制。另外,MyBatis 还提供了 @Transactional 注解来实现事务的控制,通过在方法上添加 @Transactional 注解来指定事务的隔离级别和传播行为。

11、#{}和${}的区别是什么?
${}是字符串替换,#{}是预处理;

Mybatis在处理${}时,就是把这个符号直接替换成变量的值。而Mybatis在处理#{}时,会对sql语句进行预处理,将sql中的#{}替换为?号,调用PreparedStatement的set方法来赋值;

使用#{}可以有效的防止SQL注入,提高系统安全性。

12、Mybatis的Xml映射文件中,不同的Xml映射文件,id是否可以重复?
不同的Xml映射文件,如果配置了namespace,那么id可以重复;如果没有配置namespace,那么id不能重复;

原因就是namespace+id是作为Map的key使用的,如果没有namespace,就剩下id,那么,id重复会导致数据互相覆盖。有了namespace,自然id就可以重复,namespace不同,namespace+id自然也就不同。

13、Mybatis是如何进行分页的?分页插件的原理是什么?
Mybatis使用RowBounds对象进行分页,它是针对ResultSet结果集执行的内存分页,而非物理分页。可以在sql内直接书写带有物理分页的参数来完成物理分页功能,也可以使用分页插件来完成物理分页。
分页插件的基本原理是使用Mybatis提供的插件接口,实现自定义插件,在插件的拦截方法内拦截待执行的sql,然后重写sql

14、Mybatis的一级、二级缓存?
MyBatis的缓存分为一级缓存和二级缓存,一级缓存是SqlSession级别的缓存,二级缓存是Mapper级别的缓存。

(1)一级缓存: 基于 PerpetualCache 的 HashMap 本地缓存,其存储作用域为 Session,当 Session flush 或 close 之后,该 Session 中的所有 Cache 就将清空,默认打开一级缓存。

(2)二级缓存与一级缓存其机制相同,默认也是采用 PerpetualCache,HashMap 存储,不同在于其存储作用域为 Mapper(Namespace),并且可自定义存储源,如 Ehcache。默认不打开二级缓存,要开启二级缓存,使用二级缓存属性类需要实现Serializable序列化接口(可用来保存对象的状态),可在它的映射文件中配置 ;

(3)对于缓存数据更新机制,当某一个作用域(一级缓存 Session/二级缓存Namespaces)的进行了C/U/D 操作后,默认该作用域下所有 select 中的缓存将被 clear 掉并重新更新,如果开启了二级缓存,则只根据配置判断是否刷新。

15、Mybatis是如何将sql执行结果封装为目标对象并返回的?都有哪些映射形式?
第一种是使用标签,逐一定义数据库列名和对象属性名之间的映射关系。

第二种是使用sql列的别名功能,将列的别名书写为对象属性名。

有了列名与属性名的映射关系后,Mybatis通过反射创建对象,同时使用反射给对象的属性逐一赋值并返回,那些找不到映射关系的属性,是无法完成赋值的。

16、使用MyBatis的mapper接口调用时有哪些要求?
Mapper接口方法名和mapper.xml中定义的每个sql的id相同;
Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql 的parameterType的类型相同;
Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同;
Mapper.xml文件中的namespace即是mapper接口的类路径。

17、请说说MyBatis的工作原理
在这里插入图片描述

1、 读取MyBatis配置文件:mybatis-config.xml为MyBatis的全局配置文件,配置了MyBatis的运;行环境等信息,例如数据库连接信息。
2、 加载映射文件映射文件即SQL映射文件,该文件中配置了操作数据库的SQL语句,需要在;MyBatis 配置文件 mybatis-config.xml 中加载。mybatis-config.xml 文件可以加载多个映射文件,每个文件对应数据库中的一张表。
3、 构造会话工厂:通过MyBatis的环境等配置信息构建会话工厂SqlSessionFactory;
4、 创建会话对象:由会话工厂创建SqlSession对象,该对象中包含了执行SQL语句的所有方法;
5、 Executor执行器:MyBatis底层定义了一个Executor接口来操作数据库,它将根据SqlSession;传递的参数动态地生成需要执行的 SQL 语句,同时负责查询缓存的维护。
6、 MappedStatement对象:在Executor接口的执行方法中有一个MappedStatement类型的参;数,该参数是对映射信息的封装,用于存储要映射的 SQL 语句的 id、参数等信息。
7、 输入参数映射:输入参数类型可以是Map、List等集合类型,也可以是基本数据类型和POJO类;型。输入参数映射过程类似于 JDBC 对 preparedStatement 对象设置参数的过程。
8、 输出结果映射:输出结果类型可以是Map、List等集合类型,也可以是基本数据类型和POJO类;型。输出结果映射过程类似于 JDBC 对结果集的解析过程。

18、Mybatis都有哪些Executor执行器?它们之间的区别是什么?
Mybatis有三种基本的Executor执行器,SimpleExecutor、ReuseExecutor、BatchExecutor。
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批处理相同。

19、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()方法的调用。这就是延迟加载的基本原理。

20、如何获取生成的主键
新增标签中添加:keyProperty=" ID " 即可

<insert id="insert" useGeneratedKeys="true" keyProperty="userId" >insert into user(user_name, user_password, create_time)values(#{userName},{userPassword} ,{createTime, jdbcType=TIMESTAMP})
</insert>
int id=mapper.insert(user)

21、简述Mybatis的插件运行原理,以及如何编写一个插件。
Mybatis仅可以编写针对ParameterHandler、ResultSetHandler、StatementHandler、Executor这4种接口的插件,Mybatis使用JDK的动态代理,为需要拦截的接口生成代理对象以实现接口方法拦截功能,每当执行这4种接口对象的方法时,就会进入拦截方法,具体就是InvocationHandler的invoke()方法,当然,只会拦截那些你指定需要拦截的方法。
实现Mybatis的Interceptor接口并复写intercept()方法,然后在给插件编写注解,指定要拦截哪一个接口的哪些方法即可,记住,别忘了在配置文件中配置你编写的插件。

22、MyBatis的乐观锁是怎么实现的?
MyBatis的乐观锁是通过版本号实现的,即在数据表中增加一个版本号字段。在更新时,比较版本号是否一致,如果一致才更新数据。

@Update("UPDATE user SET name = #{name}, version = #{version + 1} WHERE id = #{id} AND version = #{version}")
int updateUser(User user);

23、 MyBatis中如何处理存储过程?
可以使用select标签调用存储过程,使用resultMap映射输出参数。

<select id="callProcedure" statementType="CALLABLE" parameterType="Map">{call my_procedure(#{inputParam, mode=IN, jdbcType=INTEGER},#{outputParam, mode=OUT, jdbcType=VARCHAR})}
</select>

24、MyBatis的懒加载是什么?
懒加载是指在需要使用关联数据时才去加载,而不是在查询主体数据时就将关联数据一并加载。

<resultMap id="userResultMap" type="User"><id property="id" column="id"/><result property="name" column="name"/><result property="age" column="age"/><collection property="orders" ofType="Order" column="user_id" select="getOrdersByUserId" lazyLoading="true"/>
</resultMap>

25、MyBatis中如何处理返回多个结果集?
通过resultSets属性指定多个结果集。

<select id="getUserAndOrder" resultType="User" statementType="CALLABLE" parameterType="Map" resultSets="user,order">{call get_user_and_order(#{userId, mode=IN, jdbcType=INTEGER})}
</select>

26、MyBatis中如何实现动态更新?
使用标签可以方便地动态拼接更新字段。

UPDATE user name = #{name}, age = #{age}, WHERE id = #{id}

27、MyBatis 是如何处理枚举类型的?
MyBatis 可以通过实现 TypeHandler 接口来处理枚举类型。用户可以创建自定义的 TypeHandler,然后在 MyBatis 配置文件中指定这个自定义的类型处理器来对枚举类进行转换操作。

28、MyBatis 如何实现一对一关联查询?
可以通过联表查询或者嵌套查询来实现一对一映射。在 ResultMap 中使用 association 元素进行配置,确定对象之间的关联关系。

29、MyBatis 如何实现一对多关联查询?
通过在 ResultMap 中配置 collection 元素来实现一对多的映射。这可以根据一方的主键关联到多方的外键来实现。

可以关注,微信订阅号“猿来编码”的文章查看更多面试题或者其他工具分享

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

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

相关文章

Linux--进程控制(2)--进程的程序替换(夺舍)

目录 进程的程序替换 0.相关函数 1.先看现象 2.解释原理 3.将代码改成多进程版 4.使用其它的替换函数&#xff0c;并且认识函数参数的含义 5.其它 进程的程序替换 0.相关函数 关于进程替换我们需要了解的6个函数&#xff1a; 函数解释&#xff1a; 这些函数如果调用成功则…

通过filebeat实现对docker服务的通用日志收集

平台 依赖 linux docker docker-compose 或者 docker compose 镜像 docker.elastic.co/beats/filebeat:8.12.2 docker.elastic.co/beats/kibana:8.12.2 docker.elastic.co/beats/elasticsearch:8.12.2 正文 背景 对于有自建机房的公司来说&#xff0c;如果公司的运维技术…

Stable Diffusion使用ControlNet:IP-Adapter实现图片风格迁移

IP-Adapter 全称是 Text Compatible Image Prompt Adapter for Text-to-Image Diffusion Models&#xff08;文本到图像扩散模型的文本兼容图像提示适配器&#xff09;&#xff0c;是腾讯研究院出品的一个新的ControlNet模型&#xff0c;旨在使预训练的文本到图像扩散模型能够生…

【06】JAVASE-数组讲解【从零开始学JAVA】

Java零基础系列课程-JavaSE基础篇 Lecture&#xff1a;波哥 Java 是第一大编程语言和开发平台。它有助于企业降低成本、缩短开发周期、推动创新以及改善应用服务。如今全球有数百万开发人员运行着超过 51 亿个 Java 虚拟机&#xff0c;Java 仍是企业和开发人员的首选开发平台。…

最全GPTs使用教程+Prompt预设词教程

使用指南 直接复制使用 可以前往已经添加好Prompt预设的AI系统测试使用&#xff08;可自定义添加使用&#xff09; https://ai.sparkaigf.com 现已支持GPTs 雅思写作考官 我希望你假定自己是雅思写作考官&#xff0c;根据雅思评判标准&#xff0c;按我给你的雅思考题和对应…

从零入门区块链和比特币(第三期)

欢迎来到我的区块链与比特币入门指南&#xff01;如果你对区块链和比特币感兴趣&#xff0c;但不知道从何开始&#xff0c;那么你来对地方了。本博客将为你提供一个简明扼要的介绍&#xff0c;帮助你了解这个领域的基础知识&#xff0c;并引导你进一步探索这个激动人心的领域。…

一些基础知识FK

1. 群体稳定性指数PSI 通过 PSI(Population Stability Index) 指标&#xff0c;可以得到不同样本下&#xff0c;模型在各分数段分布的稳定性。用于衡量两个群体(比如两个时间点、两个子群体等)之间稳定性的指标。通常PSI被用于评估信用风险模型、预测模型等在不同时间点或不同群…

安装配置Maven(idea里面配置)

放在这个路径下&#xff08;如果需要可以免费发给你&#xff0c;dd我就好了&#xff09; D:\IearnSoftware\maven\apache-maven-3.6.1-bin.zip&#xff08;我自己的路径下面&#xff0c;防止忘记&#xff09; 1.首先测试maven在不在&#xff0c;配置对不对 mvn -v 这样就是成…

STM32HAL库++ESP8266+cJSON连接阿里云物联网平台

实验使用资源&#xff1a;正点原子F1 USART1&#xff1a;PA9P、A10&#xff08;串口打印调试&#xff09; USART3&#xff1a;PB10、PB11&#xff08;WiFi模块&#xff09; DHT11&#xff1a;PG11&#xff08;采集数据、上报&#xff09; LED0、1&#xff1a;PB5、PE5&#xff…

【微信小程序调用百度API实现图像识别实战】-前后端加强版

前言&#xff1a;基于前面两篇图像识别项目实战文章进行了改造升级。 第一篇 入门【微信小程序调用百度API实现图像识别功能】----项目实战 第二篇 前后端结合 【微信小程序调用百度API实现图像识别实战】----前后端分离 这一篇主要讲述的是在第二篇的基础上新增意见反馈功能&a…

第72天:漏洞发现-Web框架中间件联动GobyAfrogXrayAwvsVulmap

案例一&#xff1a;某 APP-Web 扫描-常规&联动-Burp&Awvs&Xray Acunetix 一款商业的 Web 漏洞扫描程序&#xff0c;它可以检查 Web 应用程序中的漏洞&#xff0c;如 SQL 注入、跨站脚本攻击、身份验证页上的弱口令长度等。它拥有一个操作方便的图形用户界 面&#…

实验8 NAT配置

实验8 NAT配置 一、 原理描述二、 实验目的三、 实验内容1.实验场景2.实验要求 四、 实验配置五、 实验步骤2.静态NAT配置3.NAT Outbound配置4.NAT Easy-IP配置 一、 原理描述 2019年11月26日&#xff0c;全球43亿个IPv4地址正式耗尽&#xff0c;这意味着没有更多的IPv4地址可…

Taro引入echarts【兼容多端小程序(飞书/微信/支付宝小程序)】

近期接到公司新需求&#xff0c;开发飞书小程序&#xff0c;并且原型中含有大量的图表&#xff0c;本想使用飞书内置图表组件 —— chart-space&#xff0c;但官方表示已经停止维护了&#xff0c;无奈之下&#xff0c;只能另寻他路&#xff0c;于是乎&#xff0c;图表之王&…

【Godot4.2】自定义Todo清单类 - myTodoList

概述 在写myList类的时候&#xff0c;就想到可以写一个类似的Todo清单类。 基础思路 本质还是在内部维护一个数组&#xff0c;在其基础上进行增删改查操作的封装为了方便存储数据&#xff0c;编写一个自定义内置类TodoItem&#xff0c;内部数组就变成了Array[TodoItem]类型的…

【Flutter】GetX

前言 状态管理 / 路由管理 / 依赖管理 这三部分之间存在联系 参考文章 建议看官网文章&#xff0c;很详细 &#xff0c;pub.dev搜索get pub.dev的文档 状态管理文章相关链接 状态管理 案例 实现一个计算器&#xff0c;运用GetX去管理它 构建界面 构建一个计算器界面 …

GateWay具体的使用之全链路跟踪TraceId日志

1.创建全局过滤器&#xff0c;在请求头上带入traceId参数&#xff0c;穿透到下游服务. package com.by.filter;import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.jwt.JWTValidator;…

数据结构1(初):时间复杂度和空间复杂度

目录 1、引言 1.1、什么是数据结构&#xff1f; 1.2、什么是算法&#xff1f; 1.3、如何学好数据结构和算法 &#xff1f; 2、算法效率 2.1、如何衡量一个算法的好坏 2.2、算法的复杂度 3、时间复杂度 3.1、时间复杂度的概念 3.2、大O的渐进表示法 3.3、常见时间复杂…

C语言自定义类型【联合体与枚举】

文章目录 1.联合体1.1联合体的声明1.2联合体的特点1.3联合体的大小计算联合体的使用案例 2.枚举2.1枚举类型的声明2.2枚举类型的优点(为什么使用枚举)2.3枚举类型的使用 结语 1.联合体 1.1联合体的声明 和结构体一样&#xff0c;联合体也是由一个或多个成员构成&#xff0c;同…

Atcoder Beginner Contest351 A-E Solution题解

文章目录 [A - The bottom of the ninth](https://atcoder.jp/contests/abc351/tasks/abc351_a)[B - Spot the Difference ](https://atcoder.jp/contests/abc351/tasks/abc351_b)[D - Grid and Magnet](https://atcoder.jp/contests/abc351/tasks/abc351_d)E Note&#xff1a;…

Rust 实战练习 - 12. Axum Web 简单demo

Rust Web 历程 Rust 的异步框架tokio非他莫属&#xff0c;而web框架一直是悬而未决&#xff0c;说到底还是因为没有官方成熟的方案指引&#xff0c;大家各玩各的&#xff0c;互不兼容&#xff0c;白白浪费精力。 这个事情一直等到半官方组织tokio推出axum有了改善。但是市场上…