乐途乐途
主页
  • 计算机基础

    • TCP/IP协议
    • Linux命令
    • HTTP协议
  • 数据库

    • SQL
    • MySQL 5.7
  • 编程语言

    • C语言
    • Python2
    • Python3
  • 数据格式

    • JSON
    • XML
  • 认证与安全

    • JWT
  • 工具

    • Markdown
  • Git

    • GitFlow
  • Quartz

    • Quartz
  • Java

    • MyBatis
    • Spring
    • Spring MVC
    • Maven 入门
    • Maven 进阶
    • Java 设计模式
  • 缓存

    • Redis
联系
阿里云
主页
  • 计算机基础

    • TCP/IP协议
    • Linux命令
    • HTTP协议
  • 数据库

    • SQL
    • MySQL 5.7
  • 编程语言

    • C语言
    • Python2
    • Python3
  • 数据格式

    • JSON
    • XML
  • 认证与安全

    • JWT
  • 工具

    • Markdown
  • Git

    • GitFlow
  • Quartz

    • Quartz
  • Java

    • MyBatis
    • Spring
    • Spring MVC
    • Maven 入门
    • Maven 进阶
    • Java 设计模式
  • 缓存

    • Redis
联系
阿里云
  • 学习路径
  • 第1章 MyBatis概述与快速上手

    • 本章定位
    • MyBatis简介
    • 环境搭建
    • 第一个MyBatis程序
    • SqlSessionFactoryBuilder与openSession重载
    • SqlSessionFactory与SqlSession
    • SqlSession核心方法
    • 不使用 XML 构建 SqlSessionFactory
    • Mapper接口与映射方式
    • Java API 目录结构
  • 第2章 全局配置文件详解

    • 本章定位
    • properties
    • settings
    • typeAliases
    • typeHandlers
    • objectFactory
    • plugins
    • environments
    • transactionManager
    • dataSource
    • databaseIdProvider
    • mappers
    • 日志配置
  • 第3章 SQL映射文件基础

    • 本章定位
    • select
    • insert
    • update
    • delete
    • 参数传递与占位符
    • 主键生成策略
    • resultType
    • resultMap
    • 自动映射详解
    • sql片段
    • SQL 语句构建器
  • 第4章 动态SQL

    • 本章定位
    • if
    • choose、when、otherwise
    • where
    • set
    • foreach
    • trim
    • bind
    • script 元素:在注解映射器中启用动态 SQL
    • _databaseId 与动态 SQL 的多数据库支持
    • 动态 SQL 中插入脚本语言
  • 第5章 结果映射与关联查询

    • 本章定位
    • resultMap详解
    • association
    • collection
    • discriminator
    • N+1查询问题
    • 延迟加载
  • 第6章 MyBatis注解开发

    • 本章定位
    • @Select
    • @Insert
    • @Update
    • @Delete
    • @Param
    • @Options
    • @SelectKey
    • @Results
    • @Result
    • @One
    • @Many
    • @SelectProvider
  • 第7章 缓存与性能优化

    • 本章定位
    • 一级缓存
    • 二级缓存
    • 缓存配置详解
    • 自定义缓存
    • Executor执行器类型
    • 分页插件

环境搭建

导学

通过本节学习,你将能够:

  • 在 Maven 项目中正确引入 MyBatis 3.5.x 及 MySQL 驱动依赖
  • 编写符合规范且元素顺序正确的 mybatis-config.xml
  • 理解 properties → settings → typeAliases → ... → mappers 的强制顺序约束
  • 建立标准的 MyBatis 项目目录结构,避免资源文件加载失败

定义

为什么需要专门的环境搭建

MyBatis 不是单一 Jar 包即插即用的工具,它依赖:

  1. 核心库(mybatis):提供 SqlSession、Executor、缓存等运行时能力
  2. 数据库驱动(mysql-connector-j):建立与 MySQL 5.7 的 JDBC 连接
  3. 全局配置文件(mybatis-config.xml):告知框架数据源在哪、事务如何管理、Mapper 文件在哪
  4. 映射文件(Mapper.xml):存放 SQL 语句

这些组件必须按约定组织在正确的目录位置,否则会出现 "找不到配置文件"、"找不到 Mapper"、"数据源初始化失败" 等启动期错误。

与 JDBC 原始写法的对比

维度JDBC 原始项目MyBatis 项目
依赖管理手动下载 mysql-connector.jar 放入 libMaven 坐标声明,自动传递依赖
连接配置代码中硬编码 URL、用户名、密码集中在 XML,支持多环境切换
项目结构无强制规范,随意放置资源文件必须放在 resources 类路径下
启动检查运行时才发现连接错误启动时即解析配置,提前暴露问题

核心原理

MyBatis 配置解析流程

