MyBatis源码解析——获取SqlSessionFactory方式

 更新时间:2021年12月16日 10:31:38   作者:rz_0212  
这篇文章主要介绍了MyBatis源码解析——获取SqlSessionFactory方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

MyBatis源码解析_获取SqlSessionFactory

我们都知道,在Mybatis中,对数据库的增删改查,实际上是由SqlSession来操作的,而SqlSession又是从SqlSessionFactory中得到的,那么问题来了,SqlSessonFactory是如何获得的呢?我们一起来解读一下Mybatis是如何加载配置文件,从而获取SqlSessionFactory的。

首先从Resources.getResourceAsReader(path)

传入我们mybatis全局配置文件得到一个输入流InputStream,这里用Reader来接收。然后new一个SqlSessionFactoryBuilder对象,这是干嘛呢,这个对象里有一个build(Reader)方法,可以将我们传入的Reader,经过一系列的解析过程,返回给我们一个SqlSessionFactory实例,这样我们就得到了想要的SqlSessionFactory了,估计要是这么就结束了,读者会不会打死我呀(哈哈)。

所以我们就详细说一下中间的解析过程。

进入到SqlSessionFactoryBuilder.build(Reader)方法中

它会再次调用build(Reader,environment(默认是null),Properties(默认是null))方法,在这里,根据我们传入的参数先new出一个XMLConfigBuilder对象,称为parser(就是个解析器),然后parser调用它的parse()方法,parse()方法中有一个parseConfiguration(parser.evalNode("/configuration"))方法,我们知道mybatis的全局配置文件是以configuration作为根节点的,而且各个子节点是有严格顺序的,这里就是找到configuration根节点,来分别解析根节点下的每个子节点,然后将解析结果放在一个Configuration中。

解析节点是调用XpathParser.evalNode(root , expression),返回一个XNode,当作参数,放在一个**Element(XNode)方法中去处理节点里每一个信息。这里我们选一个mapperElement(root.evalNode("mappers"))来看看,它是如何解析mappers这个子节点的。

进入到mapperElement(XNode)方法后

先去判断传入的节点是否为null,不为null则解析XNode下的每一个孩子节点,(在mappers标签下,可以插入两种子节点,一种是package,这种做法,要求接口和xml文档在同一个包下,另一种是mapper,mapper节点里有三种属性,分别是resource,url,class,至多只能选一种)。

这里我我们来判断子节点名字是否为"package",如果是,将package节点中的name取出,调用Configuration.addMappers(mapperPackage)方法,实际上调用MapperRegistry.addMappers(packeagename)方法,在这里,又new出了一个ResolverUtil<Class<?>>对象resolverUtil,它可以通过find()方法,找到该包下所有的所有的class或是别的文件,然后筛选出所有.class文件(不是class文件不要),如果是接口的话(不是接口不管),new出一个MapperAnnotationBuilder对象parser(实际上也是个解析器),调用parser.parse()方法,加载与接口名相同的XML文件,保存在configuration中。

如果子节点名字不是package

则取出"resource"、"url"、"class"等属性,分别进行判空,如果属性resource中有值,先将resource所对应的xml文件给转成一个InputStream,再new出一个XMLMapperBuilder(inputStream,configuration,resource)对象mapperParser(这里也是个解析器),调用parse()方法,对接口里所对应的XML文件去解析,具体解析过程和解析mybatis全局配置文件比较类似。

在解析每一个增删改查标签,都会new一个mappedStatement对象statement(这里是通过它的静态内部类Builder来new的),相当于一个MappedStatemet就代表了一个增删改查的详细信息 ,同样MappedStatement也保存在Configuration中。

对于url中有值,过程和resource那个一样,这里不作讲述。对于mapperClass中有值,通过全类名反射,拿到对应的接口,调用configuration.addMapper(mapperInterface)方法,具体过程和package那个一样,也不再讲述。

经过一系列的解析,终于完成了

mappers节点的所有信息也都保存在Configuration中。这个时候回到SqlSessionFactoryBuilder中,将返回的Configuration对象作为参数,调用它的build(configuration)方法,这里是关键的一步,此时根据configuration,new出了一个DefaultSqlSessionFactory对象返回给我们。

