第六篇:Configuration之mappers

本文详细解读了Mybatis中XML配置文件的复杂解析过程,涉及mapper接口、BoundSql、SqlSource、LanguageDriver等核心概念,以及XMLMapperBuilder和MapperAnnotationBuilder的解析流程,帮助理解Mybatis内部工作机制。

这是Configuration里面最后一部分数据的解析,也是最复杂的一部分,所以这里使用了一篇来专门说这个,希望可以尽量说的清除点,首先要先看几个比较重要的概念

mapper

这个就是一个个的文件,大概格式如下

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zxc.study.test.mapper.UserMapper">
    <select id="selectUser" resultType="com.zxc.study.test.bean.User" flushCache="true">
    select * from user where id = #{param1}
  </select>

    <select id="test" resultType="com.zxc.study.test.bean.User">
    select * from user where id in
    <foreach collection="objectList" item="id" separator="," open="(" close=")">
        #{id}
    </foreach>
    </select>

</mapper>

BoundSql

绑定sql的对象,里面包含了具体的sql执行语句,比如

select * from user where id = ? and name = ?

与对应填充占位符对象ParameterMapping,里面包含了类型等

SqlSource

sql生成来源接口,用来获取BoundSql的源接口,主要有几个实现

DynamicSqlSource:动态sql数据源,也是最核心的一种了

StaticSqlSource:静态sql数据源,直接拿到就行了

RawSqlSource:介于两者之间的

LanguageDriver

语言驱动器,用来获取SqlSource的接口,主要有以下的实现

XMLLanguageDriver:也就是从xml文件解析,就想上面的例子一样

RawLanguageDriver:从接口上的注解进行解析的,比如

 @Select("select * from user where id = #{id}")
 User a(@Param("id") Integer id);

会从接口上解析select里面的语句出来,不过这种尽量少用比较好

以上是一些比较核心的接口和对应的一些基本类,接下来再去看源码解析是怎么走的

源码解析

解析入口为
org.apache.ibatis.builder.xml.XMLConfigBuilder#mapperElement


  private void mapperElement(XNode parent) throws Exception {
    if (parent != null) {
      //循环处理
      for (XNode child : parent.getChildren()) {
        //包格式的处理,等同于接口类型的处理
        if ("package".equals(child.getName())) {
          String mapperPackage = child.getStringAttribute("name");
          configuration.addMappers(mapperPackage);
        } else {
          String resource = child.getStringAttribute("resource");
          String url = child.getStringAttribute("url");
          String mapperClass = child.getStringAttribute("class");
          if (resource != null && url == null && mapperClass == null) {
            ErrorContext.instance().resource(resource);
            InputStream inputStream = Resources.getResourceAsStream(resource);
            //xml文件格式处理
            XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, configuration, resource, configuration.getSqlFragments());
            mapperParser.parse();
          } else if (resource == null && url != null && mapperClass == null) {
            ErrorContext.instance().resource(url);
            InputStream inputStream = Resources.getUrlAsStream(url);
            //xml文件格式处理
            XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, configuration, url, configuration.getSqlFragments());
            mapperParser.parse();
          } else if (resource == null && url == null && mapperClass != null) {
            //接口处理
            Class<?> mapperInterface = Resources.classForName(mapperClass);
            configuration.addMapper(mapperInterface);
          } else {
            //xml和接口必须要有一个,否则抛异常
            throw new BuilderException("A mapper element may only specify a url, resource or class, but not more than one.");
          }
        }
      }
    }
  }



可以看到实际上有两种解析方法,一种是通过xml,一种是通过接口,不过两种最终都会保存一份到另外一个位置去,比如xml解析完会根据namespace把接口也注册进行,接口注册完也会生成一份xml的进
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值