【2024最新精简版】MyBatis面试篇

在这里插入图片描述

文章目录

  • mybatis内部实现过程
  • mybatis延迟加载
  • 请说说MyBatis的工作原理
  • mybatis接口里的方法,参数不同时能重载吗
  • mybatis分页插件的原理是什么?
  • mybatis的一级、二级缓存👍
  • mybatis如何实现多表查询
  • mybatis如何实现批量插入👍
  • mybatis动态SQL标签有哪些👍
  • Mybatis和MybatisPlus有什么区别
  • 什么是ORM框架 ,你了解的ORM框架有哪些 ?

更多相关内容可查看

mybatis内部实现过程

加载账套 ,然后通过创建SqlSessionFactory,获取SqlSession对象,通过mapper接口代理,动态加载账套类别等
根据账套信息动态选择环境

public User getUserByIdAndAccount(String accountId, int userId) {String environmentId = determineEnvironmentId(accountId);SqlSessionFactory sqlSessionFactory = getSqlSessionFactory(environmentId);try (SqlSession sqlSession = sqlSessionFactory.openSession()) {UserMapper userMapper = sqlSession.getMapper(UserMapper.class);return userMapper.getUserById(userId);}}

mybatis延迟加载

延迟加载通常用于加载关联的对象或集合,以避免在检索主对象时立即检索其关联对象,特别是当关联对象的数量很大时。延迟加载允许在需要时按需加载关联对象,而不是在查询主对象时就全部加载。
在MyBatis中,可以通过以下两种方式实现延迟加载:

  1. select标签的fetchType属性:
    • 在MyBatis的映射文件中,可以使用fetchType属性来指定关联对象或集合的加载方式。
    • 可以设置fetchType属性为lazy,表示延迟加载;设置为eager表示立即加载(默认值)。
xml<select id="selectBlog" resultType="Blog" fetchType="lazy">select * from blog where id = #{id}
</select>

请说说MyBatis的工作原理

image.png

  1. 加载mybatis核心配置文件mybatis-config.xml
  2. 加载mybatis映射配置文件XxxMapper.xml , 映射配置文件里面就是定义好的SQL语句
  3. 创建会话工厂对象SqlSesssionFactory
  4. 使用会话工厂创建 SqlSession 对象,该对象中包含了执行 SQL 语句的所有方法
  5. 根据 SqlSession 传递的参数调用Executor执行器动态地生成需要执行的 SQL 语句
  6. Executor执行器使用MappedStatement 完成对请求参数映射 , 底层使用preparedStatement完成对SQL语句的预编译 , 封装参数
  7. Executor执行器执行SQL获取ResultSet结果集 , 根据接口所定义的返回类型底层使用反射完成结果集封装 , 返回查询结果

mybatis接口里的方法,参数不同时能重载吗

mybatis接口里的方法,是不能重载的,因为mybatis在执行的时候 , 是通过接口的全限定类名 + 方法名定位要执行的Statement , 如果进行重载就会出现冲突

mybatis分页插件的原理是什么?

分页插件的基本原理是使用Mybatis提供的插件接口,实现自定义插件,在插件的拦截方法内拦截待执行的sql,然后重写sql,根据dialect方言,添加对应的物理分页语句和物理分页参数
举例:select * from student,拦截sql后重写为:select t.* from (select * from student) t limit 0, 10

插件的本质是一个Interceptor 拦截器 , 可以在mybatis在映射语句执行过程中的某一点进行拦截调用。默认情况下,MyBatis 允许使用插件来拦截的方法调用包括:

  • Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed) : SQL执行
  • ParameterHandler (getParameterObject, setParameters) : 参数设置
  • ResultSetHandler (handleResultSets, handleOutputParameters) : 结果集封装
  • StatementHandler (prepare, parameterize, batch, update, query) : SQL语句预编译

myabtis分页插件的底层就是一个自定义的PageInterceptor , 拦截查询语句的执行 , 在SQL语句后面自动拼接分页参数
image.png

mybatis的一级、二级缓存👍

