MyBatis源码阅读【加载】(二)加载映射文件流程

本文详细解析了MyBatis加载映射文件的流程,从XMLConfigBuilder的mapperElement入口开始,涵盖<package>子标签处理,<mapper>子标签解析,以及XML映射文件中的各种元素如select、insert、update、delete、动态SQL等的解析过程,最后解释了如何通过MapperRegistry和MapperBuilderAssistant构建MappedStatement对象。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、相关类与对象说明

  • XMLMapperBuilder

    专门用来解析mapper映射文件

public XMLMapperBuilder(Reader reader, Configuration configuration, String resource, Map<String, XNode> sqlFragments, String namespace);
public XMLMapperBuilder(Reader reader, Configuration configuration, String resource, Map<String, XNode> sqlFragments) ;
public XMLMapperBuilder(InputStream inputStream, Configuration configuration, String resource, Map<String, XNode> sqlFragments, String namespace);
public XMLMapperBuilder(InputStream inputStream, Configuration configuration, String resource, Map<String, XNode> sqlFragments);
  • XPathParser

    用来使用XPath语法解析XML的解析器

  • MapperRegistry

    mapper的注册中心,用于注册mapper

  • MapperBuilderAssistant

    用于构建MappedStatement对象的

  • XMLStatementBuilder

    专门用来解析MappedStatement

  • MappedStatement对象

    MyBatis的mapper文件最终会被解析器,解析成MappedStatement,其中insert|update|delete|select每一个标签分别对应一个MappedStatement

private String resource;
  private Configuration configuration;
  //节点中的id属性加要命名空间
  private String id;
  //尝试影响驱动程序每次批量返回的结果行数和这个设置值相等
  private Integer fetchSize;
  //SQL超时时间
  private Integer timeout;
  //Statement的类型,STATEMENT/PREPARE/CALLABLE
  private StatementType statementType;
  //结果集类型,FORWARD_ONLY/SCROLL_SENSITIVE/SCROLL_INSENSITIVE
  private ResultSetType resultSetType;
  //表示解析出来的SQL
  private SqlSource sqlSource;
  //缓存
  private Cache cache;
  //已废弃
  private ParameterMap parameterMap;
  //对应的ResultMap
  private List<ResultMap> resultMaps;
  private boolean flushCacheRequired;
  private boolean useCache;
  private boolean resultOrdered;
  //SQL类型,INSERT/SELECT/DELETE
  private SqlCommandType sqlCommandType;
  //和SELECTKEY标签有关
  private KeyGenerator keyGenerator;
  private String[] keyProperties;
  private String[] keyColumns;
  private boolean hasNestedResultMaps;
  //数据库ID,用来区分不同环境
  private String databaseId;
  private Log statementLog;
  private LanguageDriver lang;
  //多结果集时
  private String[] resultSets;

  MappedStatement() {
    // constructor disabled
  }

二、XML映射文件

MyBatis 的真正强大在于它的语句映射,减少使用成本,让用户能更专注于 SQL 代码。

image
  • select

select 元素允许你配置很多属性来配置每条语句的行为细节。

<select
  id="selectPerson"
  parameterType="int"
  parameterMap="deprecated"
  resultType="hashmap"
  resultMap="personResultMap"
  flushCache="false"
  useCache="true"
  timeout="10"
  fetchSize="256"
  statementType="PREPARED"
  resultSetType="FORWARD_ONLY">
image
  • insert, update 和 delete

    数据变更语句 insert,update 和 delete 的实现非常接近

<insert
  id="insertAuthor"
  parameterType="domain.blog.Author"
  flushCache="true"
  statementType="PREPARED"
  keyProperty=""
  keyColumn=""
  useGeneratedKeys=""
  timeout="20">

<update
  id="updateAuthor"
  parameterType="domain.blog.Author"
  flushCache="true"
  statementType="PREPARED"
  timeout="20">

<delete
  id="deleteAuthor"
  parameterType="domain.blog.Author"
  flushCache="true"
  statementType="PREPARED"
  timeout="20">
image
  • 动态sql

借助功能强大的基于 OGNL 的表达式,MyBatis 3 替换了之前的大部分元素,大大精简了元素种类

  • if
  • choose (when, otherwise)
    MyBatis 提供了 choose 元素,它有点像 Java 中的 switch 语句
<select id="findActiveBlogLike"
     resultType="Blog">
  SELECT * FROM BLOG WHERE state = ‘ACTIVE’
  <choose>
    <when test="title != null">
      AND title like #{title}
    </when>
    <when test="author != null and author.name != null">
      AND author_name like #{author.name}
    </when>
    <otherwise>
      AND featured = 1
    </otherwise>
  </choose>
</select>
  • trim (where, set)
<trim prefix="WHERE" prefixOverrides="AND |OR ">
  ...
</trim>

<trim prefix="SET" suffixOverrides=",">
  ...
</trim>
  • foreach
    动态 SQL 的另一个常见使用场景是对集合进行遍历(尤其是在构建 IN 条件语句的时候)。比如:
<select id="selectPostIn" resultType="domain.blog.Post">
  SELECT *
  FROM POST P
  WHERE ID in
  <foreach item="item" index="index" collection="list"
      open="(" separator="," close=")">
        #{item}
  </foreach>
</select>
  • script
    要在带注解的映射器接口类中使用动态 SQL,可以使用 script 元素。比如:
@Update({"<script>",
      "update Author",
      "  <set>",
      "    <if test='username != null'>username=#{username},</if>",
      "    <if test='password != null'>password=#{password},</if>",
      "    <if test='email != null'>email=#{email},</if>",
      "    <if test='bio != null'>bio=#{bio}</if>",
      "  </set>",
      "where id=#{id}",
      "</script>"})
    void updateAuthorValues(Author author);
  • bind
    bind 元素允许你在 OGNL 表达式以外创建一个变量,并将其绑定到当前的上下文。比如:
<select id="selectBlogsLike" resultType="Blog
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码农老K

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值