MyBatis从入门到面试:掌握持久层框架的精髓

前言

在Java企业级应用开发中,持久层框架的选择至关重要。MyBatis作为一款优秀的半自动化ORM框架,以其灵活的SQL定制能力和良好的性能表现,成为了众多开发者的首选。本文将带你从MyBatis的基础入门开始,逐步深入核心概念,最后为你准备面试常见问题,助你全面掌握MyBatis。

一、MyBatis入门篇

1.1 什么是MyBatis?

MyBatis是一款优秀的持久层框架,它支持自定义SQL、存储过程以及高级映射。MyBatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集的工作,可以通过简单的XML或注解来配置和映射原始类型、接口和Java POJO为数据库中的记录。

1.2 环境搭建与配置

首先,我们需要在项目中引入MyBatis依赖:

<dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.7</version>
</dependency>

接下来创建MyBatis的核心配置文件mybatis-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" 
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><environments default="development"><environment id="development"><transactionManager type="JDBC"/><dataSource type="POOLED"><property name="driver" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/test"/><property name="username" value="root"/><property name="password" value="password"/></dataSource></environment></environments><mappers><mapper resource="com/example/mapper/UserMapper.xml"/></mappers>
</configuration>

1.3 第一个MyBatis程序

创建实体类:

public class User {private Long id;private String name;private String email;// 构造方法、getter和setter省略
}

创建Mapper接口:

public interface UserMapper {User selectUserById(Long id);
}

创建Mapper XML文件:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.mapper.UserMapper"><select id="selectUserById" resultType="com.example.entity.User">SELECT * FROM user WHERE id = #{id}</select>
</mapper>

使用MyBatis API执行查询:

public class MyBatisExample {public static void main(String[] args) {String resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);try (SqlSession session = sqlSessionFactory.openSession()) {UserMapper mapper = session.getMapper(UserMapper.class);User user = mapper.selectUserById(1L);System.out.println(user.getName());}}
}

二、MyBatis核心概念解析

2.1 SqlSessionFactory与SqlSession

  • SqlSessionFactory:每个MyBatis应用都以一个SqlSessionFactory实例为核心,它是线程安全的,一旦创建应在应用运行期间一直存在
  • SqlSession:代表一次数据库会话,不是线程安全的,每个线程都应该有它自己的SqlSession实例

2.2 Mapper接口与XML映射文件

MyBatis通过动态代理技术将Mapper接口与XML映射文件关联起来:

// Mapper接口
public interface UserMapper {@Insert("INSERT INTO user(name, email) VALUES(#{name}, #{email})")@Options(useGeneratedKeys = true, keyProperty = "id")int insertUser(User user);@Select("SELECT * FROM user WHERE id = #{id}")User selectUserById(Long id);
}

或者使用XML配置:

<mapper namespace="com.example.mapper.UserMapper"><insert id="insertUser" parameterType="com.example.entity.User"useGeneratedKeys="true" keyProperty="id">INSERT INTO user(name, email) VALUES(#{name}, #{email})</insert>
</mapper>

2.3 动态SQL

MyBatis提供了强大的动态SQL功能:

<select id="findUsers" parameterType="map" resultType="User">SELECT * FROM user<where><if test="name != null">AND name LIKE CONCAT('%', #{name}, '%')</if><if test="email != null">AND email = #{email}</if><choose><when test="orderBy == 'name'">ORDER BY name</when><otherwise>ORDER BY id</otherwise></choose></where>
</select>

2.4 结果映射

MyBatis支持复杂的结果映射:

<resultMap id="userResultMap" type="User"><id property="id" column="id"/><result property="name" column="name"/><result property="email" column="email"/><collection property="posts" ofType="Post"><id property="id" column="post_id"/><result property="title" column="post_title"/><result property="content" column="post_content"/></collection>
</resultMap>

三、MyBatis高级特性

3.1 插件开发

MyBatis允许用户使用插件拦截的方法调用包括:

  • Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)
  • ParameterHandler (getParameterObject, setParameters)
  • ResultSetHandler (handleResultSets, handleOutputParameters)
  • StatementHandler (prepare, parameterize, batch, update, query)

示例:实现一个简单的SQL执行时间统计插件

@Intercepts({@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}),@Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class})
})
public class SqlExecuteTimeInterceptor implements Interceptor {@Overridepublic Object intercept(Invocation invocation) throws Throwable {long start = System.currentTimeMillis();Object result = invocation.proceed();long end = System.currentTimeMillis();System.out.println("执行耗时: " + (end - start) + "ms");return result;}@Overridepublic Object plugin(Object target) {return Plugin.wrap(target, this);}@Overridepublic void setProperties(Properties properties) {}
}