一级缓存是 SqlSession 级别的缓存。在操作数据库时需要构造 SqlSession 对象,在对象中有一个数据结构(HashMap)用于存储缓存数据。不同的是 SqlSession 之间的缓存数据区(HashMap)是互相不影响
二级缓存是 Mapper 级别的缓存,多个 SqlSession 去操作同一个 Mapper 的 sql 语句,多个 SqlSession 可以共用二级缓存,二级缓存是跨 SqlSession 的

需要注意的是 :
mybatis中一级缓存默认开启 , 二级缓存需要使用配置开启 , 设置cacheEnabled=true开启二级缓存

  • 当SqlSession执行查询时,如果查询语句开启了二级缓存并且缓存中有对应数据,则直接从缓存中获取数据,不再访问数据库。
  • 如果缓存中没有对应数据,则SqlSession会去数据库执行查询,并将结果放入缓存。
  • 当SqlSession执行更新、插入或删除操作时,会清空相关的二级缓存,以保持数据的一致性。

mybatis如何实现多表查询

mybatis中实现多表查询的方案常见的有两种 :
第一种方式 : 编写多表语句查询多表数据 , 使用<ResultMap>标签中的associationcollection标签做一对一和一对多结果集映
例如 : 查询用户信息以及用户的账户信息image.png

<!--定义结果集映射-->
<resultMap id="UserAccountMap" type="User"><id column="id" property="id"></id><result column="username" property="username"></result><result column="birthday" property="birthday"></result><result column="sex" property="sex"></result><result column="address" property="address"></result><!--配置一对多映射,一个用户可以有多个账户--><collection property="accounts" ofType="Account" ><id column="aid" property="id"></id><result column="id" property="uid"></result><result column="money" property="money"></result></collection>
</resultMap><!--定义查询的sql语句-->
<select id="findAllWithAccount" resultMap="UserAccountMap" >select u.*,a.id aid,a.MONEY  from  user u inner join account a on u.id = a.uid
</select>

第二种方式 : 编写多条查询语句, 分别查询多张表的数据 , 使用使用<ResultMap>标签中的associationcollection标签做一对一和一对多结果集映
例如 : 查询账户信息, 以及账户所属的用户信息

<!-- 建立对应关系 -->
<resultMap type="account" id="AccountUserMap"><id column="aid" property="id"/><result column="uid" property="uid"/><result column="money" property="money"/> <!-- 它是用于指定从表方的引用实体属性的 --><association property="user" javaType="user" select="com.itheima.dao.UserDao.findById"column="uid"></association>
</resultMap><!--定义SQL语句-->
<select id="findAll" resultMap="AccountUserMap">select  * from account
</select>
<!--定义查询的sql语句-->
<select id="findById" resultMap="User"  parameterType="int" >select *  from  user  where id = #{id }
</select>

mybatis如何实现批量插入👍

Mybatis批量插入的方式有三种 :

  1. 普通插入 : 遍历insert语句,单条执行,效率低下
  2. 使用foreach 插入 : 使用foreach标签将多条数据拼接到一条SQL语句中 , 一次性插入到数据库
