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 的一些常用方法主要集中在 SqlSession
和 Mapper
中。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 接口可以简化代码,不需要手动调用 selectOne
、selectList
等方法。通过 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 执行的各个阶段(如 Executor
、StatementHandler
、ParameterHandler
、ResultSetHandler
)插入自定义逻辑。实现插件需要创建类并实现 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 默认不会自动提交事务,需要手动管理。可以通过 SqlSession
的 commit()
和 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 持久层框架,主要用于简化 SQL 数据库操作。它的设计初衷是通过 XML 或注解的方式配置和执行 SQL 语句,使得数据库操作更加灵活、方便和高效。相比于传统的 JDBC,MyBatis 提供了一些关键优势&…...

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

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

HTML 基础概念:什么是 HTML ? HTML 的构成 与 HTML 基本文档结构
文章目录 什么是 HTML ?HTML 的构成 ?什么是 HTML 元素?HTML 元素的组成部分HTML 元素的特点 HTML 基本文档结构如何打开新建的 HTML 文件代码查看 什么是 HTML ? HTML(超文本标记语言,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)模型房价数据空间分析
原文链接:https://tecdat.cn/?p38077 本文主要探讨了贝叶斯分层模型在分析区域数据方面的应用,以房价数据为例,详细阐述了如何帮助客户利用R进行模型拟合、分析及结果解读,展示了该方法在处理空间相关数据时的灵活性和有效性。&a…...

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

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

【人工智能-初级】练习题: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实现的蓝天幼儿园管理系统是为幼儿园提供的一套管理平台,可以提高幼儿园信息管理的准确性,系统将信息…...

nvm详解
本文借鉴转载于 nvm文档手册 文章目录 1.nvm是什么?2.nvm安装2.1 window上安装下载链接安装步骤 2.2 Mac上安装使用homebrew 安装 nvm 3.nvm使用指令 1.nvm是什么? nvm(Node Version Manager)是一个用于管理和切换不同版本 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)分词2)索引3)存储 1.3.3 常用的Field种类 1.4 分词…...

11.3笔记
在C#中,静态类和普通类(实例类)有一些关键的区别: 实例化: 普通类:可以被实例化,即创建对象。每个对象都有自己的状态和方法。静态类:不能被实例化,它们不包含构造函数&a…...
数据结构之线段树
线段树 线段树(Segment Tree)是一种高效的数据结构,广泛应用于计算机科学和算法中,特别是在处理区间查询和更新问题时表现出色。以下是对线段树的详细解释: 一、基本概念 线段树是一种二叉搜索树,是算法竞…...

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

iframe视频宽度高度自适应( pc+移动都可以用,jq写法 )
注意:要引入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 分发简介
作者:来自 Elastic Alexander Wert•Miguel Luna•Bahubali Shetti Elastic 自豪地推出了 Elastic Distributions of OpenTelemetry (EDOT),其中包含 Elastic 版本的 OpenTelemetry Collector 和多种语言 SDK,如 Python、Java、.NET 和 NodeJ…...

golang的RSA加密解密
参考: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…...

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

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

数据结构 —— 红黑树
目录 1. 初识红黑树 1.1 红黑树的概念 1.2 红⿊树的规则 1.3 红黑树如何确保最长路径不超过最短路径的2倍 1.4 红黑树的效率:O(logN) 2. 红黑树的实现 2.1 红黑树的基础结构框架 2.2 红黑树的插⼊ 2.2.1 情况1:变色 2.2.2 情况2:单旋变色 2.2…...

《功能高分子学报》
《功能高分子学报》 中国标准连续出版物号:CN 31-1633/O6,国际标准连续出版物号:ISSN 1008-9357,邮发代号:4-629,刊期:双月刊。 《功能高分子学报》主要刊登功能高分子和其他高分子领域具有创新意义的学术…...

Linux特种文件系统--tmpfs文件系统
tmpfs类似于RamDisk(只能使用物理内存),使用虚拟内存(简称VM)子系统的页面存储文件。tmpfs完全依赖VM,遵循子系统的整体调度策略。说白了tmpfs跟普通进程差不多,使用的都是某种形式的虚拟内存&a…...

《基于STMF103的FreeRTOS内核移植》
目录 1.FreeRTOS资料下载与出处 1.1官网下载,网址:www.freertos.org 1.2在正点原子官网,任意STM32F1的开发板资料A盘里, 2.FreeRTOS移植重要文件讲解 2.1 FreeRTOS与FreeRTOS-Plus文件夹 2.2 Demo、Lincence、Source ●Demo文件…...

一七二、Vue3性能优化方式
Vue 3 的性能优化相较于 Vue 2 有了显著提升,利用新特性和改进方法可以更高效地构建和优化应用。以下是 Vue 3 的常见性能优化方法及示例。 1. 使用组合式 API (Composition API) Vue 3 引入的组合式 API,通过逻辑拆分和复用来实现更高效的代码组织和性…...

软件测试--BUG篇
博主主页: 码农派大星. 数据结构专栏:Java数据结构 数据库专栏:MySQL数据库 JavaEE专栏:JavaEE 软件测试专栏:软件测试 关注博主带你了解更多知识 目录 1. 软件测试的⽣命周期 2. BUG 1. BUG 的概念 2. 描述bug的要素 3.bug级别 4.bug的⽣命周期 5 与开发产⽣争执怎…...

Scikit-learn和Keras简介
一,Scikit-learn是一个开源的机器学习库,用于Python编程语言。它建立在NumPy、SciPy和matplotlib这些科学计算库之上,提供了简单有效的数据挖掘和数据分析工具。Scikit-learn库包含了许多用于分类、回归、聚类和降维的算法,包括支…...

python在word的页脚插入页码
1、插入简易页码 import win32com.client as win32 from win32com.client import constants import osdoc_app win32.gencache.EnsureDispatch(Word.Application)#打开word应用程序 doc_app.Visible Truedoc doc_app.Documents.Add() footer doc.Sections(1).Footers(cons…...

Java面试题十四
一、Java中的JNI(Java Native Interface)是什么?它有什么用途? Java中的JNI(Java Native Interface)是Java提供的一种编程框架,它允许Java代码与本地(Native)代码&#x…...

yarn : 无法加载文件,未对文件 进行数字签名。无法在当前系统上运行该脚本。
执行这个命令时报错:yarn --registryhttps://registry.npm.taobao.org yarn : 无法加载文件 C:\Users\Administrator\AppData\Roaming\npm\yarn.ps1。未对文件 C:\Users\Administ rator\AppData\Roaming\npm\yarn.ps1 进行数字签名。无法在当前系统上运行该脚本。有…...