Skip to content

能说说MyBatis的工作原理吗?

首先,我们知道MyBatis是一个优秀的持久层框架,它是用来简化数据库操作的。传统地,如果没有使用框架,我们可能需要手写大量的JDBC代码,处理很多的资源管理和异常处理。但MyBatis帮我们抽象了这一部分。

好,让我们来看一下MyBatis的工作原理:

  1. 配置文件:MyBatis需要一个XML配置文件,叫做mybatis-config.xml,用于定义数据源、事务管理以及其他一些设置。
  2. SQL映射文件:为了告诉MyBatis如何映射SQL查询到我们的对象或Java Beans,我们需要定义另一些XML文件。这些文件里,我们会写SQL语句,并定义输入和输出。
  3. SqlSessionFactory:当MyBatis初始化时,它会根据上面提到的配置文件创建一个SqlSessionFactory。这个工厂只会被创建一次,然后被用来生产SqlSession,这些SqlSession是应用中真正做数据库操作的对象。
  4. SqlSession:这是MyBatis的一个关键组件。每当我们想和数据库进行交互时,我们就从SqlSessionFactory那里拿到一个SqlSession。这个会话包含了所有执行SQL的方法,比如insert, update, delete, select等。
  5. 映射器:为了使代码更整洁,我们经常使用接口来代表SQL映射。这些接口的方法对应了之前在XML映射文件中定义的SQL语句。这样,我们就可以像调用普通的Java方法那样执行SQL语句了。

那么,当你在应用中调用一个映射器方法时,这里发生了什么?

  1. MyBatis会找到对应的SQL语句。
  2. 使用给定的参数,MyBatis会为这条SQL语句创建一个PreparedStatement。
  3. 执行这个PreparedStatement。
  4. 如果这是一个查询操作,MyBatis会将查询结果映射到Java对象或集合中。
  5. 最后,返回这个结果。

这就是MyBatis的基本工作原理。使用MyBatis,我们可以更方便地与数据库交互,同时避免大部分重复和模板化的代码。

更新: 2023-08-24 14:13:32
原文: https://www.yuque.com/tulingzhouyu/db22bv/afgcfcyf1fmsg7zi

mybatis 是怎么跟他的 xml 之间形成映射的?

1. 概述

MyBatis 是一个灵活的持久层框架,核心在于通过 XML 或注解,将 Java 方法与 SQL 语句高效映射。

在实际开发中,Mapper 接口和 XML 映射文件的关联是 MyBatis 的基础,也是经常被问及的核心原理。


2. 基本结构与关联方式

(1) Mapper 接口(Java)

java
public interface UserMapper {  
    User selectUserById(int id);  
}

(2) XML 映射文件

xml
<mapper namespace="com.example.mapper.UserMapper">  
  <select id="selectUserById" parameterType="int" resultType="com.example.model.User">  
    SELECT * FROM users WHERE id = #{id}  
  </select>  
</mapper>

(3) 关联方式说明

  • namespace:XML 文件的 namespace 属性必须与 Mapper 接口的全限定名一致。
  • id:SQL 标签的 id 属性必须与接口方法名一致。

这样,MyBatis 能自动把接口方法与 XML 中的 SQL 关联起来


3. MyBatis 关联底层实现原理

(1) 动态代理机制

  • MyBatis 为每个 Mapper 接口生成一个代理对象(使用 JDK 动态代理)。
  • 你调用 Mapper 方法时,实际是由代理对象接管,并根据方法名和参数查找、执行对应 SQL。

示例:

java
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);  
User user = userMapper.selectUserById(1);

(2) MapperRegistry 和 MapperProxyFactory

  • MapperRegistry:负责注册和管理所有 Mapper 接口。
  • MapperProxyFactory:为每个接口创建动态代理对象,内部由 MapperProxy 实现方法拦截和执行。

关联过程:

  1. MyBatis 通过 MapperRegistry 注册 Mapper 接口。
  2. 当调用 getMapper 方法时,MapperProxyFactory 生成相应的代理对象。
  3. 代理对象通过 MapperProxy 调用对应的 SQL 语句。

(3) XML 解析与绑定

  • MyBatis 启动时,用 XMLMapperBuilder 解析 XML 文件:
    • 读取 namespace,与接口绑定。
    • 读取 id,与方法名一一对应。
    • 每个 SQL 和方法的绑定关系,生成 MappedStatement 存入 Configuration 对象。

(4) 流程图

2025120623344551a20575d.png


4. 实例流程(OrderMapper 为例)

  • 接口Order selectOrderById(int id);
  • XML
xml
<mapper namespace="com.example.mapper.OrderMapper">  
  <select id="selectOrderById" ...>SELECT * FROM orders WHERE id = #{id}</select>  
</mapper>
  • 执行过程
    1. 启动加载 XML——解析 namespace/id——方法与 SQL 关联
    2. sqlSession.getMapper(OrderMapper.class) 创建代理
    3. 调用 selectOrderById -> 查找配置 -> 执行 SQL -> 返回 Order 对象

5. 动态 SQL 与高级映射

  • 支持 <if>、<choose>、<foreach> 等标签,实现条件拼装动态 SQL。
  • 提升灵活性,替换传统硬编码 SQL。

示例:

xml
<select id="selectOrders" resultType="Order">  
  SELECT * FROM orders  
  WHERE 1=1  
  <if test="status != null">AND status = #{status}</if>  
</select>

更新: 2025-04-17 19:02:09
原文: https://www.yuque.com/tulingzhouyu/db22bv/eyw0xl2ktv4ew1gt