前言
一、MyBatis 概述
1. 定义与定位
● MyBatis 是一款优秀的持久层框架,支持定制化 SQL、存储过程以及高级映射。
● 它消除了几乎所有的 JDBC 代码和参数的手工设置以及结果集的检索工作。
● 核心思想:将 SQL 语句与 Java 代码分离,通过 XML 或注解进行配置和映射。
2. 核心特点
● SQL 与代码分离:SQL 写在 XML 文件中,便于维护和优化。
● 灵活的参数映射:支持多种参数传递方式(#{}、${})。
● 强大的结果映射:支持自动映射和手动映射(resultMap),可处理复杂的关联关系。
● 动态 SQL:提供动态 SQL 标签,灵活拼接 SQL 语句。
● 缓存机制:内置一级缓存和二级缓存,提升查询性能。
3. 与 JDBC、Hibernate 的对比

二、MyBatis 核心组件
1. SqlSessionFactoryBuilder
● 作用:负责构建 SqlSessionFactory,通过读取配置文件或代码配置创建。
● 生命周期:方法级,用完即丢弃。
2. SqlSessionFactory
● 作用:创建 SqlSession 的工厂,是 MyBatis 的核心对象。
● 生命周期:应用级,整个应用运行期间只创建一次(单例模式)。
3. SqlSession
● 作用:执行 SQL、管理事务、获取 Mapper 接口的代理对象。
● 生命周期:请求/会话级,每次请求创建,用完关闭。
● 核心方法:selectOne()、selectList()、insert()、update()、delete()、commit()、rollback()。
4. Mapper 接口与 Mapper 代理
● Mapper 接口:定义数据库操作方法,无需实现类。
● Mapper 代理:MyBatis 动态生成 Mapper 接口的代理对象,负责调用 SQL 语句。
● 绑定方式:通过 XML 映射文件或注解绑定 SQL。
三、MyBatis 配置文件(mybatis-config.xml)
1. 顶层结构
<?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>
<!-- 配置项顺序:properties -> settings -> typeAliases -> typeHandlers -> environments -> mappers -->
</configuration>
2. 核心配置项详解
● properties:引入外部属性文件(如 db.properties),用于配置数据库连接信息。
● settings:全局配置项,影响 MyBatis 运行行为。
配置项 作用 示例值
cacheEnabled 开启二级缓存 true
lazyLoadingEnabled 开启延迟加载 true
mapUnderscoreToCamelCase 自动下划线转驼峰命名 true
● typeAliases:为 Java 类型设置别名,简化映射文件中的类型引用。
<typeAliases>
<typeAlias type="com.example.User" alias="User"/>
<package name="com.example"/> <!-- 扫描包,自动设置别名(类名首字母小写) -->
</typeAliases>
● environments:配置数据库环境,支持多环境切换。
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/> <!-- 事务管理器 -->
<dataSource type="POOLED"> <!-- 数据源类型:UNPOOLED、POOLED、JNDI -->
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
● mappers:注册映射文件或 Mapper 接口。
<mappers>
<mapper resource="com/example/mapper/UserMapper.xml"/> <!-- 资源路径 -->
<mapper class="com.example.mapper.UserMapper"/> <!-- 接口类路径 -->
<package name="com.example.mapper"/> <!-- 扫描包 -->
</mappers>
四、MyBatis 映射文件(Mapper.xml)
1. 映射文件结构
<?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="com.example.mapper.UserMapper">
<!-- SQL 语句定义 -->
</mapper>
2. 核心 SQL 元素
● select、insert、update、delete:定义 CRUD 操作。
<select id="selectUserById" parameterType="int" resultType="User">
SELECT * FROM user WHERE id = #{id}
</select>
<insert id="insertUser" parameterType="User" useGeneratedKeys="true" keyProperty="id">
INSERT INTO user (name, age) VALUES (#{name}, #{age})
</insert>
● 参数传递:
○ #{} :预编译参数,防止 SQL 注入,推荐使用。
○ ${}:字符串替换,存在 SQL 注入风险,仅用于动态表名、列名等场景。
● 结果映射:
○ resultType:自动映射,要求数据库列名与 Java 属性名一致(或开启下划线转驼峰)。
○ resultMap:手动映射,处理复杂结果集和关联关系。
<resultMap id="UserResultMap" type="User">
<id property="id" column="user_id"/> <!-- 主键映射 -->
<result property="name" column="user_name"/> <!-- 普通属性映射 -->
<!-- 一对一关联 -->
<association property="dept" javaType="Dept">
<id property="id" column="dept_id"/>
<result property="name" column="dept_name"/>
</association>
<!-- 一对多关联 -->
<collection property="orders" ofType="Order">
<id property="id" column="order_id"/>
<result property="amount" column="order_amount"/>
</collection>
</resultMap>
3. 动态 SQL
● if:条件判断。
<select id="selectUsers" parameterType="User" resultType="User">
SELECT * FROM user
<where>
<if test="name != null">AND name = #{name}</if>
<if test="age != null">AND age = #{age}</if>
</where>
</select>
● choose、when、otherwise:多条件分支(类似 switch-case)。
● trim、where、set:辅助拼接 SQL,处理多余的 AND、逗号等。
● foreach:遍历集合,用于 IN 查询或批量插入。
<select id="selectUsersByIds" parameterType="list" resultType="User">
SELECT * FROM user WHERE id IN
<foreach collection="list" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</select>
● bind:绑定变量,防止 SQL 注入或简化表达式。
五、MyBatis 核心功能
1. CRUD 操作
● 通过 Mapper 接口调用方法,或直接使用 SqlSession 执行 SQL。
2. 参数处理
● 单个参数:直接传递,可使用任意名称。
● 多个参数:使用 @Param 注解命名,或通过索引(arg0、arg1)访问。
User selectUserByNameAndAge(@Param("name") String name, @Param("age") int age);
● 对象参数:直接传递 Java 对象,属性名对应参数名。
● Map 参数:传递 Map 集合,key 对应参数名。
3. 结果映射
● 自动映射:列名与属性名一致时自动映射。
● 手动映射:使用 resultMap 处理复杂映射、关联关系。
● 关联映射:
○ 一对一:使用 。
○ 一对多:使用 。
4. 缓存机制
● 一级缓存(SqlSession 级别):
○ 默认开启,同一 SqlSession 内相同查询直接返回缓存结果。
○ 失效场景:SqlSession 关闭、执行增删改操作、手动清空缓存。
● 二级缓存(Mapper 级别):
○ 需手动开启,多个 SqlSession 共享同一 Mapper 的缓存。
○ 配置步骤:
ⅰ. 在 mybatis-config.xml 中开启:。
ⅱ. 在 Mapper.xml 中添加:。
○ 注意:实体类需实现 Serializable 接口。
六、MyBatis 高级特性
1. 插件开发
● 原理:通过 Interceptor 拦截 MyBatis 核心方法(Executor、ParameterHandler、ResultSetHandler、StatementHandler)。
● 自定义插件步骤:
a. 实现 Interceptor 接口。
b. 使用 @Intercepts 注解指定拦截方法。
c. 在 mybatis-config.xml 中注册插件。
2. 分页插件(PageHelper)
● 使用步骤:
a. 引入 PageHelper 依赖。
b. 在 mybatis-config.xml 中配置插件。
c. 代码中调用:PageHelper.startPage(pageNum, pageSize);。
3. 逆向工程(MyBatis Generator)
● 作用:根据数据库表自动生成实体类、Mapper 接口、Mapper.xml 文件。
● 配置:编写 generatorConfig.xml,指定数据库连接、表名、生成路径等。
4. 与 Spring/Spring Boot 整合
● Spring 整合:
○ 配置 SqlSessionFactoryBean、MapperScannerConfigurer。
● Spring Boot 整合:
○ 引入 mybatis-spring-boot-starter 依赖。
○ 在 application.yml 中配置数据源、MyBatis 配置文件路径等。
七、MyBatis-Plus(扩展)
1. 概述
● MyBatis-Plus 是 MyBatis 的增强工具,在 MyBatis 基础上只做增强不做改变,简化开发、提高效率。
2. 核心功能
● BaseMapper:内置通用 CRUD 方法,无需编写 XML。
● 条件构造器(Wrapper):灵活构建查询条件(如 QueryWrapper、UpdateWrapper)。
● 分页插件:内置分页功能,无需额外配置。
● 代码生成器:一键生成实体类、Mapper、Service、Controller 代码。
八、最佳实践与常见问题
1. Mapper 接口开发规范
● Mapper 接口名与 Mapper.xml 文件名一致,且在同一包下。
● Mapper 接口方法名与 Mapper.xml 中 SQL 元素的 id 一致。
● 避免在 Mapper 接口中定义重载方法(MyBatis 无法区分)。
2. SQL 优化建议
● 避免使用 SELECT *,只查询需要的列。
● 合理使用索引,避免全表扫描。
● 批量操作使用 foreach 或批量插入 API。
● 避免在 SQL 中进行复杂计算,尽量在 Java 代码中处理。
3. 缓存使用注意事项
● 一级缓存默认开启,但在多 SqlSession 环境下可能导致数据不一致。
● 二级缓存需谨慎使用,避免缓存脏数据,建议在查询多、修改少的场景下使用。
4. 常见问题排查
● SQL 注入:避免使用 ${},尽量使用 #{} 。
● 参数绑定失败:检查参数名与 SQL 中占位符是否一致,或使用 @Param 注解。
● 结果映射失败:检查列名与属性名是否匹配,或使用 resultMap 手动映射。