我们来看一下DefaultSqlSessionFactory这个类有啥特别的呢,它实现了SqlSessionFactory接口,这个接口里有很多openSession()的重载方法,原来如此,这里我们终于得到了SqlSessionFactory,也就是一个DefaultSqlSessionFactory对象,这个对象里保存着我们的Configuration,而Configuration里又保存着我们全局配置文件里的所有信息,以及**mapper.xml文件里所有信息。

如图所示。

好啦,SqlSessionFactory获取过程就讲到这里啦,想要了解更多细节的童鞋,也可以自己去一步步debug,跟踪源码,了解整个过程

用MyBatis的配置文件获取SqlSessionFactory

import java.io.IOException;
import java.io.Reader;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
public class GetSqlSessionFactory {
    private static SqlSessionFactory sqlSessionFactory;    
    static{
        String rs="mybatis-config.xml";
        try {
            Reader reader=Resources.getResourceAsReader(rs);
            SqlSessionFactoryBuilder builder=new SqlSessionFactoryBuilder();
            sqlSessionFactory=builder.build(reader);
            //sqlSessionFactory.getConfiguration().addMappers("com.hengtian.mapper");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }    
    public  static SqlSessionFactory getInstance(){
        return sqlSessionFactory;
    }    
}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • WIN10系统中添加bat脚本重启jar服务

    WIN10系统中添加bat脚本重启jar服务

    在bat脚本中执行java服务,命令与cmd中类似,下面这篇文章主要给大家介绍了关于WIN10系统中添加bat脚本重启jar服务的相关资料,文中通过图文介绍的非常详细,需要的朋友可以参考下
    2023-12-12
  • 利用Java获取文件名、类名、方法名和行号的方法小结

    利用Java获取文件名、类名、方法名和行号的方法小结

    这篇文章运用实例代码给大家介绍了利用Java怎样获取文件名、类名、方法名和行号,有需要的可以参考借鉴,下面一起来看看吧。
    2016-08-08
  • Java如何获取word文档的条目化内容

    Java如何获取word文档的条目化内容

    这篇文章主要介绍了Java获取word文档的条目化内容的相关知识,非常不错,具有一定的参考借鉴价值,需要的朋友参考下吧
    2018-05-05
  • 基于Spring Boot的Environment源码理解实现分散配置详解

    基于Spring Boot的Environment源码理解实现分散配置详解

    这篇文章主要给大家介绍了基于Spring Boot的Environment源码理解实现分散配置的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-08-08
  • 在Spring Boot中实现HTTP缓存的方法

    在Spring Boot中实现HTTP缓存的方法

    缓存是HTTP协议的一个强大功能,但由于某些原因,它主要用于静态资源,如图像,CSS样式表或JavaScript文件。本文重点给大家介绍在Spring Boot中实现HTTP缓存的方法,感兴趣的朋友跟随小编一起看看吧
    2018-10-10
  • 浅析Java中对称与非对称加密算法原理与使用

    浅析Java中对称与非对称加密算法原理与使用

    密码学是研究编制密码和破译密码的技术科学。这篇文章主要为大家介绍了Java中对称与非对称加密算法的原理与使用,感兴趣的小伙伴可以了解一下
    2023-03-03
  • JMeter断言之json断言解读

    JMeter断言之json断言解读

    这篇文章主要介绍了JMeter断言之json断言问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03
  • RabbitMQ简单队列实例及原理解析

    RabbitMQ简单队列实例及原理解析

    这篇文章主要介绍了RabbitMQ简单队列实例及原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-12-12
  • Java实现简单学生管理系统

    Java实现简单学生管理系统

    这篇文章主要为大家详细介绍了Java实现简单学生管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-07-07
  • Java 从json提取数组并转换为list的操作方法

    Java 从json提取数组并转换为list的操作方法

    这篇文章主要介绍了Java 从json提取出数组并转换为list,使用getJSONArray()获取到jsonarray后,再将jsonArray转换为字符串,最后将字符串解析为List列表,本文通过实例代码给大家详细讲解,需要的朋友可以参考下
    2022-10-10

最新评论