3.2 缓存机制

MyBatis提供两级缓存:

  • 一级缓存:SqlSession级别的缓存,默认开启
  • 二级缓存:Mapper级别的缓存,需要手动配置开启
<!-- 在Mapper XML中开启二级缓存 -->
<cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true"/>

3.3 类型处理器

自定义类型处理器处理特殊数据类型:

public class StringArrayTypeHandler extends BaseTypeHandler<String[]> {@Overridepublic void setNonNullParameter(PreparedStatement ps, int i, String[] parameter, JdbcType jdbcType) throws SQLException {ps.setString(i, String.join(",", parameter));}@Overridepublic String[] getNullableResult(ResultSet rs, String columnName) throws SQLException {String value = rs.getString(columnName);return value != null ? value.split(",") : null;}// 其他方法省略
}

四、MyBatis面试常见问题

4.1 基础概念类

1. MyBatis和Hibernate有什么区别?

  • MyBatis是半自动ORM框架,需要手动编写SQL;Hibernate是全自动框架,自动生成SQL
  • MyBatis更灵活,适合复杂查询和性能优化场景;Hibernate开发效率更高,适合传统CRUD操作
  • MyBatis学习曲线较平缓;Hibernate学习曲线较陡峭

2. #{}和${}的区别是什么?

  • #{}是预编译处理,可以有效防止SQL注入
  • ${}是字符串替换,有SQL注入风险,一般用于order by等非值替换场景

4.2 高级特性类

1. MyBatis的插件运行原理是什么?

MyBatis使用责任链模式,通过动态代理组织多个插件。当执行目标方法时,会按照插件配置的顺序依次调用插件的intercept方法。

2. MyBatis如何实现分页?

  • 物理分页:使用RowBounds或分页插件(如PageHelper)
  • 逻辑分页:使用ResultSet的absolute方法,但数据量大时性能较差

4.3 性能优化类

1. MyBatis如何进行批量操作?

try (SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH)) {UserMapper mapper = session.getMapper(UserMapper.class);for (int i = 0; i < 1000; i++) {User user = new User("name" + i, "email" + i);mapper.insertUser(user);}session.commit();
}

2. 如何优化MyBatis查询性能?

  • 合理使用缓存
  • 使用延迟加载
  • 优化SQL语句
  • 使用连接池
  • 避免N+1查询问题

五、总结

MyBatis作为一个灵活、高效的持久层框架,在现代Java开发中占据重要地位。通过本文的学习,你应该已经掌握了MyBatis从基础使用到高级特性的核心知识,并为面试做好了充分准备。记住,框架只是工具,真正重要的是理解其背后的设计思想和原理,这样才能在实际项目中灵活运用,解决复杂问题。

希望这篇博客对你有所帮助,祝你学习进步,面试顺利!


延伸阅读

  • MyBatis官方文档
  • MyBatis-Spring整合指南
  • MyBatis Generator代码生成器

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

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

相关文章

5.Three.js 学习(基础+实践)

Three.js 是 “WebGL 的封装库”&#xff0c;帮你屏蔽了底层的着色器 / 缓冲区细节&#xff0c;专注于 “3D 场景搭建”&#xff0c;开发效率高&#xff0c;是通用 3D 开发的首选。他的核心是 “场景 - 相机 - 渲染器” 的联动逻辑&#xff0c;先掌握基础组件&#xff0c;再学进…

消火栓设备工程量计算 -【图形识别】秒计量