<insert id="batchInsert" parameterType="java.util.List">insert into table1 (field1, field2) values<foreach collection="list" item="t" index="index" separator=","> (#{t.field1}, #{t.field2})</foreach>
</insert>

需要注意的是 :
当插入数量很多时,不能一次性全放在一条语句里 , 之前测试过当表的列数较多(20+)以及一次性插入的行数较多(5000+)时,整个插入的耗时十分漫长,达到了14分钟
原因是因为当拼接的数据比较多 , SQL中存在大量的占位符需要解析 , 对于占位符的解析和参数设置需要消耗大量的时间
如果非要使用 foreach 的方式来进行批量插入的话,可以考虑减少一条 insert 语句中 values 的个数 , 一般按经验来说,一次性插20~50行数量是比较合适的
此外Mysql 对执行的SQL语句大小进行限制,默认允许最大SQL是 4M , SQL大小超过4M会报错

  1. 使用ExecutorType.BATCH插入

mybatis内置的ExecutorType有3种,SIMPLE、REUSE、BATCH; 默认的是simple,这个模式下它为每个语句的执行创建一个新的预处理语句,单条提交sql;而batch模式重复使用已经预处理的语句,并且批量执行所有更新语句,batch性能更好一些 , 配置方式 :

mybatis:configuration:default-executor-type: batch # 开启批处理模式

需要注意的是 : 进行jdbc批处理时需在JDBC的url中加入rewriteBatchedStatements=true
同时batch模式也有自己的问题,比如在Insert操作时,在事务没有提交之前,是没有办法获取到自增的id的
建议有大批量数据需要插入的情况下使用BATCH模式 , 效率最高

mybatis动态SQL标签有哪些👍

  1. 基本的增删改查标签 , 例如 : <insert>,<select>,<update>,<delete>
  2. 语义处理标签 , 例如 : where,set
  3. 进行条件判断的标签 , 例如 : <if test="条件">,<choose> .... <when>...<otherwise>
<!-- if标签 : 条件判断 -->
<select id="selectByUsername" resultType="User">SELECT * FROM t_user WHERE 1 = 1<if test="status != null">AND status = #{status}</if><if test="username != null and username != ''">AND username = #{username}</if>
</select><!--<choose> .... <when>...<otherwise> 标签, 类似与 : switch 语句 -->
<select id="selectByUsername" resultType="User">SELECT * FROM t_user WHERE 1 = 1<choose><when test="status != null">AND status = #{status}</when><otherwise>AND username = #{username}</otherwise></choose>
</select>
  1. 遍历循环标签 , 例如 : <foreach collection="遍历的集合" item="遍历每一项" index="索引" open="遍历开始字符" close="遍历结束字符" separator="遍历分割符号" >
<select id="selectInIdList" resultType="User">SELECT * FROM t_user<foreach item="item" index="index" collection="idList" open="id IN (" separator="," close=")" nullable="true">#{item}</foreach>
</select>
  1. <script>标签 : 可以在注解中使用动态SQL
public interface UserSqlMapper {@Select("<script>" +"SELECT * FROM t_user" +"<where>" +"   <if test='status != null'>AND status = #{status}</if>" +"   <if test='username != null'>AND username = #{username}</if>" +"</where>" +"</script>")List<User> selectByUser(User user);
}
  1. <sql>标签 : 定义SQL片段 , 可以使用include进行引入, 实现SQL复用
<!--定义SQL片段-->
<sql id="userColumns"> id,username,password </sql><select id="selectUsers" resultType="map">select<!--引用SQL片段--><include refid="userColumns"></include>from user 
</select>

Mybatis和MybatisPlus有什么区别

Mybatis是一个基于XML配置文件和SQL语句的ORM框架。它提供了基本的SQL映射、缓存管理等持久化功能 , Mybatis PlusMybatis的基础上进行了扩展,提供了更多功能特性,如分页插件、代码生成器、注解支持 , 多数据源插件等
Mybatis在进行数据持久化时需要编写大量的XML配置文件SQL语句 , Mybatis Plus则使用注解和API的方式进行数据持久化,使得编码更加便捷和简洁
Mybatis Plus在功能扩展的同时也对性能进行了优化,提供了高效的SQL语句构建和执行能力,并支持动态SQL语句生成,从而提高了应用的性能和效率。
总的来说,Mybatis Plus就是一个Mybatis的增强工具提供了更加强大的功能扩展 , 在使用Mybatis Plus的同时也可以使用Mybatis中所提供的一些功能 , 完全没有影响

什么是ORM框架 ,你了解的ORM框架有哪些 ?

ORM又叫对象关系映射 , 建立实体对象和数据库表之间的映射关系。开发者操作对象就相当于操作数据库 , 自动生成相关的SQL语句实现对数据库的操作
常见ORM框架:

  1. Hibernate(Nhibernate):Hibernate是最早的Java ORM框架之一,支持将对象映射到关系数据库中。提供了自动映射、事务管理、连接管理等功能。
  2. MyBatis:MyBatis提供了更加灵活的SQL语句编写方式,支持动态SQL语句生成和参数绑定等功能。是一个半自动化的ORM框架。
  3. Mybatis Plus:Mybatis Plus是在MyBatis的基础上扩展而来的ORM框架,它提供了更多的功能特性,如分页插件、代码生成器、注解支持等。
  4. JPA(Java Persistence API):JPA提供了一种统一的持久化操作方式。许多ORM框架都实现了JPA规范,如Hibernate

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

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

相关文章

关于使用pycharm中控制台运行代码错误之FileNotFoundError: [Errno 2] No such file or directory:

在使用pycharm环境下复现《python编程&#xff1a;从入门到实践》这本书第16.1.1内容中分析csv文件头一节的代码时出现如下问题&#xff1a; 1、文章中使用的数据来源问题 直接参考本站Kenny C同学的文章提供内容即可。 https://github.com/kenidi8215/Hello-World 打开网页&a…

Java面试题--JVM大厂篇之掌握JVM性能优化:选择合适的垃圾回收器

掌握JVM性能优化&#xff1a;选择合适的垃圾回收器 引言: ​  在Java开发中&#xff0c;性能优化往往是提高应用稳定性和用户体验的关键所在。而垃圾回收器的选择和优化&#xff0c;是JVM性能调优的核心环节。如何在众多垃圾回收器中选出适合自己应用需求的那一个&#xff1…

Docker笔记-Debian容器内搭建ssh服务

登陆容器之后修改密码&#xff1a; passwd 密码设置完成后安装openssh-server apt-get install openssh-server 修改端口号为50022并添加配置 vim /etc/ssh/sshd_config 修改成 Port 50022 PasswordAuthentication yes PermitRootLogin yes 启动 rootlinux:~# /etc/in…

cve_2017_12635-CouchDB垂直权限绕过

1.采用参考 https://www.cnblogs.com/mlxwl/p/16577781.html vulfocus&#xff1a;Vulfocus 漏洞威胁分析平台 2.产生原因 在2017年11月15日&#xff0c;CVE-2017-12635和CVE-2017-12636披露&#xff0c;CVE-2017-12635是由于Erlang和JavaScript对JSON解析方式的不同&#…

照明灯具哪个品牌好,一文详细带你了解照明灯具种类有哪些

在孩子学习过程中&#xff0c;有一样物品的重要性不容忽视&#xff0c;那就是一盏提供舒适光源的照明灯具。那么照明灯具哪个品牌好&#xff1f;面对不断增加的学业负担&#xff0c;孩子们经常需要在夜晚借助台灯的光亮进行学习&#xff0c;这已经成为了家庭生活中普遍的情景。…

Vue34-销毁流程

一、销毁流程预览 二、vm.$destroy()函数的调用&#xff0c;开始销毁流程 一个应用只有一个vm&#xff0c;但是一个vm会管理一堆组件实例对象&#xff08;和vm很像&#xff1a;微型的vm&#xff09;。 销毁流程中解绑的事件监听器&#xff0c;是自定义事件&#xff0c;不是原…

uni app 自定义 带popup弹窗的input组件

工作需要。自定义了个带popup弹窗的input组件。此组件满足个人需求&#xff0c;不喜勿喷。应该可以看明白怎么回事&#xff0c;也能自己改改&#xff0c;所以就不要联系了&#xff0c;点赞收藏就好 <template><view class"dialog_main"><input v-mod…

这份简历让一位程序员在谷歌获得30万美元

大家好&#xff0c;我是弗雷。每次都在让大家尝试走出职场&#xff0c;但今天我们却选择再次走进职场。 作为曾经的职场人&#xff0c;我深深明白简历的敲门砖作用&#xff0c;制作一份优质的简历至关重要。 你所见过的最优秀的简历是什么样子&#xff1f; 或者你想象中最优秀…

chatgpt的命令词

人不走空 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌赋&#xff1a;斯是陋室&#xff0c;惟吾德馨 目录 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌…

ABBYY Finereader 15软件下载及安装教程

ABBYY FineReader 是一款功能强大的 OCR&#xff08;Optical Character Recognition&#xff09;软件&#xff0c;可以将扫描的文档转换为可编辑的文本文件。它不仅可以识别文本&#xff0c;还可以识别表格、图像和布局&#xff0c;使得文档的转换更加准确和方便。 安 装 包 获…

Opus从入门到精通(五)OggOpus封装器全解析

Opus从入门到精通(五)OggOpus封装器全解析 为什么要封装 前面Opus从入门到精通(四)Opus解码程序实现提到如果不封装会有两个问题: 无法从文件本身获取音频的元数据(采样率,声道数,码率等)缺少帧分隔标识,无法从连续的文件流中分隔帧(尤其是vbr情况) 针对上面的问题我们可以…

算法day31

第一题 542. 01 矩阵 本题本来求解的是每一个1到0的最短距离并返回到矩阵之中&#xff1b; 我们采用正难则反的思路&#xff0c;将其化解为每一个0到每一个1的最短距离&#xff0c;并通过矩阵来返回&#xff1b; 解法&#xff1a;多源bfs正难则反 步骤一&#xff1a; 定义一个…

换卡槽=停机?新手机号使用指南!

刚办理的手机号莫名其妙的就被停用了&#xff1f;这到底是怎么回事&#xff1f;这篇文章快来学习一下吧。 ​ 先说一下&#xff0c;你的手机为什么被停机&#xff1f; 现在运营商对于手机卡的使用有着非常严格的要求&#xff0c;尤其是刚办理的新号码&#xff0c;更是“严上加…

【2024算力大会分会 | SPIE独立出版 | 往届均已完成EI检索】2024云计算、性能计算与深度学习国际学术会议(CCPCDL 2024)

【2024算力大会分会 | SPIE出版】 2024云计算、性能计算与深度学习国际学术会议(CCPCDL 2024) 2024 International conference on Cloud Computing, Performance Computing and Deep Learning *CCPCDL往届均已完成EI检索&#xff0c;最快会后4个半月完成&#xff01; 一、…

算法金 | 再见!!!K-means

大侠幸会&#xff0c;在下全网同名「算法金」 0 基础转 AI 上岸&#xff0c;多个算法赛 Top 「日更万日&#xff0c;让更多人享受智能乐趣」 今天我们来聊聊达叔 6 大核心算法之 —— k-means 算法。最早由斯坦福大学的 J. B. MacQueen 于 1967 年提出&#xff0c;后来经过许多…

进口二手RS FSH4规格3.6G罗德与施瓦茨 FSH6参数

Rohde & Schwarz FSH4 的规格包括&#xff1a; 频率范围从 9 kHz 到 3.6 GHz 高灵敏度&#xff08;<-141dBm&#xff08;1Hz&#xff09;&#xff0c;或使用可选前置放大器<-161dBm&#xff08;1Hz&#xff09;&#xff09; 低测量不确定度&#xff08; 内部跟踪发生…

SpringCloud 前端-网关-微服务-微服务间实现信息共享传递

目录 1 网关获取用户校验信息并保存至请求头&#xff08;前端-网关&#xff09; 2 微服务获取网关中的用户校验信息&#xff08;网关-微服务&#xff09; 2.1 一般的做法是在公共的module中添加&#xff0c;此处示例为common 公共配置module中添加 2.2 定义拦截器 2.3 定义…

简易五子棋

简介 使用Java实现简易五子棋 规则介绍 游戏使用一个标准的1515方格的棋盘&#xff0c;双方分别用黑白两种颜色的棋子进行对战。黑子先行&#xff0c;双方轮流在空棋盘的交叉点上落子&#xff0c;每人一次只能落一子。游戏的目标是让自己的五颗棋子连成一线&#xff0c;这条…

一分钟制作爆火的治愈插画,让插画来替你说出心声

超火的AI治愈插画来了&#xff0c;有趣的文字搭配上有趣的图&#xff0c;无论是发朋友圈还是发小红书&#xff0c;这效果简直无敌。 下面是我刚生成的&#xff0c;快来看看效果吧。 这个工具&#xff0c;国内可用&#xff0c;可以直接上手&#xff0c;不需要什么技术&#xff0…

C# Winform 侧边栏,切换不同页面

在项目中我们经常遇到需要在主界面上切换不同子页面的需求&#xff0c;常用做法是左侧显示子页面菜单&#xff0c;用户通过点击左侧菜单&#xff0c;实现右边子页面的展示。 实例项目实现&#xff1a; 项目左侧侧边栏实现FlowLayoutPanel使用显示不同子窗体 实例链接&#xf…