当应用启动并执行 new SqlSessionFactoryBuilder().build(inputStream) 时,MyBatis 内部按以下流程解析配置:

关键约束:元素顺序不可颠倒

MyBatis 的 DTD 对 mybatis-config.xml 中顶层元素的顺序有强制要求,顺序错误会导致解析异常:

properties → settings → typeAliases → typeHandlers → objectFactory
→ plugins → environments → databaseIdProvider → mappers

这个设计的深层原因是:后面的元素可能依赖前面元素的解析结果。例如 environments 中的 ${jdbc.url} 需要 properties 先加载;mappers 中的别名需要 typeAliases 先注册。


完整示例

场景说明

乐途公司技术部新建了一个 Maven 项目 fly-student-system,需要集成 MyBatis 3.5.15 访问 MySQL 5.7 数据库。本节展示从空项目到可运行状态的完整搭建过程。

操作前的准备

  • JDK 1.8 或更高版本
  • Maven 3.6+
  • MySQL 5.7 已启动,存在数据库 school
  • 数据库已创建 student 表并插入初始数据(见下表)

数据库表结构及初始数据:

idnameagemajorscore
1大翔22计算机科学95.50
2白歌21软件工程88.00
3小崔20计算机科学92.00
4黄俪21信息安全90.50
5李眉22软件工程87.00

完整的 pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
                             http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.fly</groupId>
    <artifactId>fly-student-system</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <mybatis.version>3.5.15</mybatis.version>
        <mysql.version>8.0.33</mysql.version>
    </properties>

    <dependencies>
        <!-- MyBatis 核心 -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>${mybatis.version}</version>
        </dependency>

        <!-- MySQL 驱动 -->
        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <version>${mysql.version}</version>
        </dependency>

        <!-- 日志实现(可选但强烈建议) -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-simple</artifactId>
            <version>2.0.9</version>
        </dependency>

        <!-- 单元测试 -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

完整的 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>

    <!-- 1. 属性:加载外部配置文件,供后续 ${} 引用 -->
    <properties resource="db.properties"/>

    <!-- 2. 设置:全局行为开关 -->
    <settings>
        <!-- 开启驼峰命名自动映射:db_create_time → dbCreateTime -->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
        <!-- 开启日志输出,方便调试 SQL -->
        <setting name="logImpl" value="SLF4J"/>
        <!-- 开启二级缓存 -->
        <setting name="cacheEnabled" value="true"/>
    </settings>

    <!-- 3. 类型别名:简化 XML 中的全限定类名书写 -->
    <typeAliases>
        <package name="com.fly.entity"/>
    </typeAliases>

    <!-- 4. 类型处理器:一般使用内置,无需自定义 -->
    <!-- <typeHandlers>...</typeHandlers> -->

    <!-- 5. 对象工厂:一般使用默认 -->
    <!-- <objectFactory type="..."/> -->

    <!-- 6. 插件:如分页插件、性能监控插件 -->
    <!-- <plugins>...</plugins> -->

    <!-- 7. 环境配置:数据源 + 事务管理器 -->
    <environments default="development">
        <environment id="development">
            <!-- JDBC 事务管理器:使用 Connection 的 commit/rollback -->
            <transactionManager type="JDBC"/>
            <!-- 连接池数据源 -->
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>

    <!-- 8. 数据库厂商标识:多数据库适配时使用 -->
    <!-- <databaseIdProvider type="DB_VENDOR">...</databaseIdProvider> -->

    <!-- 9. 映射器:注册 Mapper XML 文件或接口 -->
    <mappers>
        <!-- 方式一:按资源路径注册 XML -->
        <mapper resource="mapper/StudentMapper.xml"/>
        <!-- 方式二:按接口类注册(注解方式时使用) -->
        <!-- <mapper class="com.fly.mapper.StudentMapper"/> -->
        <!-- 方式三:按包名批量注册 -->
        <!-- <package name="com.fly.mapper"/> -->
    </mappers>

</configuration>

数据库连接属性文件 db.properties

jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/school?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=UTF-8
jdbc.username=root
jdbc.password=123456

标准项目目录结构

fly-student-system/
├── pom.xml
├── src/
│   ├── main/
│   │   ├── java/
│   │   │   └── com/
│   │   │       └── fly/
│   │   │           ├── entity/          # 实体类
│   │   │           ├── mapper/          # Mapper 接口
│   │   │           └── util/            # 工具类(如 MyBatisUtil)
│   │   └── resources/
│   │       ├── mybatis-config.xml       # 全局配置
│   │       ├── db.properties            # 数据库连接信息
│   │       └── mapper/                  # Mapper XML 文件
│   │           └── StudentMapper.xml
│   └── test/
│       └── java/                        # 测试类
└── target/                              # 编译输出

