Java 持久层框架 MyBatis 全面详解(附带Idea添加对应的XML文件模板教程)

Java 持久层框架 MyBatis 全面详解(附带Idea添加对应的XML文件模板教程)

一、介绍

MyBatis 是一款持久层框架,原名为 iBatis,2010 年由 Apache 迁移到 Google Code 并更名,2013 年又迁移到 GitHub。它消除了几乎所有的 JDBC 代码、手动设置参数和获取结果集的操作,通过XML 或注解的方式将 SQL 与 Java 代码解耦,支持自定义 SQL、存储过程和高级映射,是 Java 生态中主流的 ORM(对象关系映射)框架之一。

特点:

  1. 轻量级 & 灵活:相比 Hibernate 等全自动化 ORM 框架,MyBatis 不强制封装所有 SQL,允许开发者手写 SQL,适配复杂业务场景(如多表联查、复杂条件筛选)。
  2. SQL 与代码解耦:SQL 可集中管理在 XML 文件中,便于维护和优化(DBA 可直接修改 SQL 无需改动代码)。
  3. 强大的映射能力:支持一对一、一对多、多对多等复杂关系映射,无需手动封装结果集。
  4. 减少 JDBC 冗余代码:自动处理连接获取、参数设置、结果集解析、连接关闭等操作,避免手动管理导致的错误。
  5. 动态 SQL:提供 <if><where><foreach> 等标签,可根据条件动态拼接 SQL,解决拼接 SQL 时的空格、逗号等问题。
补充:

什么是ORM?

对象关系映射(ORM,Object-Relational Mapping)是一种编程技术,它的核心是把 "数据库中的表 / 记录" 和 "编程语言中的对象 / 实例" 做对应,让开发者可以用 "操作对象" 的方式来操作数据库,无需直接写 SQL(或减少 SQL 的编写)。

简单说:

数据库里的表 → 对应编程语言里的类;

表中的一行记录 → 对应类的一个对象实例;

表中的字段 → 对应类的属性;

对数据库的增删改查 → 对应对对象的创建、修改、删除、查询。

MyBatis 执行流程:

每次数据库操作执行
项目启动时,仅执行一次
解析配置生成 Configuration 全局配置对象
动态生成代理类
接收业务层调用
配置文件/注解

(mybatis-config.xml/Mapper.xml/注解)
SqlSessionFactoryBuilder
SqlSessionFactory

(全局唯一)
SqlSession

(单次会话,非线程安全)
Executor

(执行器,处理缓存/事务)
StatementHandler

(语句处理器,构建SQL)
ParameterHandler

(参数处理器,设置SQL参数)
JDBC操作

(PreparedStatement执行SQL)
ResultSetHandler

(结果集处理器,映射结果)
结果返回

(封装为实体类/Map等)
Mapper接口(代理类)

二、核心组件

1. SqlSessionFactory

  • 作用:创建 SqlSession 的工厂类,是 MyBatis 的核心入口,全局唯一(通常通过单例模式创建)。
  • 创建方式:通过 SqlSessionFactoryBuilder 解析 MyBatis 核心配置文件(mybatis-config.xml)或自定义配置类生成。

2. SqlSession

  • 作用:代表与数据库的一次会话,是执行 SQL 的核心对象,提供了增删改查的方法(如 selectOneinsertupdate 等)。
  • 生命周期:单次请求 / 方法级别,用完需及时关闭(否则会导致连接泄漏)。
  • 注意:SqlSession 不是线程安全的,不能在多线程中共享。

3. Mapper 接口(映射器)

  • 作用:MyBatis 采用 "接口 + XML / 注解" 的方式定义 SQL,Mapper 接口是 SQL 操作的抽象层,无需实现类(MyBatis 动态生成代理类)。

  • 示例:

    java 复制代码
    public interfadce UserMapper {
        // 通过注解定义SQL
        @Select("SELECT * FROM user WHERE id = #{id}")
        User selectUserById(Long id);
        
        // 通过XML定义SQL(推荐复杂SQL)
        List<User> selectUserByCondition(UserCondition condition);
    }

