MyBatis:从入门到进阶

📌 摘要

在 Java 后端开发中,MyBatis 是一个非常流行且灵活的持久层框架。它不像 Hibernate 那样完全封装 SQL,而是提供了对 SQL 的精细控制能力,同时又具备 ORM(对象关系映射)的功能。

本文将带你从 MyBatis 基础语法高级特性 全面掌握这一持久层利器,内容涵盖:

  • MyBatis 简介与核心优势
  • 快速入门示例(XML 和 注解方式)
  • 映射文件详解(resultMap、动态SQL等)
  • 与 Spring / Spring Boot 整合实战
  • 性能优化技巧与最佳实践
  • 常见面试题解析

适合初学者入门和中高级开发者提升技能。

  • 🔥 MyBatis中文网地址

🎯 一、为什么选择 MyBatis?

✅ MyBatis 的特点:

特性描述
轻量级无侵入性,无需继承特定类或实现接口
SQL 控制强手写 SQL,便于性能调优
ORM 支持自动将结果集映射为 Java 对象
动态 SQL提供 <if><foreach> 等强大标签
可扩展性强支持自定义类型处理器、插件机制
与主流框架兼容完美支持 Spring、Spring Boot

❗ 适用场景:

  • 对 SQL 有较高要求,需要定制化查询
  • 数据结构复杂、需频繁优化性能
  • 不希望被 Hibernate 的“黑盒”束缚
  • 企业项目中已有大量 SQL 脚本迁移需求

🧱 二、MyBatis 核心组件介绍

组件描述
SqlSessionFactoryBuilder构建 SqlSessionFactory 工厂对象
SqlSessionFactory创建 SqlSession 实例的核心工厂
SqlSession执行 SQL 语句并获取映射结果的主要接口
Mapper XML 文件定义 SQL 语句和结果映射规则
Mapper 接口通过接口绑定 XML 中的 SQL
Configuration全局配置对象,包含数据源、事务管理器等信息

🚀 三、快速入门:搭建第一个 MyBatis 应用

✅ 开发环境准备:

  • JDK 1.8+
  • Maven 3.x
  • MySQL 5.7+
  • IDE(如 IntelliJ IDEA)

1. 添加依赖(Maven):

<!-- MyBatis -->
<dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.10</version>
</dependency><!-- MySQL驱动 -->
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.29</version>
</dependency>

2. 配置 mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//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.cj.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/test_db?useSSL=false&amp;serverTimezone=UTC"/><property name="username" value="root"/><property name="password" value="123456"/></dataSource></environment></environments><mappers><mapper resource="mapper/UserMapper.xml"/></mappers>
</configuration>

3. 编写实体类 User.java

public class User {private Integer id;private String name;private String email;// Getter/Setter
}

4. Mapper 接口 UserMapper.java

public interface UserMapper {User selectById(Integer id);
}

5. Mapper XML 文件 UserMapper.xml

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

6. 测试类 TestMyBatis.java

public class TestMyBatis {public static void main(String[] args) throws IOException {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.selectById(1);System.out.println(user.getName());}}
}

🛠️ 四、MyBatis 进阶功能详解

1. resultMap 结果映射

适用于字段名与属性名不一致的情况:

<resultMap id="userResultMap" type="User"><id property="id" column="user_id"/><result property="name" column="user_name"/><result property="email" column="email"/>
</resultMap><select id="selectAllUsers" resultMap="userResultMap">SELECT user_id, user_name, email FROM users
</select>

2. 动态 SQL