验证环境是否搭建成功

MyBatisUtil.java

package com.fly.util;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;

public class MyBatisUtil {
    private static SqlSessionFactory sqlSessionFactory;

    static {
        try {
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            System.out.println("【环境验证】SqlSessionFactory 创建成功!");
        } catch (IOException e) {
            throw new RuntimeException("初始化 MyBatis 失败: " + e.getMessage(), e);
        }
    }

    public static SqlSessionFactory getSqlSessionFactory() {
        return sqlSessionFactory;
    }
}

测试执行结果

【环境验证】SqlSessionFactory 创建成功!

若能正常输出上述日志,无 BuilderException 或 IOException,说明环境搭建完成。


易错场景 / 常见误区

误区错误表现正解
元素顺序错误org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Cause: org.apache.ibatis.builder.BuilderException: The properties element must be the first element in the configuration.严格遵循 properties → settings → typeAliases → typeHandlers → objectFactory → plugins → environments → databaseIdProvider → mappers 的顺序
Mapper XML 放错位置Invalid bound statement (not found) 或 IOException: Could not find resource mapper/StudentMapper.xmlMapper XML 必须放在 src/main/resources/mapper/ 下,与 mybatis-config.xml 中 <mapper resource="mapper/StudentMapper.xml"/> 的路径一致
数据库驱动类名错误ClassNotFoundException: com.mysql.jdbc.DriverMySQL 8.0+ 驱动类名为 com.mysql.cj.jdbc.Driver,非旧版的 com.mysql.jdbc.Driver
URL 时区未设置The server time zone value 'XXX' is unrecognizedURL 中必须附加 serverTimezone=Asia/Shanghai
properties 文件未放入 resources${jdbc.url} 解析失败,报无法找到属性db.properties 必须放在 src/main/resources 根目录,与 <properties resource="db.properties"/> 匹配

面试考点

Q1:mybatis-config.xml 中各元素的配置顺序是否可以调整?为什么?

A: 不可以。MyBatis 的 DTD 约束规定了严格的顺序:properties → settings → typeAliases → typeHandlers → objectFactory → plugins → environments → databaseIdProvider → mappers。这个顺序的设计原因是后面的配置可能依赖前面配置的结果,例如 environments 中的 ${jdbc.url} 需要 properties 先加载;mappers 中的 resultType 可能使用 typeAliases 中注册的短名称。顺序错误会在解析阶段直接抛出 BuilderException。

Q2:MyBatis 的 environments 为什么支持配置多个 environment,并通过 default 属性切换?

A: 这是为了支持多环境部署。例如可以配置 development(开发环境,连接本地数据库)、test(测试环境)、production(生产环境)。通过修改 default 属性即可切换整组数据源和事务配置,无需改动 Java 代码,符合 "配置与代码解耦" 的设计哲学。

Q3:数据源类型 UNPOOLED、POOLED、JNDI 有什么区别?

A: UNPOOLED 每次请求都创建新连接,用完即关,性能差,仅用于简单测试。POOLED 使用 MyBatis 内置连接池管理连接生命周期,复用连接,是生产环境推荐配置。JNDI 从应用服务器(如 Tomcat)的 JNDI 树中查找数据源,适用于企业级应用由容器统一管理连接池的场景。

Q4:<mappers> 的三种注册方式各适用于什么场景?

A: <mapper resource="..."/> 按 XML 文件路径注册,适用于 XML 映射方式,最常用。<mapper class="..."/> 按接口全限定名注册,适用于纯注解映射方式。<package name="..."/> 按包名批量注册,适用于包下所有 Mapper 统一注册,减少配置量,但要求 XML 文件与接口同名同路径。


小结

本节完成了 MyBatis 项目的从零搭建:通过 Maven 引入 mybatis 3.5.15 和 mysql-connector-j 8.0.33,编写了符合 DTD 顺序约束的 mybatis-config.xml,建立了标准的目录结构,并验证了 SqlSessionFactory 能正常初始化。

关键记忆点:

  • mybatis-config.xml 九大元素顺序不可颠倒
  • POOLED 数据源是生产环境默认选择
  • Mapper XML 必须放在 resources 类路径下,否则构建后无法加载
  • 外部化 db.properties 可实现环境切换而不改代码

下一章引子

环境已就绪,配置文件已解析,但 SqlSessionFactory 创建之后发生了什么?SqlSession 又是什么时候打开的?下一节将深入讲解 MyBatis 的两大核心对象——SqlSessionFactory 与 SqlSession,包括它们的生命周期、作用域、线程安全性,以及为什么必须 "用完即关"。理解这些,是写出稳定、高性能 MyBatis 代码的前提。

上一页
MyBatis简介
下一页
第一个MyBatis程序