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

news2024/11/29 1:53:31

在这里插入图片描述

文章目录

  • 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.coloradmin.cn/o/1825156.html

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

相关文章

【最新鸿蒙应用开发】——关于鸿蒙MVVM模式的理解

MVVM模式 MVVM&#xff08;Model-View-ViewModel&#xff09;是一种软件设计模式&#xff0c;主要用于分离应用程序的用户界面&#xff08;UI&#xff09;和业务逻辑。这种模式可以帮助开发者更高效地开发和管理复杂的用户界面。 程序的状态数据通常包含了数组、对象&#xff0…

Linux内存从0到1学习笔记(8.15 MMU/IOMMU/SMMU概览)

一, 什么是MMU? MMU(Memory Management Unit 内存管理单元),即内存管理单元,是计算机硬件中的一个重要组件,主要负责处理中央处理器(CPU)的内存访问请求。 其工作原理如下: 当程序发出内存访问请求,包括读取或写入操作以及逻辑地址(虚拟地址)。然后,MMU根据页表…

自动化测试git的使用

git是一款分布式的配置管理工具。本文主要讲git如何在自动化测试中安装&#xff0c;上传及拉取下载代码。 1 、git 介绍 每天早上到公司&#xff0c;从公司的git服务器上下载最新的代码&#xff0c;白天在最新的代码基础上&#xff0c;编写新的代码&#xff0c;下班时把“代码…

[Java基本语法] 异常

&#x1f338;个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 &#x1f3f5;️热门专栏:&#x1f355; Collection与数据结构 (92平均质量分)https://blog.csdn.net/2301_80050796/category_12621348.html?spm1001.2014.3001.5482 &#x1f9c0;线程与…

Linux 内核 (十二)进程间通讯 之 消息队列

前言 这个系列的上一篇介绍了进程间通讯关于管道相关的内容及代码实例,本章要介绍关于消息队列相关的内容. 消息队列交互图示 函数原型 #include <sys/msg.h> #include <sys/ipc.h> //创建 or 打开队列 成功返回队列ID,失败返回-1 int msgget(key_t key,int fla…

探索AIGC与3D技术的融合:从图像到可探索的3D动态场景

随着人工智能和计算机图形技术的飞速发展,AIGC(人工智能生成内容)与3D技术的结合正在为我们打开一扇全新的创意之门。最近,我深入研究了几个令人兴奋的AIGC+3D方案,它们不仅展示了从单张图片或文本提示生成3D点云的强大能力,还进一步实现了AI虚拟试穿和生成高保真3D数字人…

Qt信号槽的回调机制

问&#xff1a;Qt强大的地方在哪里&#xff1f; 答&#xff1a;跨平台、信号槽。。。 问&#xff1a;信号槽是什么&#xff1f; 答&#xff1a;回调函数 问&#xff1a;怎么个回调法子 答&#xff1a;。。。 成果 信号槽本身实现过程是有些复杂的&#xff0c;所以本人参考…

CDN绕过技术

DNS域名信息收集 简介 Dns域名信息的手机&#xff0c;需要收集域名对应IP&#xff0c;域名注册人&#xff0c;DNS记录&#xff0c;子域名等一系列与域名相关的信息。 Cdn技术简介 Cdn是一个内容分发网络&#xff0c;类似于dns服务器一样&#xff0c;用户发送数据直接发送到…

AI Assistant 2024 震撼登场:AI补全功能惊艳来袭,替换GitHub Copilot Chat最友好的方式!

哈喽!欢迎来到程序视点。 前言 在之前的文章中&#xff0c;我们提到过“JetBrains 2024.1 中&#xff0c;AI Assistant 插件已被解绑&#xff0c;现在作为单独的插件在 JetBrains IDE 中可用”。 这一变化的驱动力是&#xff0c;需要在使用 AI 驱动的技术时提供更大的决策灵活…

【C语言习题】30.使用指针打印数组内容