<if> 条件判断:
<select id="findUsers" parameterType="map" resultType="User">SELECT * FROM users<where><if test="name != null">AND name LIKE CONCAT('%', #{name}, '%')</if><if test="email != null">AND email = #{email}</if></where>
</select>
<choose>/<when>/<otherwise> 分支判断:
<choose><when test="name != null">AND name = #{name}</when><when test="email != null">AND email = #{email}</when><otherwise>AND status = 1</otherwise>
</choose>
<foreach> 遍历集合:
<delete id="deleteByIds">DELETE FROM users WHERE id IN<foreach collection="ids" item="id" open="(" separator="," close=")">#{id}</foreach>
</delete>

🔗 五、与 Spring / Spring Boot 整合实战

1. Spring Boot + MyBatis 快速整合

添加依赖:
<dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>3.0.3</version>
</dependency>
application.yml 配置:
spring:datasource:url: jdbc:mysql://localhost:3306/test_db?useSSL=false&serverTimezone=UTCusername: rootpassword: 123456driver-class-name: com.mysql.cj.jdbc.Drivermybatis:mapper-locations: classpath:mapper/*.xmltype-aliases-package: com.example.model
Mapper 接口自动注入:
@Mapper
public interface UserMapper {@Select("SELECT * FROM users WHERE id = #{id}")User selectById(Integer id);
}

🚀 六、MyBatis 高级特性与优化技巧

✅ 使用 PageHelper 分页插件:

<dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper-spring-boot-starter</artifactId><version>1.4.2</version>
</dependency>

使用示例:

PageHelper.startPage(1, 10);
List<User> users = userMapper.selectAll();
PageInfo<User> pageInfo = new PageInfo<>(users);

✅ 自定义 TypeHandler 类型转换器

public class BooleanTypeHandler implements TypeHandler<Boolean> {@Overridepublic void setNonNullParameter(PreparedStatement ps, int i, Boolean parameter, JdbcType jdbcType) {ps.setInt(i, parameter ? 1 : 0);}@Overridepublic Boolean getNullableResult(ResultSet rs, String columnName) throws SQLException {return rs.getInt(columnName) == 1;}
}

✅ 使用 MyBatis 插件(Interceptor)

可用于日志记录、分页、SQL 监控等。

@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})})
public class MyInterceptor implements Interceptor {@Overridepublic Object intercept(Invocation invocation) throws Throwable {// 前置处理逻辑System.out.println("Before executing SQL");// 执行原方法Object result = invocation.proceed();// 后置处理逻辑System.out.println("After executing SQL");return result;}@Overridepublic Object plugin(Object target) {return Plugin.wrap(target, this);}@Overridepublic void setProperties(Properties properties) {// 可以获取配置的属性}
}

💬 七、常见面试题解析

Q1: MyBatis 和 Hibernate 的区别?

答:Hibernate 是全自动 ORM 框架,屏蔽 SQL;MyBatis 是半自动 ORM,需手动编写 SQL,更灵活可控。

Q2: #{} 和 ${} 的区别?

答:#{} 是预编译占位符,防止 SQL 注入;${} 是字符串替换,存在注入风险。

Q3: 如何实现批量插入?

答:使用 <foreach> 标签拼接多条 INSERT 语句,或结合 JDBC 的批处理。

Q4: 如何防止 N+1 查询问题?

答:使用 <association><collection> 嵌套查询,并启用延迟加载(lazyLoadingEnabled)。

Q5: MyBatis 如何实现缓存?

答:一级缓存默认开启(SqlSession级别),二级缓存需手动配置(Mapper级别)。


💡 八、总结

通过本文的学习,你应该已经掌握了:

  • MyBatis 的基本原理与使用方式
  • 如何使用 XML 或注解方式进行 CRUD 操作
  • 动态 SQL 的编写技巧
  • resultMap 的使用与映射优化
  • 与 Spring / Spring Boot 的整合方法
  • 高级特性如分页、插件、自定义类型处理器
  • 常见面试题解析

MyBatis 是 Java 持久层开发中的利器,既能保持灵活性,又能兼顾开发效率,是构建高性能后端系统的首选之一。



