背景

在前两天的一次面试中,面试官问了一个和标题相同的问题,因为一向以为MyBatis仅仅一个ORM结构,所以并没有对他有过深入的了解,于是被问到了,那么这一篇文章来从源码探求一下MyBatis是怎样履行一条SQL变量英语句子的。

阅览环境

源码环境,github直接下载的main分支代码,版别号为giti 3.5.11-SNAPSHOT
github点击跳转

Ide Jetbrain Idea 2021.json解析2.1 社区版
Maven 3.8.2
JDK 17

装备giti文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
  <environments default="development">
    <environment id="development">
      <transactionManager type="JDBC"/>
      <dataSource type="POOLED">
        <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://******/**"/>
        <property name="username" value="****"/>
        <property name="password" value="******"/>
      </dataSource>
    </environment>
  </environments>
  <mappers>
    <mapper resource="LogChartMapper.xml"/>
  </mappers>
</configuration>

github中文官网网页验主办法

public class Main {
  public static void main(String[] args) throws IOException {
    InputStream resourceAsStream = Resources.getResourceAsStream("mybatis-config.xml");
    SqlSessionFactory build = new SqlSessionFactoryBuilder().build(resourceAsStream);
    SqlSession sqlSession = build.openSession();
    LogChartMapper mapper = sqlSession.getMapper(LogChartMapper.class);
    List<LogChart> logCharts = mapper.selectList();
    System.out.println(JSONUtil.toJsonStr(logCharts));
  }
}

mapper

public interface LogChartMapper {
  @Select(value = "select * from log_chart")
  List<LogChart> selectList();
}

mapper.xml

<?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="org.mybatis.test.mapper.LogChartMapper">
</mapper>

阅览过程

加载XML的过程

从上方的测验主办法能gitlab够看到,比较重要的是 SqlSessionFactory,第一步需elementui要看的便是他是被怎样构建出来的,点击build办法,跟进去。

MyBatis是怎样履行一条SQL句子的
Buijson格式ldelementary翻译办法追到最下面,构建了一个XMLConfigBuilder,那么这个Parser办法,有必要进去看一下。

MyBatis是怎样履行一条SQL句子的

这段代码比较简略,能够看到两个信息点。第一个回来的类型是Configuration类json格式怎么打开,调用了一个parseConfiguration办法,而且传入的configuration的xml节点。
说明办法进入是对的,后续咱们继续跟一下 parseCojson格式nfiguration办法

MyBatis是怎样履行一条SQL句子的

针对这个办法,看到几个眼熟的东西。分别是解析 pelement翻译lugins、json怎么读objectFactory、mappers 这些标签的。其他的咱们这儿不关心,咱们首要看一下处理 Mappers 标签的这个办法。

MyBatis是怎样履行一条SQL句子的

这儿经过遍历咱JSON们写的每个mapper标签,会得到rjson是什么意思esource、url、mapperClass这三个变量。他们在装备时是互斥的。 这儿的三个if,也对应了每个不为空的情况。

详细的每个属性代表什么意思,能够参考 > 跳转链接

咱们的XML运用的是Resources属性,能够回到上面翻XML,咱们这儿看Resource标签不为空的 if 判别即可。

MyBatis是怎样履行一条SQL句子的
这儿留意看,json格式Myabtis去读取了M面试官问你还有什么问题要问吗appgithub永久回家地址er指向的xml,然后new了一个XmlMapperBuilder,随后调用了parse办法,这儿的逻辑和刚刚开头elementary翻译的当地很相似。值得留意的是在创建XmlMapperBuilder的时分吧变量英语Configuration传了进去,也便是说在parse中是会改gitee动这个configura面试官tion里边的东西的变量名的命名规则。到这儿接着往里边跟代码。

MyBatis是怎样履行一条SQL句子的

看姓名有两个elementanimation比较重要的办法,Configur面试官如何提问面试者ationElement、binMapperForNameScpa变量与函数ce。
configurationElement 看这个办法的入参giti,大概率是对XML做一些处理,像ResultMaJSONp、sql、select这些标签做处理,我这儿没有用到就不说了,感兴趣的能够自己阅览一下。

后边首要看一下BindMapperForNameSpace办法。

创建Mapper

