第四篇 mybatis的运行原理(1):重要组件的介绍

一、组件介绍

相比其他框架,mybatis的组件构成还是相对简单的,下面是网络上比较常见的一张图,关于mybatis的执行流程,其中是mybatis的最常用的组件:


  在来学习mybatis的源码和底层原理之前,先来了解各大组件的作用和生命周期:
    (1)SqlSessionFactoryBuilder
                  SqlSessionFactoryBuilder是利用XML或者Java编码获得资源来构建SqlSessionFactory的,通过它可以构建多个SqlsessionFactory,它的作用就是一个构建器,一旦创建SqlSessionFactory,
           它的作用就会消失,所以构建SqlsessionFactory成功后会废弃回收。所以的它的生命周期只存在于方法的局部,它的作用就是生成SqlSessionFactory对象。

(2)SqlSessionFactory对象
                SqlSessionFactory的作用就是创建SqlSession,Sqlsession相当于JDBC中的Connection对象,每次访问数据库都需要创建SqlSession,前面的文章就已经说过,一个SqlSessionFactory对应一个数据库,
           那么能不能多个对应一个数据库了?是可以的,但是这样做的话,有多个SqlSessionFactory就会有很多的数据库连接,这样会导致数据库连接资源容易耗尽,且不易管理数据库连接,所以,mybatis的设计采用的单例
           模式,这样可以更有效的管理数据库的资源分配。由于SqlSessionFactory一直维护着SqlSession的创建,所以SqlSessionFactory的生命周期是框架运行的整个过程。

(3)SqlSession
               SqlSession对象时连接数据库的通道,更准确地说是访问数据库的一次会话,当发起访问数据库的请求时,创建一个SqlSession对象,请求完成关闭SqlSession。  要注意的是,SqlSession是一个线程不安全的对象,
         在涉及多线程的时候,要保证操作数据库的隔离级别 、数据库锁等高级特性,此外,SqlSession使用完成后都必须及时的关闭,避免占用连接资源,导致数据库宕机

(4)Mapper
               Mapper是一个接口,它的作用是发送SQL,当然,作为接口,当然不能执行SQL, 所以Mapper是代理方式完成这一操作, 然后返回我们需要的结果,或者执行SQL从而修改数据库的数据,具体实现,后面会说。
        因此,Mapper是一个方法级别的东西,当SqlSession销毁时,Mapper也会随之销毁。

二、SqlSessionFactory的创建

前面已经知道了mybatis的使用,执行流程以及重要的组件构成,但是对于一名开发者来说,知道这些远远不够,学习mybatis的底层原理,可以帮我们更好解决框架使用中的问题,甚至可以修改框架或者自定义插件来满足我们的业务需求。
 所以我们从源码层面一步一步走mybatis的执行流程。 首先,从mybatis加载解析mybatis的配置文件mybatisConfig.xml开始。我们先来看看我们是如何创建SqlSessionFactory的:

  /*资源*/
   InputStream is = UserService.class.getClassLoader().getResourceAsStream("mybatis/mybatisConfig.xml")
   /*创建SqlSessionFactory*/
   SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);

由上述代码可以看出SqlSessionFactory的创建是依托于SqlSessionFactoryBuilder类的build方法,打开该类SqlSessionFactoryBuilder由众多形式的build方法组成,尽管方法有很多,但是目的只有一个那就是

解析资源,创建SqlSessionFactory,所以我们以public SqlSessionFactory build(InputStream inputStream)为例深入

   public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
        try {
          /*解析xml文件,封装成一个XMLConfigBuilder对象*/
          XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
          /*生成一个参数类Configuration对象,然后通过该参数类创建DefaultSqlSessionFactory对象*/
          Configuration config = parser.parse();
          return build(config);
        } catch (Exception e) {
          throw ExceptionFactory.wrapException("Error building SqlSession.", e);
        } finally {
          ErrorContext.instance().reset();
          try {
            inputStream.close();
          } catch (IOException e) {
            // Intentionally ignore. Prefer previous error.
          }
        }
      }

      public SqlSessionFactory build(Configuration config) {
        return new DefaultSqlSessionFactory(config);
      }

    }

