环境搭建
导学
通过本节学习,你将能够:
- 在 Maven 项目中正确引入 MyBatis 3.5.x 及 MySQL 驱动依赖
- 编写符合规范且元素顺序正确的
mybatis-config.xml - 理解
properties → settings → typeAliases → ... → mappers的强制顺序约束 - 建立标准的 MyBatis 项目目录结构,避免资源文件加载失败
定义
为什么需要专门的环境搭建
MyBatis 不是单一 Jar 包即插即用的工具,它依赖:
- 核心库(
mybatis):提供 SqlSession、Executor、缓存等运行时能力 - 数据库驱动(
mysql-connector-j):建立与 MySQL 5.7 的 JDBC 连接 - 全局配置文件(
mybatis-config.xml):告知框架数据源在哪、事务如何管理、Mapper 文件在哪 - 映射文件(
Mapper.xml):存放 SQL 语句
这些组件必须按约定组织在正确的目录位置,否则会出现 "找不到配置文件"、"找不到 Mapper"、"数据源初始化失败" 等启动期错误。
与 JDBC 原始写法的对比
| 维度 | JDBC 原始项目 | MyBatis 项目 |
|---|---|---|
| 依赖管理 | 手动下载 mysql-connector.jar 放入 lib | Maven 坐标声明,自动传递依赖 |
| 连接配置 | 代码中硬编码 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 表并插入初始数据(见下表)
数据库表结构及初始数据:
| id | name | age | major | score |
|---|---|---|---|---|
| 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.xml | Mapper XML 必须放在 src/main/resources/mapper/ 下,与 mybatis-config.xml 中 <mapper resource="mapper/StudentMapper.xml"/> 的路径一致 |
| 数据库驱动类名错误 | ClassNotFoundException: com.mysql.jdbc.Driver | MySQL 8.0+ 驱动类名为 com.mysql.cj.jdbc.Driver,非旧版的 com.mysql.jdbc.Driver |
| URL 时区未设置 | The server time zone value 'XXX' is unrecognized | URL 中必须附加 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 代码的前提。