Skip to content

MyBatis 学习路线

MyBatis 是 Java 后端常用的持久层框架。它属于半自动 ORM:SQL 主要由开发者自己写,MyBatis 负责参数映射、结果映射、会话管理、缓存和插件扩展。

如果你已经会基础 SQL,再学 MyBatis 会很顺。如果 SQL 基础薄弱,建议先补 MySQL 的查询、索引和事务。

MyBatis 解决什么问题

不用 MyBatis 时,JDBC 代码通常会很繁琐:

  1. 获取连接。
  2. 创建 PreparedStatement。
  3. 设置参数。
  4. 执行 SQL。
  5. 遍历 ResultSet。
  6. 手动封装对象。
  7. 关闭资源。

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 &gt;= #{minAge}
        </if>
    </where>
</select>

常用标签:

标签作用
if条件判断
where自动处理 where 和 and
set动态更新字段
foreach遍历集合,常用于 in
choose类似 switch

适合场景

场景说明
SQL 复杂手写 SQL 可控性强
报表查询可以精细控制 join、group、子查询
老系统改造更容易贴合已有表结构
性能敏感可以针对 SQL 做明确优化

常见坑

  1. #{}${} 混用导致 SQL 注入。
  2. XML 方法 id 和 Mapper 方法名不一致。
  3. 返回字段和对象属性名不匹配。
  4. 动态 SQL 拼出错误语法。
  5. N+1 查询导致性能差。
  6. 批量插入一次传太多数据。
  7. 事务边界放错位置。

开发建议

  1. Mapper 方法命名表达业务含义。
  2. 复杂 SQL 分段清楚,不要写成一大坨。
  3. 查询字段不要长期使用 select *
  4. 批量操作控制批次大小。
  5. 插件拦截器只做分页、审计等横切能力,不写业务逻辑。
  6. 慢 SQL 先看执行计划,再考虑改 SQL 或加索引。

练习

  1. 创建 user 表。
  2. selectById 查询。
  3. insertUser 插入。
  4. 写动态条件查询。
  5. foreachin 查询。
  6. 故意让字段名和属性名不一致,用 resultMap 解决。

本章小结

MyBatis 的核心是 SQL、参数映射、结果映射和动态 SQL。学 MyBatis 不要脱离 SQL,框架只是帮你减少 JDBC 样板代码,真正的性能和正确性仍然取决于 SQL 写得是否合理。