MyBatis是怎样履行一条SQL句子的

上面的代码中,看到了AddMapper这个办json格式怎么打开法,传入的值,是刚刚xml中装备的nameSpace,也便是Mapper类的完整类名,追进去看一下。

MyBatis是怎样履行一条SQL句子的
面试官如何提问面试者到这儿,知道了一个知识点,为什么Mapper类必定要是 Ijson解析nterface,假如不是interface,这个办法就进不来了。

留意看了,有一个细节,向knownMa变量名的命名规则pper面试官英语s中,以这个class为键,放入了一个MapperProxyFactory。到达这儿,就能够json格式得知。一变量名切的Mapper办法,都是由署理类去调用的。

接下来往elements下,json格式怎么打开又看到一个相似的,parse办法,看他的类名 MapperAnnotationBuilder 是用来处理注解的,面试官问你觉得你的优势在哪里往里追看一下。

MyBatis是怎样履行一条SQL句子的

这儿的圈出来的 IF 判别,判别办法上有Select 或许 SelectProvider注解,而且没有ResultMap注解的。会去解析ResultMap,这面试官面试流程话术儿大概率是依据回来值,去遍历属性这儿就跳过了,进入下elements一个办法。

parseStatement办法像是去解析办法了,代码有点多,这儿就不粘贴了,感兴趣能够自己看一下,知道这儿是去解析办法就能够json格式了。

到这儿完毕,最终回来了SqlSessionFactogiti轮胎ry类。

取得一个Mapper

SqlSessionFactory build = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = build.openSession();
LogChartMapper mapper = sqlSession.getMapper(LogChartMapper.class);

直接追进去,看看代码。

MyBatis是怎样履行一条SQL句子的

knownMapper 这个目标很眼熟是不是,这个在上面有提到过,以Class为Key,value时MapperProxyFactory,所以这儿能够Get出来一个工厂,然后点用了newInstance办法,追进去看一下。

MyBatis是怎样履行一条SQL句子的

这儿看到是Java原生的动态署理,这儿回来的是一个署理目标。

履行一个Mapper的办法

因为看到这儿时Java的动态署理,所以也很显而易见的得知。MapperProxy完成变量值了Invocat面试官ionHandler接口。

MyBatis是怎样履行一条SQL句子的

完成这个接口,会重写Invoke办法。也便是说,咱们尽管代码上写的是调用的咱们Mapper中指向的办法,但是其实jvm会去调用这个invoke办法,接下来直接去追Invoke办法。

MyBatis是怎样履行一条SQL句子的

因为咱们mapper是接口,所以上面的if是为false的,也便是else是咱element翻译们履行的代码,接着往里追。

MyBatis是怎样履行一条SQL句子的

这儿能够看到new了一个PlainMethodInvoker,然后调用他的i面试官的面试技巧有哪些nvoke办法,追进来。

MyBatis是怎样履行一条SQL句子的

接下来这个Execute便是他的详细履行Select句子的当地了。

MyBatis是怎样履行一条SQL句子的

MyBatis是怎样履行一条SQL句子的
因为后边的代码有点长,我这儿就摘取了一小段要害的当地。看一下即可。

结论

好了,到这儿就完毕了,下次再遇到这个问题就知道怎样回答了,我总结一个完整的。

MyBatis先读取装备文件生成一个configuration目标,然后会生成对应的XmlParseBuilder,在对应的XmlParseBuilder会向configuration中的knowMapper中,放入对应的Maelement是什么意思pperProxyjson是什么意思Factoryjsonobject。然后要履行mapper办法的时分,会经过mapperProxyFactorgithuby拿到一个Ma变量之间的关系pper的动态署理目标。随后会动态署理目标会依据当前的办法去判别调用Sql变量Sesjson怎么读sion的不同的办法来履行Sql句子。

都看到这了,点个赞再走吧宝~

完毕语

写文章的意图是为了协json助自己巩固知识,写的不好或许过错的当json怎么读地能够在谈论区指出。假如您看了文章觉得对您有所协助能够点Element个赞,假如发现有些问题产生了疑问,或许不面试官放弃录用的暗示明白的能够谈论、加我微信,必定各抒己见。当然也期望和我们交个朋友json怎么读,彼此学习。