您当前的位置: 首页 >  面试

墨家巨子@俏如来

暂无认证

  • 0浏览

    0关注

    188博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

吃透Mybatis源码-面试官问我mapper映射器是如何工作的(五)

墨家巨子@俏如来 发布时间:2022-01-05 18:15:40 ,浏览量:0

2021一路有你,2022我们继续加油!你的肯定是我最大的动力

博主在参加博客之星评比,点击链接 , https://bbs.csdn.net/topics/603957267 疯狂打Call!五星好评 ⭐⭐⭐⭐⭐ 感谢

前言

面试官:你说一下为什么Mapper映射器是一个interface,而我们却可以直接调用它的方法,还能执行对应的SQL。额…也许你不知道,也许你知道个大概,本篇文章将带你从源码的角度彻彻底底理解Mybatis的Mapper映射器

Mapper的注册

我们在执行Mybatis的时候可以使用 sqlSession.selectOne("cn.whale.mapper.StudentMapper.selectById",1L)这种最原生的方式,这种方式的弊端是太麻烦,每次都要去拼接 statementId。所以我们在项目中通常是使用Mapper映射器来执行。如下:

StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
Student student = mapper.selectById(1L);

下面我们就来分析一下通过Mapper映射器是如何工作的。在之前的文章中我们有分析到,在SqlSessionFactoryBuilder.buid的时候会通过XMLConfigBuilder对mybatis-config.xml进行解析,其中有一个步骤就是对Mapper.xml的解析 ,如: 。代码直接来到XMLConfigBuilder#mapperElement

private void mapperElement(XNode parent) throws Exception {
    if (parent != null) {
      for (XNode child : parent.getChildren()) {
        if ("package".equals(child.getName())) {
          //package配置方式
          String mapperPackage = child.getStringAttribute("name");
          configuration.addMappers(mapperPackage);
        } else {
          //拿到配置的资源 如: mapper/studentMapper.xml
          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);
            //mapper.xml的解析器
            XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, configuration, resource, configuration.getSqlFragments());
            //【重点】解析mapper.xml
            mapperParser.parse();
          } else if (resource == null && url != null && mapperClass == null) {
            ErrorContext.instance().resource(url);
            InputStream inputStream = Resources.getUrlAsStream(url);
            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 {
            throw new BuilderException("A mapper element may only specify a url, resource or class, but not more than one.");
          }
        }
      }
    }
  }

上面代码会加载mapper.xml文件然后使用XMLMapperBuilder去解析xml,代码来到 org.apache.ibatis.builder.xml.XMLMapperBuilder#parse

 public void parse() {
    if (!configuration.isResourceLoaded(resource)) {
    //解析mapper.xml中的              
关注
打赏
1651329177
查看更多评论
0.0593s