4. 核心配置文件(mybatis-config.xml)

MyBatis 的全局配置文件,包含环境(数据源、事务)、类型别名、插件、映射器等核心配置:

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!-- 环境配置:数据源、事务管理器 -->
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/> <!-- 事务管理:JDBC/MANAGED -->
            <dataSource type="POOLED"> <!-- 数据源:POOLED/UNPOOLED/JNDI -->
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/test?useSSL=false"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    <!-- 映射器:指定Mapper接口或XML文件位置 -->
    <mappers>
        <mapper resource="mapper/UserMapper.xml"/>
        <!-- 或通过接口包扫描 -->
        <!-- <package name="com.example.mapper"/> -->
    </mappers>
</configuration>

5. Mapper XML 文件

存放 SQL 语句和结果映射规则,核心标签包括:

<select>:查询语句

<insert>:插入语句

<update>:更新语句

<delete>:删除语句

<resultMap>:自定义结果集映射(解决字段名与实体属性名不一致、关联查询等)

示例(UserMapper.xml):

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- namespace对应Mapper接口全类名 -->
<mapper namespace="com.example.mapper.UserMapper">
    <!-- 自定义结果映射:解决字段名(如user_name)与属性名(userName)不一致 -->
    <resultMap id="UserResultMap" type="com.example.entity.User">
        <id column="id" property="id"/> <!-- 主键映射 -->
        <result column="user_name" property="userName"/>
        <result column="age" property="age"/>
        <result column="create_time" property="createTime" jdbcType="TIMESTAMP"/>
    </resultMap>

    <!-- 查询:引用自定义resultMap,参数通过#{参数名}接收 -->
    <select id="selectUserById" resultMap="UserResultMap">
        SELECT id, user_name, age, create_time FROM user WHERE id = #{id}
    </select>

    <!-- 动态SQL:根据条件拼接查询条件 -->
    <select id="selectUserByCondition" resultMap="UserResultMap">
        SELECT id, user_name, age, create_time FROM user
        <where>
            <if test="userName != null and userName != ''">
                AND user_name LIKE CONCAT('%', #{userName}, '%')
            </if>
            <if test="age != null">
                AND age = #{age}
            </if>
        </where>
    </select>

    <!-- 插入:返回自增主键 -->
    <insert id="insertUser" useGeneratedKeys="true" keyProperty="id">
        INSERT INTO user (user_name, age, create_time)
        VALUES (#{userName}, #{age}, #{createTime})
    </insert>
</mapper>

三、核心特性

1. 参数传递

MyBatis 支持多种参数传递方式:

单个参数:直接通过 #{参数名} 接收(参数名可任意,推荐与接口参数名一致)。

多个参数:

方式 1:使用@Param注解命名参数:

java 复制代码
User selectUserByUserNameAndAge(@Param("userName") String userName, @Param("age") Integer age)

方式 2:封装为实体类 / Map 传递。

数组 / 集合参数:结合<foreach>标签遍历,如批量删除:

xml 复制代码
<delete id="batchDeleteUser">
    DELETE FROM user WHERE id IN
    <foreach collection="ids" item="id" open="(" separator="," close=")">
        #{id}
    </foreach>
</delete>

2. 动态 SQL

MyBatis 提供丰富的动态 SQL 标签,解决手动拼接 SQL 的痛点:

标签 作用
<if> 条件判断
<where> 自动处理 AND/OR 前缀
<set> 自动处理更新语句的逗号
<foreach> 遍历集合(如 IN 条件)
<choose> 类似 Java 的 switch 语句
<trim> 自定义字符串截取

3. 结果映射

默认映射:字段名与实体属性名完全一致时,无需自定义 resultMap

自定义映射:通过resultMap解决:

字段名与属性名不一致(如数据库 user_name → 实体 userName);

关联查询(一对一 <association>、一对多 <collection>)。

示例(一对多映射):

xml 复制代码
<resultMap id="OrderResultMap" type="com.example.entity.Order">
    <id column="order_id" property="orderId"/>
    <result column="order_no" property="orderNo"/>
    <!-- 一对多:订单关联多个订单项 -->
    <collection property="orderItems" ofType="com.example.entity.OrderItem">
        <id column="item_id" property="itemId"/>
        <result column="product_name" property="productName"/>
    </collection>
</resultMap>

补:如何去开启全局驼峰命名映射(数据库:user_id → 实体类:userId):

方式 A:在mybatis-config.xml中配置:

xml 复制代码
<settings>
  <!-- 开启下划线→驼峰自动映射(user_id → userId) -->
  <setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>

方式 B:Spring Boot 项目在application.yml中配置:

yaml 复制代码
mybatis:
  configuration:
    map-underscore-to-camel-case: true

4. 缓存机制

MyBatis 缓存(一级 / 二级)的核心目的是提升系统性能、降低数据库压力,本质是 "用内存换速度"------ 把高频访问的数据库查询结果暂存到内存中,后续相同查询直接从内存取数据,无需重复访问数据库。

简单举个例子:

你可以把数据库比作咖啡店的「后厨」,查询请求比作顾客点咖啡,缓存比作吧台的「保温柜」:

没有缓存:

每个顾客点同款拿铁,后厨都要重新磨豆、萃取、冲调(每次查询都走数据库),慢且费资源;

有缓存:

后厨冲好一大壶拿铁放进保温柜,后续点拿铁的顾客直接从保温柜取(查缓存),速度快、后厨压力小。

MyBatis 一级缓存 = 「单个服务员的专属保温柜」(只服务自己接待的顾客);

MyBatis 二级缓存 = 「全店共享的保温柜」(所有服务员都能用来给顾客取咖啡)。

MyBatis 提供两级缓存,默认开启一级缓存,关闭二级缓存:

一级缓存 :基于 SqlSession 的本地缓存,同一 SqlSession 中相同 SQL 查询会复用结果(单次会话内重复查询),关闭 SqlSession 后缓存失效。

二级缓存 :基于 Mapper 命名空间的全局缓存,多个 SqlSession 可共享(多会话共享静态数据),需手动开启(在 Mapper XML 中添加 <cache/>),且实体类需实现 Serializable

四、MyBatis 与 Spring/Spring Boot 集成

实际开发中,MyBatis 通常与 Spring/Spring Boot 集成,核心依赖:

xml 复制代码
<!-- Spring Boot 整合 MyBatis 起步依赖 -->
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.3.0</version>
</dependency>
<!-- MySQL 驱动 -->
<dependency>
    <groupId>com.mysql</groupId>
    <artifactId>mysql-connector-j</artifactId>
    <scope>runtime</scope>
</dependency>

依赖版本适配表

Spring Boot 版本 MyBatis-Spring-Boot-Starter 版本 MyBatis 核心版本 Spring 版本 适配说明
2.0.x 2.0.x 3.5.0+ 5.0.x Spring Boot 2.0 基线版本
2.1.x 2.1.x 3.5.3+ 5.1.x 兼容 Java 8+
2.2.x 2.2.x 3.5.5+ 5.2.x 优化连接池适配
2.3.x 2.3.x 3.5.7+ 5.3.x 主流稳定版本,推荐中小项目
2.4.x - 2.7.x 2.4.x - 2.3.x(2.3.x 兼容) 3.5.9+ 5.3.x - 5.3.20+ Spring Boot 2.x 最终稳定版
3.0.x - 3.1.x 3.0.x - 3.1.x 3.5.10+ 6.0.x - 6.1.x 适配 Spring 6、Java 17+
3.2.x+ 3.2.x+ 3.5.13+ 6.1.x+ 最新版本,适配 Spring 6.1+

Spring Boot 配置(application.yml)

yaml 复制代码
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/test?useSSL=false&serverTimezone=UTC
    username: root
    password: 123456
mybatis:
  mapper-locations: classpath:mapper/*.xml # Mapper XML 文件位置
  type-aliases-package: com.example.entity # 实体类别名包
  configuration:
    map-underscore-to-camel-case: true # 自动将下划线命名转换为驼峰命名(如user_name → userName)
    cache-enabled: false # 关闭二级缓存

常用注解

@Mapper:标注在 Mapper 接口上,让 Spring 扫描并创建代理对象。

@MapperScan:在启动类上扫描 Mapper 接口包(替代每个接口加@Mapper):

java 复制代码
@SpringBootApplication
@MapperScan("com.example.mapper") // 扫描Mapper接口包
public class MyBatisApplication {
    public static void main(String[] args) {
        SpringApplication.run(MyBatisApplication.class, args);
    }
}

五、适用场景

  • 适合需要自定义 SQL、对性能要求高的场景(如电商、金融);
  • 适合数据库结构复杂、需要灵活调整 SQL 的项目;
  • 不适合完全追求 "零 SQL" 的快速开发场景(可选择 JPA/Hibernate)。

六、总结

MyBatis 以 "半自动化 ORM" 为核心,平衡了 SQL 灵活性和开发效率,既保留了开发者对 SQL 的控制权,又简化了 JDBC 操作。它是 Java 后端开发中最常用的持久层框架之一,尤其在互联网项目中广泛应用,掌握其核心组件、动态 SQL、结果映射是使用 MyBatis 的关键。

七、补充

idea使用mybatis-xml自定义模板创建文件

打开File -- Setting

打开Editor -- File and Code Templates --- 中间的"+"号

mybatis-xml文件模板如下:

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="">

</mapper>

配置mybatis-config.xml步骤一致:

模板:

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!-- 环境配置:数据源、事务管理器 -->
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/> <!-- 事务管理:JDBC/MANAGED -->
            <dataSource type="POOLED"> <!-- 数据源:POOLED/UNPOOLED/JNDI -->
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/test?useSSL=false"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    <!-- 映射器:指定Mapper接口或XML文件位置 -->
    <mappers>
        <mapper resource="mapper/UserMapper.xml"/>
        <!-- 或通过接口包扫描 -->
        <!-- <package name="com.example.mapper"/> -->
    </mappers>
</configuration>
相关推荐
计算机学姐6 分钟前
基于SpringBoot的高校体育场馆预约系统【个性化推荐算法+数据可视化统计】
java·vue.js·spring boot·后端·mysql·信息可视化·推荐算法
Coder_Boy_8 分钟前
基于SpringAI的在线考试系统设计-用户管理模块设计
java·大数据·人工智能·spring boot·spring cloud
Tan_Ying_Y10 分钟前
为什么InnoDB存储引擎默认使用B+树作为索引结构?B+树索引工作原理?
数据库·b树·oracle
lalala_lulu10 分钟前
MySQL数据库存储引擎的数据结构(超详细版)
数据结构·数据库·mysql
ruleslol12 分钟前
MySQL中的binlog日志
数据库·mysql
小白不想白a14 分钟前
RabbitMQ监控
java·rabbitmq·java-rabbitmq
:mnong15 分钟前
大语言模型提示词生成交互原型案例分享
大数据·数据库·人工智能
Vin0sen15 分钟前
leetcode 高频SQL50题
数据库·leetcode
Overt0p19 分钟前
MQ简单介绍以及RabbitMQ基础使用,快速上手
java·分布式·rabbitmq
奋进的芋圆21 分钟前
SerialCommManager 详解:从嵌入式通信管理器到 Spring Boot 后端服务
java·spring boot·接口隔离原则