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. 写 foreach 的 in 查询。
  6. 故意让字段名和属性名不一致,用 resultMap 解决。

本章小结 ​

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