消火栓设备工程量计算 -【图形识别】秒计量 消防系统的消火栓设备水枪、水带和消火栓组成&#xff0c;根据清单定额规则计算消火栓设备工程量。通过CAD快速看图的图形识别框选图纸就能自动数出消火栓数量&#xff0c;省时又准确&#xff0c;是工程人做消防算量的好帮手。 一、…

Docker 与 VSCode 远程容器连接问题深度排查与解决指南

Docker 与 VSCode 远程容器连接问题深度排查与解决指南 引言 Visual Studio Code 的 Remote - Containers 扩展极大地提升了开发体验&#xff0c;它将开发环境容器化&#xff0c;保证了环境的一致性&#xff0c;并允许开发者像在本地一样在容器内进行编码、调试和运行。然而&…

爱图表:镝数科技推出的智能数据可视化平台

本文转载自&#xff1a;https://www.hello123.com/aitubiao ** 一、✨ AI 图表&#xff1a;智能数据可视化好帮手 爱图表是镝数科技旗下的一款智能数据可视化工具&#xff0c;它能让复杂的数字和报表变得直观又好懂。接入了先进的DeepSeek 系列 AI 模型&#xff0c;它不仅会做…

ENVI系列教程(四)——图像几何校正

目录 1 概述 1.1 控制点选择方式 1.2 几何校正模型 1.3 控制点的预测与误差计算 2 详细操作步骤 2.1 扫描地形图的几何校正 2.1.1 第一步:打开并显示图像文件 2.1.2 第二步:启动几何校正模块 2.2 Landsat5 影像几何校正 2.2.1 第一步:打开并显示图像文件 2.2.2 第…

STM32-FreeRTOS操作系统-消息队列

引言在嵌入式开发领域&#xff0c;STM32与FreeRTOS的结合应用极为广泛。本文将探讨如何在STM32上使用FreeRTOS实现消息队列功能&#xff0c;助力高效任务通信与系统协作。消息队列定义消息队列是一种在 FreeRTOS 中用于任务间通信的机制。它允许任务将消息发送到队列中&#xf…

【开题答辩全过程】以 C语言程序设计课程网站为例,包含答辩的问题和答案

个人简介一名14年经验的资深毕设内行人&#xff0c;语言擅长Java、php、微信小程序、Python、Golang、安卓Android等开发项目包括大数据、深度学习、网站、小程序、安卓、算法。平常会做一些项目定制化开发、代码讲解、答辩教学、文档编写、也懂一些降重方面的技巧。感谢大家的…

手机上有哪些比较好用的待办事项提醒工具

在快节奏的现代工作中&#xff0c;我们每天都要面对大量的任务与事务。从项目截止日期、客户会议&#xff0c;到日常的工作安排&#xff0c;琐碎的事项容易让人顾此失彼。 手机待办事项工具早已突破传统“记事本”的局限&#xff0c;成为移动办公场景下的效率核心。它们通过任务…

Mysql数据库事务全解析:概念、操作与隔离级别

MySQL系列 文章目录MySQL系列一、什么是事务1.1事务的核心概念1.2、 事务的四大属性&#xff08;ACID&#xff09;1.2.1 原子性&#xff08;Atomicity&#xff09;1.2.2 一致性&#xff08;Consistency&#xff09;1.2.3 隔离性&#xff08;Isolation&#xff09;1.2.4 持久性&…

【MCU EEPROM开发教程】

简单来说把eeprom芯片当成一个传感器来使用&#xff0c;通过IIC/SPI等协议对芯片进行读写操作&#xff0c;具体的读写操作涉及到一些算法—怎么样读写更加快速&#xff0c;以及一些异常错误处理。 应用场景&#xff1a; 对于一些掉电也不能丢失的数据要存在eeprom/flash中&…

Docker将镜像搬移到其他服务上的方法

导出/加载镜像&#xff08;保留分层、标签&#xff09;和导出/导入容器快照&#xff08;仅文件系统&#xff0c;丢失镜像历史与标签&#xff09;。 一、把镜像打包带走&#xff08;推荐&#xff09; 适合把一个或多个镜像搬到离线/内网机器&#xff0c;保留分层与标签。 在源服…