文章目录 作业标题作业内容2.解题思路3.具体代码 作业标题 使用指针打印数组内容 作业内容 写一个函数打印arr数组的内容&#xff0c;不使用数组下标&#xff0c;使用指针。 arr是一个整形一维数组。 2.解题思路 先定义一个数组&#xff0c;使用指针打印数组内容那就是说我们…

linux驱动学习(八)之内核定制与裁剪

一、内核的配置 1) 把相关硬件平台的配置文件拷贝给.config 2) 执行make menuconfig命令 关于内核配置说明:Arrow keys navigate the menu. 方向键对菜单有效<Enter> selects submenus --->. 如果有该符号"--->",则按Enter表示进入子菜单Highlighted …

可视化图表:如此高颜值柱状图,其实简单配置就能实现。

这不又有某个boss给我图截图一些柱状性图表&#xff0c;说他们的前端觉得很难&#xff0c;说了一堆技术术语&#xff0c;他也不懂&#xff0c;截图我看到后&#xff0c;就给了他一个网址&#xff0c;马上就解决了。 在这里给大家摘录出几个比较有特色的柱状图出来&#xff0c;让…

【网络安全学习】使用Kali做渗透情报收集-01-<域名信息主机信息>

1.收集开源情报 开源情报(Open Source Intelligence&#xff0c;OSINT)是指从各种公开的渠道中寻找和获取有价值的信息 如&#xff1a;互联网、媒体、社交网络、公共数据库等开源情报具有以下特点&#xff1a; - 丰富性&#xff1a;开源情报涵盖了各种类型和领域的信息 - 可…

香橙派鲲鹏Pro(orange pi kunpeng) 开箱测试,和在娱乐功能(电视盒子),深度机器学习应用方面的测试报告

摘要 对Orange Pi kunpeng这个开发板进行综合评测&#xff0c;特别关注其作为电视盒子的性能以及在深度学习应用中的算力和稳定性。通过一个月的测试&#xff0c;我们评估了其硬件性能、软件兼容性、用户体验和实际应用潜力 引言 5月份&#xff0c;我收到了csdn 对Orange P…

论文阅读笔记:Instance-Aware Dynamic Neural Network Quantization

论文阅读笔记&#xff1a;Instance-Aware Dynamic Neural Network Quantization 1 背景2 创新点3 方法4 模块4.1 网络量化4.2 动态量化4.3 用于动态量化的位控制器4.4 优化 5 效果 论文&#xff1a;https://openaccess.thecvf.com/content/CVPR2022/papers/Liu_Instance-Aware_…

班子考核评价的重要性与实施方法

在组织管理领域&#xff0c;班子考核评价是一项至关重要的工作&#xff0c;它不仅关系到组织的发展方向和速度&#xff0c;更直接影响到组织的凝聚力和战斗力。一个科学、公正、有效的班子考核评价体系&#xff0c;能够准确反映班子的工作成效&#xff0c;激励班子成员积极作为…

前后端分离对于后端来说,是利好还是利弊呢?

前后端分离已经成为前端开发的主流模式&#xff0c;这种模式极大的解放了后端&#xff0c;让后端人员不再即当爹又当妈了&#xff0c;那么这种模式对于后端来说是利好还是利弊呢&#xff0c;如何趋利避害呢&#xff0c;贝格前端工场为大家分享一下。 一、什么前后端分离的开发…

新一代大核卷积反超ViT和ConvNet!同参数量下性能、精度、速度完胜

大核卷积网络是CNN的一种变体&#xff0c;也是深度学习领域的一种重要技术&#xff0c;它使用较大的卷积核来处理图像数据&#xff0c;以提高模型对视觉信息的理解和处理能力。 这种类型的网络能够捕捉到更多的空间信息&#xff0c;因为它的大步长和大感受野可以一次性覆盖图像…

ORB算法特征提取

声明&#xff1a;学习过程中的知识总结&#xff0c;欢迎批评指正。 ORB算法提取两路输入图像&#xff08;图像A&#xff0c;图像B&#xff09;的特征点&#xff0c;根据提取的特征点进行特征匹配得到特征对。 ​ 图像金字塔 因为在现实世界中&#xff0c;同一个物体可能会以…