MyBatis 从入门到精通(第二篇)—— 核心架构、配置解析与 Mapper 代理开发
在第一篇博客中,我们掌握了 MyBatis 的基础概念与环境搭建,成功通过简单查询实现了数据持久化。但要真正用好 MyBatis,还需深入理解其 “内部工作原理” 与 “企业级开发规范”。本篇将聚焦三大核心:MyBatis 架构与核心类、全局配置文件详解、Mapper 代理开发(企业主流方案),帮你从 “会用” 升级到 “懂原理、能规范开发”。
目录
一、深入 MyBatis 架构:三层架构 + 核心类解析
1.1 三层架构:从 “调用入口” 到 “基础支撑”
(1)API 接口层:上层应用的 “交互入口”
(2)数据处理层(核心层):MyBatis 的 “业务大脑”
(3)基础支撑层:MyBatis 的 “后勤保障”
1.2 5 个核心类:MyBatis 的 “关键零件”
核心类工作流程示例(以 “查询部门” 为例):
二、MyBatis 全局配置文件:SqlMapConfig.xml 详解
2.1 properties标签:灵活管理数据源参数
方式 1:内部直接定义属性(简单但不推荐)
方式 2:加载外部jdbc.properties文件(推荐)
方式 3:动态传入属性(了解,特殊场景用)
2.2 settings标签:MyBatis 的 “运行开关”
配置示例:
2.3 typeAliases标签:简化全限定类名的 “别名神器”
方式 1:为单个类定义别名(简单场景用)
方式 2:为包下所有类定义别名(推荐,企业常用)
2.4 environments标签:多环境配置(开发 / 测试 / 生产)
配置示例:
关键子标签说明:
切换环境:
2.5 mappers标签:告诉 MyBatis “SQL 在哪里”
方式 1:加载类路径下的 Mapper.xml(入门用)
方式 2:加载本地文件系统的 Mapper.xml(了解)
方式 3:加载单个 Mapper 接口(Mapper 代理用)
方式 4:扫描包下所有 Mapper 接口(推荐,企业常用)
三、Mapper 代理开发:企业级 Dao 层开发规范
3.1 为什么要放弃 “原始 Dao 开发”?
3.2 Mapper 代理开发的 4 个核心规范
3.3 Mapper 代理开发实战步骤
步骤 1:创建 Mapper 接口(DeptMapper.java)
步骤 2:创建对应的 Mapper.xml(DeptMapper.xml)
步骤 3:配置SqlMapConfig.xml的mappers标签
步骤 4:编写测试类,通过代理对象调用方法
代理开发的优势总结:
四、总结与下一步预告
一、深入 MyBatis 架构:三层架构 + 核心类解析
就像开车需要了解方向盘、油门的作用,使用 MyBatis 前,搞懂其架构与核心类,能让你在遇到问题时快速定位原因。MyBatis 的功能架构自上而下分为三层,核心类则是每层的 “关键执行器”。
1.1 三层架构:从 “调用入口” 到 “基础支撑”
MyBatis 的架构设计清晰,每层职责明确,协同完成数据库操作,具体如下:
(1)API 接口层:上层应用的 “交互入口”
这是我们最常接触的一层,核心对象是SqlSession
—— 它是上层应用(如 Service 层)与 MyBatis 的 “桥梁”,提供了 CRUD 操作的所有方法(如selectList()
查询列表、insert()
插入数据、update()
更新数据)。
我们无需关心底层如何执行 SQL,只需通过SqlSession
调用对应的方法即可。例如:
// 通过SqlSession调用查询方法,定位SQL的“namespace+id”
List<Dept> depts = session.selectList("com.jr.mapper.DeptMapper.selectDept");
当SqlSession
接收到调用请求后,会将任务交给下一层(数据处理层)执行。
(2)数据处理层(核心层):MyBatis 的 “业务大脑”
这是 MyBatis 的核心,负责完成数据库操作的全流程,主要做四件事:
- 参数映射:将 Java 代码传入的参数(如
Integer deptno
)解析并转换为 JDBC 支持的类型(如SQL INTEGER
); - SQL 解析:读取 Mapper.xml 中的 SQL 语句,处理动态 SQL(如
<if>
、<where>
标签),生成最终可执行的 SQL; - SQL 执行:通过执行器(
Executor
)调用 JDBC API 执行 SQL,与数据库交互; - 结果映射:将数据库返回的 ResultSet 结果集,自动映射为 Java 实体类(如
Dept
对象),无需手动遍历赋值。
这一层的核心组件是Executor
(执行器),它是 SQL 执行的 “实际操作者”,MyBatis 提供了三种常用执行器:
SimpleExecutor
:默认执行器,每次执行 SQL 都会创建新的PreparedStatement
;ReuseExecutor
:重用PreparedStatement
,避免重复创建,提升性能;BatchExecutor
:支持批量更新,适用于大量插入 / 更新场景。
(3)基础支撑层:MyBatis 的 “后勤保障”
这一层提供通用功能支撑,为上层(数据处理层)服务,核心能力包括:
- 连接管理:通过数据源(
DataSource
)管理数据库连接,支持连接池(如POOLED
类型),避免频繁创建 / 关闭连接; - 事务管理:支持 JDBC 事务(手动提交 / 回滚)和 MANAGED 事务(交给容器管理,如 Spring);
- 缓存处理:实现一级缓存(
SqlSession
级别)和二级缓存(Mapper
级别),减少数据库访问次数; - 工具类:提供 XML 解析、反射、日志打印等基础工具,简化框架内部逻辑。
1.2 5 个核心类:MyBatis 的 “关键零件”
理解核心类的作用与生命周期,是排查问题、优化性能的关键,下表整理了必须掌握的 5 个核心类:
核心类 | 核心作用 | 生命周期 | 关键特点 |
---|---|---|---|
SqlSessionFactory | 创建SqlSession 的 “工厂” | 应用启动时创建,全局唯一 | 一旦创建,需一直存在,不可重复创建(浪费资源) |
SqlSession | 与数据库的 “一次会话”,提供 CRUD 方法 | 每次操作数据库时创建,用完关闭 | 非线程安全,必须手动关闭(推荐try-finally ) |
Executor | 执行器,负责 SQL 的实际执行(查询 / 更新) | 每个SqlSession 对应一个Executor | 可通过配置切换执行器类型(如批量执行器) |
MappedStatement | 存储 Mapper.xml 中的 SQL 信息(id、参数、结果映射) | 应用启动时加载,全局唯一 | 每个 SQL 节点(如<select> )对应一个实例 |
Configuration | 存储 MyBatis 的所有配置信息(数据源、映射、settings) | 应用启动时解析配置文件生成 | 是 MyBatis 的 “配置中心”,所有核心类都依赖它 |
核心类工作流程示例(以 “查询部门” 为例):
- 应用启动时,解析
SqlMapConfig.xml
和DeptMapper.xml
,生成Configuration
对象; - 通过
SqlSessionFactoryBuilder
读取Configuration
,创建SqlSessionFactory
; - 调用
SqlSessionFactory.openSession()
,创建SqlSession
,并为其分配Executor
; - 调用
SqlSession.selectList("com.jr.mapper.DeptMapper.selectDept")
,SqlSession
通过 “namespace+id” 找到对应的MappedStatement
; Executor
根据MappedStatement
中的 SQL 信息,执行 SQL 并处理结果,最终返回Dept
列表;- 关闭
SqlSession
,释放Executor
与数据库连接。
二、MyBatis 全局配置文件:SqlMapConfig.xml 详解
SqlMapConfig.xml
是 MyBatis 的 “全局控制中心”,所有影响 MyBatis 行为的配置都集中在这里。上篇我们只写了基础配置,本篇将详细解析 5 个核心配置标签,覆盖企业开发中的常用场景。
2.1 properties
标签:灵活管理数据源参数
properties
标签用于加载数据库连接参数(如驱动、URL、用户名、密码),避免硬编码在配置文件中,支持三种使用方式,推荐第二种(加载外部属性文件)。
方式 1:内部直接定义属性(简单但不推荐)
直接在properties
标签内写死参数,修改时需改配置文件,灵活性差:
<configuration><!-- 内部定义数据源参数 --><properties><property name="driver" value="com.mysql.cj.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/mytestdb?serverTimezone=GMT&useSSL=false"/><property name="username" value="root"/><property name="password" value="root"/></properties><!-- 使用参数:${属性名} --><environments default="development"><environment id="development"><transactionManager type="JDBC"/><dataSource type="POOLED"><property name="driver" value="${driver}"/><property name="url" value="${url}"/><property name="username" value="${username}"/><property name="password" value="${password}"/></dataSource></environment></environments>
</configuration>
方式 2:加载外部jdbc.properties
文件(推荐)
将参数放在独立的属性文件中,实现 “参数与配置分离”,修改参数无需动SqlMapConfig.xml
:
在src/main/resources
下新建jdbc.properties
文件:
# jdbc.properties:单独存储数据源参数
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/mytestdb?serverTimezone=GMT&useSSL=false
username=root
password=root
在SqlMapConfig.xml
中加载该文件:
<configuration><!-- 加载外部属性文件,resource指定文件路径(类路径下) --><properties resource="jdbc.properties"/><!-- 直接使用${属性名}引用参数 --><environments default="development"><environment id="development"><transactionManager type="JDBC"/><dataSource type="POOLED"><property name="driver" value="${driver}"/><property name="url" value="${url}"/><property name="username" value="${username}"/><property name="password" value="${password}"/></dataSource></environment></environments>
</configuration>
方式 3:动态传入属性(了解,特殊场景用)
通过SqlSessionFactoryBuilder.build()
方法动态传入参数,覆盖配置文件中的值,适用于 “临时切换数据源” 场景:
// 1. 加载配置文件
InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
// 2. 动态创建属性,覆盖url
Properties props = new Properties();
props.setProperty("url", "jdbc:mysql://localhost:3306/testdb2?serverTimezone=GMT&useSSL=false");
// 3. 传入属性,创建SqlSessionFactory
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is, props);
重要优先级规则:动态传入的属性 > 外部属性文件 > 内部定义的属性,即后加载的属性会覆盖先加载的同名属性。
2.2 settings
标签:MyBatis 的 “运行开关”
settings
标签用于配置 MyBatis 的全局运行参数,这些参数直接影响框架的性能与行为。企业开发中常用的配置如下:
设置项 | 作用描述 | 默认值 | 推荐配置 |
---|---|---|---|
cacheEnabled | 开启全局二级缓存(后续博客详解) | true | 保持默认 true |
lazyLoadingEnabled | 开启延迟加载(按需加载关联数据,如查员工时不默认查部门) | false | 复杂项目设为 true |
aggressiveLazyLoading | 开启 “积极懒加载”:访问实体类任一属性,加载所有关联数据 | false(3.4.1+) | 设为 false(按需加载,更灵活) |
mapUnderscoreToCamelCase | 开启 “下划线转驼峰”:数据库字段dept_name 自动映射为实体类属性deptName | false | 必须设为 true(避免手动映射字段) |
logImpl | 指定日志实现(如 SLF4J、LOG4J) | 未设置 | 开发环境设为 LOG4J(方便看 SQL 日志) |
配置示例:
<configuration><properties resource="jdbc.properties"/><!-- settings标签必须在properties之后、typeAliases之前 --><settings><!-- 开启下划线转驼峰,避免手动映射字段 --><setting name="mapUnderscoreToCamelCase" value="true"/><!-- 开启延迟加载,优化关联查询性能 --><setting name="lazyLoadingEnabled" value="true"/><!-- 关闭积极懒加载,按需加载关联数据 --><setting name="aggressiveLazyLoading" value="false"/></settings><!-- 其他配置... -->
</configuration>
2.3 typeAliases
标签:简化全限定类名的 “别名神器”
在 Mapper.xml 中,resultType
/parameterType
需要写实体类的全限定类名(如com.jr.pojo.Dept
),重复书写繁琐且易出错。typeAliases
标签可给实体类定义 “别名”,简化书写。
方式 1:为单个类定义别名(简单场景用)
<configuration><properties resource="jdbc.properties"/><settings>...</settings><!-- 为单个实体类定义别名 --><typeAliases><!-- alias:别名,type:实体类全限定类名 --><typeAlias alias="dept" type="com.jr.pojo.Dept"/><typeAlias alias="emp" type="com.jr.pojo.Emp"/></typeAliases><!-- 其他配置... -->
</configuration>
使用时直接写别名,无需全限定类名:
<!-- Mapper.xml中使用别名 -->
<select id="selectDept" resultType="dept"> <!-- 直接用“dept”代替“com.jr.pojo.Dept” -->select * from dept
</select>
方式 2:为包下所有类定义别名(推荐,企业常用)
若实体类较多,逐个定义别名太麻烦,可直接扫描整个包,MyBatis 会自动将 “类名首字母小写” 作为别名(如Dept
→dept
、Emp
→emp
):
<configuration><properties resource="jdbc.properties"/><settings>...</settings><!-- 扫描com.jr.pojo包下所有实体类,自动生成别名 --><typeAliases><package name="com.jr.pojo"/></typeAliases><!-- 其他配置... -->
</configuration>
特殊需求:若想自定义别名(不使用首字母小写),可在实体类上添加@Alias
注解:
import org.apache.ibatis.type.Alias;@Alias("myDept") // 自定义别名“myDept”
public class Dept {// 实体类属性、getter/setter...
}
使用时直接写自定义别名:
<select id="selectDept" resultType="myDept">select * from dept
</select>
2.4 environments
标签:多环境配置(开发 / 测试 / 生产)
实际项目中,开发、测试、生产环境的数据库配置不同(如开发用本地库,生产用服务器库),environments
标签支持配置多个环境,默认激活一个。
配置示例:
<configuration><properties resource="jdbc.properties"/><settings>...</settings><typeAliases>...</typeAliases><!-- default:默认激活的环境ID(此处为开发环境) --><environments default="development"><!-- 开发环境 --><environment id="development"><!-- 事务管理器:JDBC(手动控制事务) --><transactionManager type="JDBC"/><!-- 数据源:POOLED(连接池,开发/测试用) --><dataSource type="POOLED"><property name="driver" value="${dev.driver}"/><property name="url" value="${dev.url}"/><property name="username" value="${dev.username}"/><property name="password" value="${dev.password}"/></dataSource></environment><!-- 生产环境 --><environment id="production"><!-- 事务管理器:MANAGED(交给Spring容器管理) --><transactionManager type="MANAGED"/><!-- 数据源:POOLED(生产环境也用连接池,提升性能) --><dataSource type="POOLED"><property name="driver" value="${prod.driver}"/><property name="url" value="${prod.url}"/><property name="username" value="${prod.username}"/><property name="password" value="${prod.password}"/></dataSource></environment></environments><!-- 其他配置... -->
</configuration>
对应的jdbc.properties
需包含多环境参数:
# 开发环境参数
dev.driver=com.mysql.cj.jdbc.Driver
dev.url=jdbc:mysql://localhost:3306/dev_db?serverTimezone=GMT&useSSL=false
dev.username=root
dev.password=root# 生产环境参数
prod.driver=com.mysql.cj.jdbc.Driver
prod.url=jdbc:mysql://192.168.1.100:3306/prod_db?serverTimezone=GMT&useSSL=false
prod.username=prod_user
prod.password=prod_pwd
关键子标签说明:
transactionManager
(事务管理器):
支持两种类型:JDBC
(依赖数据源连接,手动调用session.commit()
提交事务)和MANAGED
(不管理事务,交给容器如 Spring 处理,MyBatis 只负责 SQL 执行)。dataSource
(数据源):
支持三种类型:POOLED
:连接池,创建连接池管理连接,避免频繁创建 / 关闭,开发 / 测试 / 生产都推荐;UNPOOLED
:无连接池,每次执行 SQL 都新建连接,性能差,仅适用于小规模项目;JNDI
:从应用服务器(如 Tomcat)的 JNDI 数据源获取连接,适用于 JavaEE 企业级项目。
切换环境:
默认使用default
指定的环境,若需切换(如测试时用生产环境配置),可在创建SqlSessionFactory
时指定环境 ID:
InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
// 指定激活“production”环境
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is, "production");
2.5 mappers
标签:告诉 MyBatis “SQL 在哪里”
mappers
标签用于配置 “Mapper 映射文件” 或 “Mapper 接口” 的位置 ——MyBatis 需要通过它找到我们写的 SQL 语句,常用四种配置方式,企业开发推荐后两种(Mapper 代理用)。
方式 1:加载类路径下的 Mapper.xml(入门用)
通过resource
指定 Mapper.xml 的类路径,适用于 “普通项目” 或 “非代理开发” 场景:
<mappers><mapper resource="com/jr/mapper/DeptMapper.xml"/><mapper resource="com/jr/mapper/EmpMapper.xml"/>
</mappers>
方式 2:加载本地文件系统的 Mapper.xml(了解)
通过url
指定本地文件的绝对路径,适用于 Mapper.xml 不在类路径下的场景(很少用):
<mappers><mapper url="file:///D:/mybatis-project/mappers/DeptMapper.xml"/>
</mappers>
方式 3:加载单个 Mapper 接口(Mapper 代理用)
通过class
指定 Mapper 接口的全限定类名,适用于 “Mapper 代理开发”(后续详解),要求:Mapper 接口与 Mapper.xml 在同一包下,且文件名相同:
<mappers><mapper class="com.jr.mapper.DeptMapper"/><mapper class="com.jr.mapper.EmpMapper"/>
</mappers>
方式 4:扫描包下所有 Mapper 接口(推荐,企业常用)
通过package
扫描整个包下的所有 Mapper 接口,自动关联对应的 Mapper.xml,要求与方式 3 一致(接口与 XML 同包同名),简化大量配置:
<mappers><!-- 扫描com.jr.mapper包下所有Mapper接口 --><package name="com.jr.mapper"/>
</mappers>
三、Mapper 代理开发:企业级 Dao 层开发规范
在第一篇的环境搭建中,我们通过SqlSession.selectList("namespace+id")
调用 SQL,这种方式属于 “原始 Dao 开发”。但在企业项目中,更推荐Mapper 代理开发—— 无需编写 Dao 接口的实现类,MyBatis 会自动生成代理对象,大幅减少重复代码。
3.1 为什么要放弃 “原始 Dao 开发”?
原始 Dao 开发需要手动编写 Dao 接口的实现类(如DeptDaoImpl
),存在三个明显缺点:
- 模板代码冗余:实现类中大量重复代码(如创建
SqlSession
、调用方法、关闭SqlSession
),开发者沦为 “代码搬运工”; - SQL ID 硬编码:调用
SqlSession
方法时,需写死 SQL 的 “namespace+id”(如session.selectList("com.jr.mapper.DeptMapper.selectDept")
),写错不会在编译期报错,只能在运行时发现; - 类型不安全:
SqlSession
的方法参数与返回值大量使用泛型(如selectList()
返回List<Object>
),若参数类型或返回值类型错误,编译期无法察觉。
而 Mapper 代理开发能完美解决这些问题 —— 只需写 “Mapper 接口” 和 “Mapper.xml”,MyBatis 自动生成实现类代理对象,既简洁又安全。
3.2 Mapper 代理开发的 4 个核心规范
要让 MyBatis 自动生成代理对象,必须遵守以下 4 个规范(缺一不可),否则框架无法关联接口与 SQL:
- 接口与 XML 同包同名:Mapper 接口(如
DeptMapper.java
)与 Mapper.xml(如DeptMapper.xml
)必须在同一包下,且文件名完全相同; - XML 的 namespace 与接口全路径一致:Mapper.xml 的
namespace
属性必须等于 Mapper 接口的全限定类名(如com.jr.mapper.DeptMapper
); - 接口方法名与 XML 的 SQL ID 一致:Mapper 接口中的方法名(如
selectDept()
)必须等于 Mapper.xml 中 SQL 标签的id
(如<select id="selectDept">
); - 接口方法参数 / 返回值与 XML 匹配:
- 接口方法的参数类型 ≡ XML 中 SQL 的
parameterType
; - 接口方法的返回值类型 ≡ XML 中 SQL 的
resultType
/resultMap
(若返回列表,返回值类型为List<实体类>
,XML 中resultType
为单个实体类)。
- 接口方法的参数类型 ≡ XML 中 SQL 的
3.3 Mapper 代理开发实战步骤
以 “查询部门列表” 为例,完整演示 Mapper 代理开发的流程(基于 Maven 项目):
步骤 1:创建 Mapper 接口(DeptMapper.java)
在src/main/java/com/jr/mapper
下创建接口,定义查询方法,无需写实现类:
package com.jr.mapper;import com.jr.pojo.Dept;
import java.util.List;// 规范1:接口名与后续XML文件名相同(DeptMapper)
public interface DeptMapper {// 规范3:方法名与XML中SQL的id一致(selectDept)// 规范4:返回值类型为List<Dept>,对应XML中resultType="dept"(单个实体类)List<Dept> selectDept();// 新增:根据部门编号查询单个部门(演示参数匹配)// 规范4:参数类型为int,对应XML中parameterType="int";返回值为Dept,对应resultType="dept"Dept selectDeptByNo(int deptno);
}
步骤 2:创建对应的 Mapper.xml(DeptMapper.xml)
在src/main/resources/com/jr/mapper
下创建 XML 文件(与接口同包同名),配置 SQL 并遵守规范:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd"><!-- 规范2:namespace等于Mapper接口全路径(com.jr.mapper.DeptMapper) -->
<mapper namespace="com.jr.mapper.DeptMapper"><!-- 规范3:id等于接口方法名(selectDept) --><!-- 规范4:resultType="dept"(单个实体类),对应接口返回值List<Dept> --><select id="selectDept" resultType="dept">select * from dept</select><!-- 规范3:id等于接口方法名(selectDeptByNo) --><!-- 规范4:parameterType="int"(接口方法参数类型),resultType="dept"(返回值类型) --><select id="selectDeptByNo" parameterType="int" resultType="dept">select * from dept where deptno = #{deptno}</select>
</mapper>
步骤 3:配置SqlMapConfig.xml
的mappers
标签
使用 “扫描包” 方式加载 Mapper 接口(企业推荐):
<configuration><properties resource="jdbc.properties"/><settings><setting name="mapUnderscoreToCamelCase" value="true"/></settings><typeAliases><package name="com.jr.pojo"/> <!-- 扫描实体类,生成别名 --></typeAliases><environments default="development"><!-- 数据源配置... --></environments><!-- 规范:扫描Mapper接口所在包,自动关联XML --><mappers><package name="com.jr.mapper"/></mappers>
</configuration>
步骤 4:编写测试类,通过代理对象调用方法
通过SqlSession.getMapper(接口.class)
获取 MyBatis 自动生成的代理对象,直接调用接口方法:
import com.jr.mapper.DeptMapper;
import com.jr.pojo.Dept;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;
import java.io.InputStream;
import java.util.List;public class DeptMapperTest {private SqlSessionFactory factory;// 测试前初始化SqlSessionFactory(只执行一次)@Beforepublic void setUp() throws Exception {InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");factory = new SqlSessionFactoryBuilder().build(is);}// 测试查询所有部门@Testpublic void testSelectDept() {SqlSession session = null;try {session = factory.openSession();// 获取Mapper代理对象(MyBatis自动生成,无需手动new实现类)DeptMapper deptMapper = session.getMapper(DeptMapper.class);// 直接调用接口方法,底层自动执行SQLList<Dept> depts = deptMapper.selectDept();for (Dept dept : depts) {System.out.println(dept);}} finally {// 确保关闭会话if (session != null) {session.close();}}}// 测试根据部门编号查询@Testpublic void testSelectDeptByNo() {SqlSession session = null;try {session = factory.openSession();DeptMapper deptMapper = session.getMapper(DeptMapper.class);// 传入参数,调用方法Dept dept = deptMapper.selectDeptByNo(10);System.out.println(dept); // 输出:Dept{deptno=10, dname='ACCOUNTING', loc='NEW YORK'}} finally {if (session != null) {session.close();}}}
}
代理开发的优势总结:
- 无模板代码:无需写 Dao 实现类,MyBatis 自动生成代理对象;
- SQL ID 无硬编码:通过接口方法名关联 SQL,编译期可检查错误;
- 类型安全:接口方法的参数与返回值类型明确,编译期可发现类型错误;
- 符合面向接口编程:符合企业级开发规范,便于团队协作与后期维护。
四、总结与下一步预告
本篇博客我们深入 MyBatis 的核心:
- 理解了 MyBatis 的三层架构与核心类,知道 SQL 是如何从 “调用” 到 “执行” 的;
- 掌握了全局配置文件
SqlMapConfig.xml
的 5 个核心标签,能应对企业级项目的配置需求; - 学会了 Mapper 代理开发规范,摆脱了原始 Dao 开发的冗余与不安全,实现了 “接口 + XML” 的简洁开发。
第三篇预告:MyBatis 的 “高级特性”—— 动态 SQL(灵活处理多条件查询)、关联查询(一对一 / 一对多)、查询缓存(一级 / 二级缓存优化性能),这些是解决复杂业务场景的关键,也是面试高频考点。跟着系列博客一步步深入,你会发现 MyBatis 的强大与灵活,真正做到 “知其然,更知其所以然”。