  • 如果你在学习过程中遇到任何疑问,欢迎在评论区留言交流!
  • 👍 如果你觉得这篇文章对你有帮助,别忘了点赞、收藏、转发哦!

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

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

相关文章

leetcode51.N皇后:回溯算法与冲突检测的核心逻辑

一、题目深度解析与N皇后问题本质 题目描述 n皇后问题研究的是如何将n个皇后放置在nn的棋盘上&#xff0c;并且使皇后彼此之间不能相互攻击。给定一个整数n&#xff0c;返回所有不同的n皇后问题的解决方案。每一种解法包含一个明确的n皇后问题的棋子放置方案&#xff0c;该方…

算法-每日一题(DAY9)杨辉三角

1.题目链接&#xff1a; 118. 杨辉三角 - 力扣&#xff08;LeetCode&#xff09; 2.题目描述&#xff1a; 给定一个非负整数 numRows&#xff0c;生成「杨辉三角」的前 numRows 行。 在「杨辉三角」中&#xff0c;每个数是它左上方和右上方的数的和。 示例 1: 输入: numRo…

【MATLAB代码】制导方法介绍与例程——追踪法,适用于二维平面,目标是移动的|附完整源代码

追踪法(追踪导引法)是一种常见的导弹导引方式,其基本原理是保持导弹的速度矢量始终指向目标。在追踪法中,导弹的加速度可以表示为指向目标的加速度。 本文给出二维平面下,移动目标的追踪法导引的介绍、公式与matlab例程 订阅专栏后,可以直接查看完整源代码 文章目录 运行…

小白的进阶之路系列之十八----人工智能从初步到精通pytorch综合运用的讲解第十一部分

从零开始的NLP:使用序列到序列网络和注意力机制进行翻译 我们将编写自己的类和函数来预处理数据以完成我们的 NLP 建模任务。 在这个项目中,我们将训练一个神经网络将法语翻译成英语。 [KEY: > input, = target, < output]> il est en train de peindre un table…

SSL安全证书:数字时代的网络安全基石

SSL安全证书&#xff1a;数字时代的网络安全基石 在当今数字化浪潮中&#xff0c;网络通信安全已成为个人、企业和组织不可忽视的核心议题。SSL&#xff08;Secure Sockets Layer&#xff0c;安全套接层&#xff09;安全证书作为保障数据传输安全的关键技术&#xff0c;通过加…

LLM-201: OpenHands与LLM交互链路分析

一、核心交互链路架构 #mermaid-svg-ZBqCSQk1PPDkIXNx {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-ZBqCSQk1PPDkIXNx .error-icon{fill:#552222;}#mermaid-svg-ZBqCSQk1PPDkIXNx .error-text{fill:#552222;strok…

【项目】仿muduo库one thread one loop式并发服务器SERVER模块(下)

&#x1f4da; 博主的专栏 &#x1f427; Linux | &#x1f5a5;️ C | &#x1f4ca; 数据结构 | &#x1f4a1;C 算法 | &#x1f152; C 语言 | &#x1f310; 计算机网络 |&#x1f5c3;️ mysql 项目文章&#xff1a; 仿muduo库one thread one loop式并发服务器…

数据库索引结构 B 树、B + 树与哈希索引在不同数据查询场景下的适用性分析

一、数据库索引结构B树 树概述 树是一种多路平衡查找树&#xff0c;广泛应用于数据库和文件系统中。B树的节点可以存储多个数据元素&#xff0c;并且保持树的平衡&#xff0c;以提高查询效率。 适用性分析 在数据量较大&#xff0c;范围查找较多的场景下&#xff0c;B树的查询效…

Linux进程间通信——信号

1.信号的介绍 信号( Signal )是 Unix, 类Unix以及其他POSIX兼容的操作系统中进程间通信的一种有限制的手段。 1&#xff09;信号是在软件层面上对中断机制的一种模拟&#xff0c;是一种异步通信方式。2&#xff09;信号可以直接进行用户空间进程和内核进程之间的交互&#xff…

Bytemd@Bytemd/react详解(编辑器实现基础AST、插件、跨框架)

ByteMD Markdown编辑器详细解释&修改编辑器默认样式&#xff08;高度300px) AST树详解 [ByteMD 插件系统详解(https://blog.csdn.net/m0_55049655/article/details/148811248?spm1001.2014.3001.5501) Sevelet编写的Bytemd如何适配到React中 ⚡️1️⃣ 背景概述 Byte…

《Redis》事务

文章目录 Redis中的原子性Redis的事物和MySQL事务的区别Redis实现事务什么场景下&#xff0c;会使用事务? Redis事务相关命令watch命令的实现原理 总结 Redis中的原子性 Redis的原子性不同于MySQL的原子性。 Redis的事物和MySQL事务的区别 但是注意体会Redis的事务和MySQL…

Elasticsearch Kibana (一)

一、官方文档 elasticsearch官网&#xff1a;elasticsearch官网 elasticsearch源码&#xff1a;elasticsearch源码 ik分词器&#xff1a; ik分词器 ik分词器下载&#xff1a;ik分词器下载 elasticsearch 版本选择&#xff1a;elasticsearch 版本选择 官方推荐Elasticsearch和j…

[linux] Ubuntu 24软件下载和安装汇总(自用)

经常重装系统&#xff0c;备份下&#xff0c;有用的也可以参考。 安装图形界面 apt install ubuntu-desktop systemctl set-default graphical.target reboot 安装chrome wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb sudo apt insta…

分布变化的模仿学习算法

与传统监督学习不同,直接模仿学习在不同时刻所面临的数据分布可能不同.试设计一个考虑不同时刻数据分布变化的模仿学习算法 import numpy as np import torch import torch.nn as nn import torch.optim as optim from torch.utils.data import DataLoader, TensorDataset from…

arm-none-eabi-ld: cannot find -lm

arm-none-eabi-ld -Tuser/hc32l13x.lds -o grbl_hc32l13x.elf user/interrupts_hc32l13x.o user/system_hc32l13x.o user/main.o user/startup_hc32l13x.o -lm -Mapgrbl_hc32l13x.map arm-none-eabi-ld: cannot find -lm makefile:33: recipe for target link failed 改为在gcc…

【Python办公】Excel文件批量样式修改器

目录 专栏导读1. 背景介绍2. 项目概述3. 库的安装4. 核心架构设计① 类结构设计② 数据模型1) 文件管理2) 样式配置5. 界面设计与实现① 布局结构② 动态组件生成6. 核心功能实现① 文件选择与管理② 颜色选择功能③ Excel文件处理核心逻辑完整代码结尾专栏导读 🌸 欢迎来到P…

