Skip to content

mybatis ​

参考文档:The MyBatis Blog

帮助:MyBatis中文网

MyBatis 是什么 ​

MyBatis 是一个半自动 ORM 框架。它不会像 JPA 那样把所有 SQL 都隐藏起来,而是让开发者自己编写 SQL,并负责把 SQL 参数和查询结果映射到 Java 对象。

如果要从零系统学习,先看这一页建立整体认识,再进入 MyBatis 核心全过程原理。核心页会把 Mapper 代理、SqlSession、Executor、BoundSql、参数绑定、结果映射、缓存、插件、事务和排查流程完整串起来。

它适合这些场景:

  1. 业务 SQL 比较复杂,需要开发者掌控执行细节。
  2. 团队希望 SQL 可见、可调优、可通过 explain 分析。
  3. 项目以关系型数据库为主,需要灵活处理多表查询。

执行流程 ​

mermaid
flowchart TD
    A[Mapper 接口方法] --> B[SqlSession 代理调用]
    B --> C[读取 MappedStatement]
    C --> D[解析动态 SQL 和参数]
    D --> E[创建 PreparedStatement]
    E --> F[执行数据库 SQL]
    F --> G[ResultSet 结果集]
    G --> H[ResultMap 映射成对象]
    H --> I[返回业务代码]

核心组件 ​

组件作用
SqlSessionFactory创建 SqlSession 的工厂
SqlSession执行 SQL、提交事务、获取 Mapper
MapperDAO 接口,业务代码主要调用它
MappedStatement一条 SQL 的完整描述,包括 SQL、参数、返回类型
Executor真正负责执行 SQL 的组件
TypeHandlerJava 类型和 JDBC 类型之间的转换
ResultMap查询结果和 Java 对象字段的映射关系

XML 和注解如何选择 ​

方式优点缺点
XML适合复杂 SQL,结构清晰,便于维护动态 SQL文件数量更多
注解简单查询写起来快复杂 SQL 可读性差

实践中建议:

  1. 简单单表查询可以用注解或 MyBatis-Plus。
  2. 复杂查询、动态条件、多表关联优先使用 XML。
  3. 核心 SQL 保持可读,避免把大量业务判断塞进 XML。

常见能力 ​

  1. 动态 SQL:if、choose、foreach、trim。
  2. 结果映射:一对一、一对多、字段别名映射。
  3. 缓存:一级缓存默认存在,二级缓存需要谨慎开启。
  4. 插件:分页、审计、SQL 改写、性能分析。
  5. 类型处理器:处理枚举、JSON、加密字段等特殊类型。

使用建议 ​

  1. Mapper 方法命名要表达业务语义,不要只叫 queryList。
  2. 更新和删除必须带明确条件,必要时加防全表更新插件。
  3. 分页查询要关注总数 SQL 的性能。
  4. 批量写入要控制批次大小,避免单次 SQL 过大。
  5. 复杂 SQL 上线前用 explain 检查索引和扫描行数。

深入学习路线 ​

学习顺序内容目标
1MyBatis 核心全过程原理理解 Mapper 方法到数据库返回对象的完整链路
2MyBatis 动态 SQL学会根据条件生成安全、可维护的 SQL
3MyBatis 缓存机制理解一级缓存、二级缓存和一致性风险
4MyBatis 拦截器理解分页、审计、数据权限等扩展点
5MyBatis 批量操作学会批量写入的性能边界和生产风险
6ORM 事务与一致性理解事务边界为什么应该放在 Service 层

代码 Demo:Mapper 接口和 XML ​

Mapper 接口:

java
public interface UserMapper {
    UserDO selectById(Long id);

    List<UserDO> selectByStatus(Integer status);
}

XML:

xml
<mapper namespace="com.example.UserMapper">
    <resultMap id="UserMap" type="com.example.UserDO">
        <id column="id" property="id"/>
        <result column="username" property="username"/>
        <result column="status" property="status"/>
    </resultMap>

    <select id="selectById" resultMap="UserMap">
        select id, username, status
        from users
        where id = #{id}
    </select>

    <select id="selectByStatus" resultMap="UserMap">
        select id, username, status
        from users
        where status = #{status}
        order by id desc
    </select>
</mapper>

重点:#{} 是预编译参数占位,能降低 SQL 注入风险;不要用字符串拼接用户输入。

为什么 MyBatis 适合 SQL 可控场景 ​

MyBatis 的核心价值是让开发者显式控制 SQL,同时帮你完成参数绑定和结果映射。如果业务 SQL 很复杂,例如多表 join、报表查询、复杂动态条件,MyBatis 通常比全自动 ORM 更直观。

mermaid
flowchart TD
    A["Mapper 方法"] --> B["XML / 注解 SQL"]
    B --> C["参数绑定"]
    C --> D["JDBC 执行"]
    D --> E["ResultMap 映射对象"]

如果不用 #{} 而是拼接字符串,用户输入可能改变 SQL 结构,产生 SQL 注入风险。MyBatis 的底线是:业务可以灵活写 SQL,但参数必须安全绑定。