Ubuntu 系统安装 Miniconda 完整方法与注意事项

一、完整安装步骤 1. 下载 Miniconda 安装包 Miniconda 安装包为 .sh 格式脚本,下载途径分两种: 方式 1:浏览器下载(适合新手) 访问 Miniconda 官方下载页,选择对应系统版本(Ubuntu 选 Miniconda3-latest-Linux-x86_64.sh),默认保存到用户目录的 ~/Downloads 文件夹…

【后端】数据库四大范式详细解析

梳理一下 MySQL&#xff08;或关系型数据库&#xff09;中的第一、二、三、四范式&#xff0c;这是数据库设计中非常重要的规范化理论。1️⃣ 第一范式 (1NF&#xff1a;First Normal Form)定义&#xff1a;字段具有原子性&#xff0c;不可再分。数据表中每一列都必须是不可分割…

HarmonyOS后台任务调度:JobScheduler与WorkManager实战指南

本文将深入探讨HarmonyOS 5&#xff08;API 12&#xff09;中的后台任务调度机制&#xff0c;重点讲解JobScheduler和WorkManager的使用方法、适用场景及最佳实践&#xff0c;帮助开发者实现高效、智能的后台任务管理。 1. 后台任务调度概述 HarmonyOS提供了两种主要的后台任务…

Prompt工程实践

你在写prompt时候&#xff0c;是不是总觉得大模型它不听话。要么答非所问、要么一堆废话。扒开思考过程仔细阅读时而觉得它聪明绝顶&#xff0c;时而又觉得它愚蠢至极。明明已经对了怎么又推理到错的地方去了&#xff0c;明明在提示词中提醒过了不要这么思考它怎么就瞎想了。这…

基于springboot的毕业旅游一站式定制系统

博主介绍&#xff1a;java高级开发&#xff0c;从事互联网行业六年&#xff0c;熟悉各种主流语言&#xff0c;精通java、python、php、爬虫、web开发&#xff0c;已经做了多年的设计程序开发&#xff0c;开发过上千套设计程序&#xff0c;没有什么华丽的语言&#xff0c;只有实…

输入1.8V~5.5V 输出28V DCDC升压芯片TLV61046A

今天来一款TI的升压芯片TLV61046A。输入电压范围1.8V~5.5V。最高可以输出28V。开关电流980mA&#xff0c;那具体能输出多大的电流就得看输入输出的电压了。以上面的输入3.6V输出12V为例&#xff0c;效率是85%&#xff0c;那最高可以输出的电流就差不多只有200mA左右。封装也是非…

ubuntu22.04源码安装ffmpeg-4.4

# ubuntu22.04源码安装ffmpeg-4.4cd /tmpwget https://ffmpeg.org/releases/ffmpeg-4.4.6.tar.xztar -xvf ffmpeg-4.4.6.tar.xzcd ffmpeg-4.4.6apt updateapt install -y yasm pkg-config libx264-dev libx265-dev libvpx-dev libfdk-aac-dev libmp3lame-dev libopus-dev libav…

Pyhon中字符串常用的函数

一、字符串的格式化1.format()方法format()是 Python 中用于字符串格式化的方法&#xff0c;通过占位符&#xff08;如 {}&#xff09;动态插入变量或表达式。name小明 age18 grade99.556245585 information"我是{}&#xff0c;今年{}岁了,考试得分&#xff1a;{:.2f}&quo…

小迪安全v2023学习笔记(八十一讲)—— 框架安全ThinkPHPLaravelStruts2SpringBootCVE复现

文章目录前记服务攻防——第八十一天开发框架安全&SpringBoot&Struts2&Laravel&ThinkPHP&CVE复现开发框架 - 常见语言开发框架PHP - 框架安全-Thinkphp&LaravelLaravel漏洞介绍漏洞复现CVE-2021-3129ThinkPHP漏洞介绍漏洞复现CVE-2018-1002015QVD-2022…