QT的一些介绍

//虽然下面一行代码进行widget和ui的窗口关联&#xff0c;但是如果发生窗口大小变化的时候&#xff0c;里面的布局不会随之变化ui->setupUi(this);//通过下面这行代码进行显示说明&#xff0c;让窗口变化时&#xff0c;布局及其子控件随之变化this->setLayout(ui->ver…

RISC-V向量扩展与GPU协处理:开源加速器设计新范式——对比NVDLA与香山架构的指令集融合方案

点击 “AladdinEdu&#xff0c;同学们用得起的【H卡】算力平台”&#xff0c;H卡级别算力&#xff0c;按量计费&#xff0c;灵活弹性&#xff0c;顶级配置&#xff0c;学生专属优惠 当开源指令集遇上异构计算&#xff0c;RISC-V向量扩展&#xff08;RVV&#xff09;正重塑加速…

自动恢复网络路由配置的安全脚本说明

背景 两个文章 看了就明白 Ubuntu 多网卡路由配置笔记&#xff08;内网 外网同时通 可能有问题&#xff0c;以防万一可以按照个来恢复 sudo ip route replace 192.168.1.0/24 dev eno8403 proto kernel scope link src <你的IP>或者恢复脚本! 如下 误操作路由时&…

创建 Vue 3.0 项目的两种方法对比:npm init vue@latest vs npm init vite@latest

创建 Vue 3.0 项目的两种方法对比&#xff1a;npm init vuelatest vs npm init vitelatest Vue 3.0 作为当前主流的前端框架&#xff0c;官方提供了多种项目创建方式。本文将详细介绍两种最常用的创建方法&#xff1a;Vue CLI 方式 (npm init vuelatest) 和 Vite 方式 (npm in…