java对于xml文件资源的解析有dom解析,sax解析,dom4j解析,mybatis使用的dom方式,具体xml会在别的文章中说到,xml解析会得到一个  XMLConfigBuilder对象,

之后,XMLConfigBuilder对象会通过parse方法初始为一个Configuration对象,看看Configuration对象的内部,

public class Configuration {

  protected Environment environment;

  protected boolean safeRowBoundsEnabled = false;
  protected boolean safeResultHandlerEnabled = true;
  protected boolean mapUnderscoreToCamelCase = false;
  protected boolean aggressiveLazyLoading = true;
  protected boolean multipleResultSetsEnabled = true;
  protected boolean useGeneratedKeys = false;
  protected boolean useColumnLabel = true;
  protected boolean cacheEnabled = true;
  protected boolean callSettersOnNulls = false;
  protected String logPrefix;
  protected Class <? extends Log> logImpl;
  protected LocalCacheScope localCacheScope = LocalCacheScope.SESSION;
  protected JdbcType jdbcTypeForNull = JdbcType.OTHER;
  protected Set<String> lazyLoadTriggerMethods = new HashSet<String>(Arrays.asList(new String[] { "equals", "clone", "hashCode", "toString" }));
  protected Integer defaultStatementTimeout;
  protected ExecutorType defaultExecutorType = ExecutorType.SIMPLE;
  protected AutoMappingBehavior autoMappingBehavior = AutoMappingBehavior.PARTIAL;
.....
.....

从熟悉的变量名就可以联想到这个对象就是xml文件里对mybatis配置属性,那为什么这些属性不直接放到DefaultSqlSessionFactory类里面去了,这主要是由于创建SqlSessionFactory

需要的参数复杂,如果直接放到类的构造方法里面,这会导致大量的逻辑存在于类的构造方法中,所以使用一个参数类总领全局,分步构建,可以有效降低这种逻辑混乱的问题。

所以Configuration 对象也SqlSessionFactory创建过程中最重要的一个类。甚至mybatis的大多数的配置都是源于Configuration ,

Configuration 对象的作用:

1. 读取配置文件,包括初始化xml和映射器xml

2. 初始化基础配置,如果xml文件里set和typehandle

3. 提供单例,生成单例,为之后生成session提供配置

4. 执行一些重要的对象方法,如构建构造器executor等。
SqlSessionFactory接口有两个实现类:DefaultSqlSessionFactory类和SqlSessionManager类,但是是使用DefaultSqlSessionFactory创建SqlSessionFactory对象,下一篇将会剖析DefaultSqlSessionFactory具体的创建过程

原文地址:https://www.cnblogs.com/zhexuejun/p/11233041.html

时间: 2024-10-03 00:13:43

第四篇 mybatis的运行原理(1):重要组件的介绍的相关文章

开启 J2EE(四)—JSP及运行原理

JSP之了解 全称Java Server Pages,通过在HTML中嵌套Java代码实现动态网页. 可以从下面四个方面去认识一下JSP: 1.动态内容模板 动态的HTML,接受处理客户的请求,可以填充不同的业务逻辑. 2.使用定制的Java代码扩展HTML 本质是对标签的动态更新.JSP生成的标签代码可以是HTML也可以是XML等其它标签语言. 3.被编译成Servlet 本质是Servlet,在开发阶段JSP是一种文本的脚本的基于模板化的语言,运行时会被编译成Servlet的格式,执行的生命

nginx之旅(第四篇):nginx限速原理、nginx限速场景、nginx限速实现

一.nginx限速 在生产环境中,为了保护WEB服务器的安全,我们都会对用户的访问做出一些限制,保证服务器的安全及资源的合理分配. 限流(rate limiting)是NGINX众多特性中最有用的,也是经常容易被误解和错误配置的,特性之一访问请求限速.该特性可以限制某个用户在一个给定时间段内能够产生的HTTP请求数.请求可以简单到就是一个对于主页的GET请求或者一个登陆表格的POST请求.用于安全目的上,比如减慢暴力密码破解攻击.通过限制进来的请求速率,并且(结合日志)标记出目标URLs来帮助防

02 js运行原理 、js开发工具介绍 、js程序入门、 js基本语法

因为js是由浏览器来解释执行的,因此这里有一个问题,不同的类型的浏览器可能对js的支持不一样. js的运行一般分为:本地运行和远程运行 Tomcat架在公网上,其他网络用户可以访问,利用花生壳可以把一个内网的ip映射为公网 花生壳相当于用自己的服务器帮你转了一下而已. 如何选择开js发工具 微软的vs   .net平台 Eclipse 我们先选择用记事本,到了对Javascript 有了一定的了解后,我们再使用高级开发工具Eclipse. ①更深刻的理解javascript技术,培养代码感. ②

手写MyBatis,纯手工打造开源框架(第四篇:决胜千里)- 第272篇

说明 MyBatis版本:3.5.1 相关历史文章(阅读本文之前,您可能需要先看下之前的系列) Spring Boot MyBatis最全教程:你值得拥有MyBatis能脱离Spring吗一图纵览MyBatis的工作原理从源码看MyBatis,竟如此简单MyBatis的Mapper是什么`垃圾` 手写MyBatis,纯手工打造开源框架(第一篇:风云再起) 手写MyBatis,纯手工打造开源框架(第二篇:君临天下) 手写MyBatis,纯手工打造开源框架(第三篇:运筹帷幄) 前言        运

Nodejs的运行原理-libuv篇

前言 这应该是Nodejs的运行原理的第7篇分享,这篇过后,短时间内不会再分享Nodejs的运行原理,会停更一段时间,PS:不是不更,而是会开挖新的坑,最近有在研究RPG Maker MV,区块链,云计算,可能会更新一些相关文章,或者相关教学. 回到正题,异步编程的难点在于请求与响应不是按顺序发生的.以http server 为例,异步编程赋予了server 高并发的品质,而且他可以以很小的资源代价,不断地接受和处理请求.但是快速处理请求不表示快速地返回请求=>高并发不等同于快速反馈. 在Nod

互联网轻量级框架SSM-查缺补漏第七天(MyBatis的解析和运行原理)

简言: 第七章MyBatis的解析和运行原理 SqlSessionFactory是MyBatis的核心类之一,其最重要的功能就是提供创建MyBatis的核心借口SqlSession,所以要先创建SqlSessionFactory,为此要提供配置文件和相关的参数.MyBatis是一个复杂的系统,它采用了Builder模式去创建SqlSessionFactory,在实际上可以通过SqlSessionFactoryBuilder去创建,分为两步: SqlSessionFactory = new Sql

MyBatis(7)——运行原理

一.框架架构 1.先初始化SqlSessionFactory对象: MyBatis(8)--运行原理-初始化SqlSessionFactory 2.使用sqlSessionFactory对象获取SqlSession对象: MyBatis(9)--运行原理-获取SqlSession对象 3.使用SqlSession的getMapper方法获取接口的代理对象: MyBatis(10)--运行原理-getMapper获取接口的代理对象 4.最后调用mapper的查询方法: MyBatis(11)--运

Python学习笔记——进阶篇【第八周】———CPU运行原理与多线程

CPU运行原理与多线程 什么是线程(thread)? 线程是操作系统能够进行运算调度的最小单位.它被包含在进程之中,是进程中的实际运作单位.一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务 进程是容器,线程是真正执行的任务单元

Nodejs的运行原理-科普篇

前言 Nodejs目前处境稍显尴尬,很多语言都已经拥有异步非阻塞的能力.阿里的思路是比较合适的,但是必须要注意,绝对不能让node做太多的业务逻辑,他只适合接收生成好的数据,然后或渲染后,或直接发送到客户端. 为什么nodejs 还可以成为主流技术哪? 是因为nodejs 对于大前端来说还是非常重要的技术!!!如果你理解nodejs 的编程原理,很容易就会理解angularjs,reactjs 和vuejs 的设计原理. NodeJS Node是一个服务器端JavaScript解释器,用于方便地