一、学习目标
通过本文的系统学习,开发者应该能够:
- 深入理解MyBatis架构:掌握SqlSession、Executor等核心组件的工作原理与生命周期管理
- 熟练运用动态SQL与结果映射:能够编写复杂的动态SQL语句,实现灵活的结果映射配置
- 掌握缓存机制与性能优化:理解一级缓存、二级缓存原理,具备SQL性能优化能力
- 具备实战项目经验:能够运用MyBatis解决实际业务场景中的数据库操作问题
二、MyBatis架构与核心机制
1.1 MyBatis整体架构
核心组件 Configuration MappedStatement TypeHandler 应用程序 SqlSessionFactory SqlSession Executor StatementHandler ParameterHandler ResultSetHandler 数据库
MyBatis核心组件职责表:
| 组件 | 职责 | 关键接口 | 生命周期 |
|---|---|---|---|
| SqlSessionFactory | 创建SqlSession | SqlSessionFactory | 应用级别单例 |
| SqlSession | 数据库操作入口 | SqlSession | 请求级别 |
| Executor | SQL执行器 | Executor | SqlSession级别 |
| StatementHandler | SQL语句处理 | StatementHandler | 每次SQL执行 |
| ParameterHandler | 参数处理 | ParameterHandler | 每次SQL执行 |
| ResultSetHandler | 结果集处理 | ResultSetHandler | 每次SQL执行 |
1.2 配置文件解析
MyBatis配置结构
mybatis-config.xml 环境配置 属性配置 类型别名 插件配置 映射器配置 数据源 事务管理器 Mapper XML 注解Mapper
核心配置项详解表:
| 配置项 | 作用 | 示例配置 | 注意事项 |
|---|---|---|---|
| environments | 环境配置 | 开发/测试/生产环境切换 | 支持多环境 |
| dataSource | 数据源配置 | 连接池参数设置 | 性能关键 |
| typeAliases | 类型别名 | 简化类名引用 | 提高可读性 |
| mappers | 映射器配置 | XML或注解方式 | 支持包扫描 |
| plugins | 插件配置 | 分页、性能监控等 | 扩展功能 |
二、动态SQL与结果映射
2.1 动态SQL标签详解
动态SQL执行流程
动态标签处理 标签 标签 标签 标签 SQL解析 OGNL表达式计算 条件判断 SQL片段拼接 最终SQL生成 参数绑定 SQL执行
动态SQL标签对比表:
| 标签 | 作用 | 使用场景 | 示例 | 注意事项 |
|---|---|---|---|---|
| 条件判断 | 单个条件过滤 | <if test="name != null"> |
避免空指针 | |
| 多条件选择 | 类似switch-case | <when>/<otherwise> |
互斥条件 | |
| 循环遍历 | IN查询、批量操作 | collection="list" |
性能考虑 | |
| WHERE条件 | 动态WHERE子句 | 自动处理AND | 智能去除前缀 | |
| SET子句 | 动态UPDATE | 自动处理逗号 | 更新字段控制 | |
| 字符串修剪 | 自定义前缀后缀 | 灵活处理 | 复杂场景使用 |
动态SQL示例代码
xml
<!-- 复杂查询示例 -->
<select id="findUsers" parameterType="map" resultType="User">
SELECT * FROM users
<where>
<if test="name != null and name != ''">
AND name LIKE CONCAT('%', #{name}, '%')
</if>
<if test="status != null">
AND status = #{status}
</if>
<if test="roleIds != null and roleIds.size() > 0">
AND role_id IN
<foreach collection="roleIds" item="roleId" open="(" close=")" separator=",">
#{roleId}
</foreach>
</if>
</where>
ORDER BY create_time DESC
</select>
2.2 结果映射(ResultMap)详解
结果映射层次结构
ResultMap 基本映射 关联映射 集合映射 字段到属性 类型转换 一对一 一对多 集合属性 嵌套查询
ResultMap配置元素表:
| 元素 | 作用 | 属性 | 使用场景 |
|---|---|---|---|
| 主键映射 | column, property | 标识唯一性 | |
| 普通字段映射 | column, property | 基本字段映射 | |
| 一对一关联 | property, javaType | 对象关联 | |
| 一对多关联 | property, ofType | 集合属性 | |
##### 复杂结果映射示例 xml <!-- 用户与角色关联映射 --> <resultMap id="userWithRolesMap" type="User"> <id property="id" column="id"/> <result property="name" column="name"/> <result property="email" column="email"/> <!-- 一对一关联:用户详情 --> <association property="userDetail" javaType="UserDetail"> <id property="id" column="detail_id"/> <result property="address" column="address"/> <result property="phone" column="phone"/> </association> <!-- 一对多关联:用户角色 --> <collection property="roles" ofType="Role"> <id property="id" column="role_id"/> <result property="roleName" column="role_name"/> <result property="description" column="description"/> </collection> </resultMap> ### 三、缓存机制深度解析 #### 3.1 一级缓存与二级缓存 ##### 缓存层次结构 SqlSession 一级缓存 PerpetualCache SqlSessionFactory 二级缓存 装饰器模式 序列化缓存 LRU缓存 日志缓存 事务提交清空 手动清空 namespace级别 跨Session共享 一级缓存 vs 二级缓存对比表: |
特性 | 一级缓存 | 二级缓存 |