MyBatis 学习路线
MyBatis 是 Java 后端常用的持久层框架。它属于半自动 ORM:SQL 主要由开发者自己写,MyBatis 负责参数映射、结果映射、会话管理、缓存和插件扩展。
如果你已经会基础 SQL,再学 MyBatis 会很顺。如果 SQL 基础薄弱,建议先补 MySQL 的查询、索引和事务。
MyBatis 解决什么问题
不用 MyBatis 时,JDBC 代码通常会很繁琐:
- 获取连接。
- 创建 PreparedStatement。
- 设置参数。
- 执行 SQL。
- 遍历 ResultSet。
- 手动封装对象。
- 关闭资源。
MyBatis 把这些重复工作封装起来,让开发者更专注 SQL 和映射关系。
基本调用流程
mermaid
flowchart TD
A["Service 调用 Mapper 接口"] --> B["MyBatis 创建代理对象"]
B --> C["根据方法找到 SQL"]
C --> D["绑定参数"]
D --> E["执行 JDBC"]
E --> F["处理 ResultSet"]
F --> G["映射成 Java 对象"]
G --> H["返回给 Service"]学习路线
mermaid
flowchart TD
A["Mapper 接口和 XML"] --> B["参数映射"]
B --> C["结果映射"]
C --> D["动态 SQL"]
D --> E["一对一和一对多"]
E --> F["缓存机制"]
F --> G["插件拦截器"]
G --> H["批量操作和性能优化"]Mapper 接口
Mapper 接口定义数据库操作方法。
java
public interface UserMapper {
User selectById(Long id);
}XML 中写 SQL:
xml
<select id="selectById" resultType="com.example.User">
select id, name, age
from user
where id = #{id}
</select>id="selectById" 要和接口方法名对应。
参数映射
MyBatis 使用 #{} 做参数绑定。
xml
where name = #{name}不要使用字符串拼接传外部输入,避免 SQL 注入。
${} 是文本替换,只有在表名、排序字段等极少数场景才谨慎使用,并且必须做白名单校验。
结果映射
简单字段可以用 resultType。
复杂映射使用 resultMap:
xml
<resultMap id="userMap" type="com.example.User">
<id property="id" column="id"/>
<result property="userName" column="user_name"/>
</resultMap>当数据库字段和 Java 属性名不一致时,结果映射非常重要。
动态 SQL
动态 SQL 用于根据条件拼接 SQL。
xml
<select id="listUsers" resultType="com.example.User">
select id, name, age
from user
<where>
<if test="name != null and name != ''">
and name = #{name}
</if>
<if test="minAge != null">
and age >= #{minAge}
</if>
</where>
</select>常用标签:
| 标签 | 作用 |
|---|---|
if | 条件判断 |
where | 自动处理 where 和 and |
set | 动态更新字段 |
foreach | 遍历集合,常用于 in |
choose | 类似 switch |
适合场景
| 场景 | 说明 |
|---|---|
| SQL 复杂 | 手写 SQL 可控性强 |
| 报表查询 | 可以精细控制 join、group、子查询 |
| 老系统改造 | 更容易贴合已有表结构 |
| 性能敏感 | 可以针对 SQL 做明确优化 |
常见坑
#{}和${}混用导致 SQL 注入。- XML 方法 id 和 Mapper 方法名不一致。
- 返回字段和对象属性名不匹配。
- 动态 SQL 拼出错误语法。
- N+1 查询导致性能差。
- 批量插入一次传太多数据。
- 事务边界放错位置。
开发建议
- Mapper 方法命名表达业务含义。
- 复杂 SQL 分段清楚,不要写成一大坨。
- 查询字段不要长期使用
select *。 - 批量操作控制批次大小。
- 插件拦截器只做分页、审计等横切能力,不写业务逻辑。
- 慢 SQL 先看执行计划,再考虑改 SQL 或加索引。
练习
- 创建
user表。 - 写
selectById查询。 - 写
insertUser插入。 - 写动态条件查询。
- 写
foreach的in查询。 - 故意让字段名和属性名不一致,用
resultMap解决。
本章小结
MyBatis 的核心是 SQL、参数映射、结果映射和动态 SQL。学 MyBatis 不要脱离 SQL,框架只是帮你减少 JDBC 样板代码,真正的性能和正确性仍然取决于 SQL 写得是否合理。
