Mybatis在使用前需进行初始化,下面就针对Mybatis的初始化过程进行介绍。Mybatis的初始化过程有两种:基于XML和基于Java API两种方式,下面就针对基于XML的方式进行展开。

一、Mybatis初始化的基本过程

Mybatis的初始化过程如下图所示:

  1. 调用 SqlSessionFactoryBuilder 对象的 build(inputStream) 方法;
  2. SqlSessionFactoryBuilder 会根据输入流 inputStream 等信息创建XMLConfigBuilder 对象 ;
  3. SqlSessionFactoryBuilder 调用 XMLConfigBuilder 对象的 parse() 方法;
  4. XMLConfigBuilder 对象返回 Configuration 对象;
  5. SqlSessionFactoryBuilder 根据 Configuration 对象创建一个DefaultSessionFactory 对象;
  6. SqlSessionFactoryBuilder 返回 DefaultSessionFactory 对象给 Client ,供 Client使用。

上面涉及到的对象有:

  • SqlSessionFactoryBuilder :SqlSessionFactory的构造器,用于创建SqlSessionFactory,采用了Builder设计模式

  • Configuration :该对象是mybatis-config.xml文件中所有mybatis配置信息

  • SqlSessionFactory:SqlSession工厂类,以工厂形式创建SqlSession对象,采用了Factory工厂设计模式

  • XmlConfigParser :负责将mybatis-config.xml配置文件解析成Configuration对象,供SqlSessonFactoryBuilder使用,创建SqlSessionFactory

下面针对这些对象进行展开。

二、SqlSessionFactory的创建

SqlSessionFactory是MyBatis中的一个主要接口,其主要负责MyBatis框架初始化操作及提供SqlSession对象。

public interface SqlSessionFactory {

  SqlSession openSession();

  SqlSession openSession(boolean autoCommit);
SqlSession openSession(Connection connection);
SqlSession openSession(TransactionIsolationLevel level); SqlSession openSession(ExecutorType execType);
SqlSession openSession(ExecutorType execType, boolean autoCommit);
SqlSession openSession(ExecutorType execType, TransactionIsolationLevel level);
SqlSession openSession(ExecutorType execType, Connection connection); Configuration getConfiguration(); }

它有两个实现类:DefaultSqlSessionFactorySqlSessionManager,其中SqlSessionManager已被废弃。在Mybtis初始化的过程中首先会读取Mybatis的核心配置文件,一般创建SqlSessionFactory的代码如下:

InputStream is = Resources.getResourceAsStream("myBatis-config.xml");
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(is);

首先得到Mybatis核心配置文件的位置,得到InputStream,将其传给SqlSessionFactoryBuilder的build方法,以下为SqlSessionFactoryBuilde中创建SqlSessionFactory对象的方法:

public SqlSessionFactory build(Reader reader);
public SqlSessionFactory build(Reader reader, String environment);
public SqlSessionFactory build(Reader reader, Properties properties);
public SqlSessionFactory build(Reader reader, String environment, Properties properties); public SqlSessionFactory build(InputStream inputStream);
public SqlSessionFactory build(InputStream inputStream, String environment);
public SqlSessionFactory build(InputStream inputStream, Properties properties)
public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties); public SqlSessionFactory build(Configuration config);

SqlSessionFactoryBuilder是Builder模式中建造者,负责SqlSessionFactory对象的创建以及SqlSessionFactroy对象内部所需要内容的组装。其中,前八个方法都是通过读取XML文件得到XMLConfigBuilder,再调用parse()方法得到Configuration对象,从而产生SqlSessionFactory对象。核心代码如下:

XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
return build(parser.parse());

当得到一个XMLConfigBuilder后,调用parse()方法,这里采用了建造者设计模式,将XML文件中的配置读取出来,得到Configuration对象。

public Configuration parse() {
if (parsed) {
throw new BuilderException("Each XMLConfigBuilder can only be used once.");
}
parsed = true;
parseConfiguration(parser.evalNode("/configuration"));
return configuration;
} private void parseConfiguration(XNode root) {
try {
//issue #117 read properties first
propertiesElement(root.evalNode("properties"));
Properties settings = settingsAsProperties(root.evalNode("settings"));
loadCustomVfs(settings);
typeAliasesElement(root.evalNode("typeAliases"));
pluginElement(root.evalNode("plugins"));
objectFactoryElement(root.evalNode("objectFactory"));
objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
reflectorFactoryElement(root.evalNode("reflectorFactory"));
settingsElement(settings);
// read it after objectFactory and objectWrapperFactory issue #631
environmentsElement(root.evalNode("environments"));
databaseIdProviderElement(root.evalNode("databaseIdProvider"));
typeHandlerElement(root.evalNode("typeHandlers"));
mapperElement(root.evalNode("mappers"));
} catch (Exception e) {
throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e);
}
}

注:Builder模式,称为[建造者设计模式],使用多个简单的对象一步一步构建一个复杂的对象。这种模式属于[创建型模式],目前它是创建对象的最佳模式。

得到Configuration对象后,将得到的Configuration对象调用build方法创建DefaultSqlSessionFactory对象。

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

在实际调用时,SqlSessionFactory创建过程的基本写法如下:

InputStream is = Resources.getResourceAsStream("myBatis-config.xml");
SqlSessionFactoryBuilder builderObj = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builderObj.build(is);

三、SqlSession原理

SqlSession提供select/insert/update/delete方法,在旧版本中使用SqlSession接口的这些方法,新版本中建议使用Mapper接口的方法。从底层实现来说,Mapper接口方法的实现底层还是采用SqlSession接口方法实现的。SqlSession四个重要对象:

  • Execute:调度执行StatementHandler、ParmmeterHandler、ResultHandler执行相应的SQL语句;

  • StatementHandler:使用数据库中Statement(PrepareStatement)执行操作,即底层是封装好了的prepareStatement;

  • ParammeterHandler:处理SQL参数;

  • ResultHandler:结果集ResultSet封装处理返回。

后面会针对四个对象分别进行说明。

四、Configuration介绍

MyBatis框架支持开发人员通过配置文件与其进行交流,在配置文件所配置的信息,在框架运行时会被XMLConfigBuilder解析并存储在一个Configuration对象中。Configuration对象会被作为参数传送给DeFaultSqlSessionFactory,而DeFaultSqlSessionFactory根据Configuration对象信息为Client创建对应特征的SqlSession对象。

五、Mybatis生命周期

  • SqlSessionFactoryBuilder:用于创建SqlSessionFactory,一旦SqlSessionFactory创建成功,就会被回收。

  • SqlSessionFactory:用于创建SqlSession,类似于JDBC的Connection对象,而每次应用程序需要访问数据库,都要创建SqlSession,所以SqlSessionFactory在整Mybatis整个生命周期中。(每个数据库对应一个SqlSessionFactory,是单例产生的)

  • SqlSession:生命周期是存在于请求数据库处理事务的过程中,是一个线程不安全的对象(在多线程的情况下,需要特别注意),即存活于一个应用的请求和申请,可以执行多条SQL保证事务的一致性。

  • Mapper:是一个接口,没有实现类。它的作用是发送SQL,返回结果,或修改数据库表,所以它存活于一个SqlSession内,是一个方法级别的东西。当SqlSession销毁的时候,Mapper也会销毁。

Mybatis之SessionFactory原理的更多相关文章

  1. 深入理解Mybatis技术与原理

    目录 第1章 Mybatis简介 1.1 传统的JDBC编程 1.2 ORM模型 1.4 MyBatis 1.5 什么时候用MyBatis 第2章 MyBatis入门 2.2 MyBatis构成 2. ...

  2. mybatis(一、原理,一对多,多对一查询)

    MyBatis框架及原理分析 MyBatis 是支持定制化 SQL.存储过程以及高级映射的优秀的持久层框架,其主要就完成2件事情: 封装JDBC操作 利用反射打通Java类与SQL语句之间的相互转换 ...

  3. Mybatis之工作原理

    1.Mybatis的架构 1.1 Mybatis的框架分层 1.2 MyBatis的实现原理 mybatis底层还是采用原生jdbc来对数据库进行操作的,它支持定制化 SQL.存储过程以及高级映射的优 ...

  4. Mybatis接口编程原理分析(三)

    前面两篇博客Mybatis接口编程原理分析(一)和Mybatis接口编程原理分析(二)我们介绍了MapperProxyFactory.MapperProxy和MapperMethod的操作及源码分析, ...

  5. Mybatis接口编程原理分析(二)

    在上一篇博客中 Mybatis接口编程原理分析(一)中我们介绍了MapperProxyFactory和MapperProxy,接下来我们要介绍的是MapperMethod MapperMethod:它 ...

  6. mybatis 插件的原理-责任链和动态代理的体现

    目录 1 拦截哪些方法 2 如何代理 3 代理对象 4 责任链设计模式 @ 如果没有自定义过拦截器, 可以看我前面的文章.如果不知道 JDK 动态代理怎么使用的, 可以看我这文章. 责任链设计模式理解 ...

  7. Mybatis简介与原理

    经常面试别人或者被面试,对Mybatis简介与原理这个问题的回答千差万别,为了更好的服务与以后,来个原理介绍. 什么是Mybatis MyBatis 本是apache的一个开源项目iBatis, 20 ...

  8. MyBatis整合Spring原理分析

    目录 MyBatis整合Spring原理分析 MapperScan的秘密 简单总结 假如不结合Spring框架,我们使用MyBatis时的一个典型使用方式如下: public class UserDa ...

  9. 深入详解Mybatis的架构原理与6大核心流程

    MyBatis 是 Java 生态中非常著名的一款 ORM 框架,目前在一线互联网大厂中应用广泛,Mybatis已经成为了一个必会框架. 如果你想要进入一线大厂,能够熟练使用 MyBatis 开发已经 ...

随机推荐

  1. 在cad2008引用了错误的com接口的dll导致出现了

    请求“System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.0.0, Culture=neutral, Publi ...

  2. Linux下查看文档指令

    1,cat直接查看 cat /etc/profile 2,more,less分页查看 less  /etc/profile more /etc/profile less -N /etc/profile ...

  3. shell环境改变引起的命令提示符改变

    1. 故障现象与背景 1.1 背景 开发早上找我说root环境变得异常,跟平时不太一样.其他用户没有改变,就root用户发生变化 1.2故障现象 root用户命令提示符 :➜ ~ 命令行上命令提示符发 ...

  4. Liferay开发实战(2):Service Builder生成持久化层,及开发服务层

    本文Liferay适用版本:v6.2.ce-ga6版 Liferay的插件体系是:模型-视图-控制器的portlet MVC框架.MVC是一个伟大的用于Web应用程序的设计模式,在实际应用中还应处理持 ...

  5. Hadoop框架之HDFS的shell操作

    既然HDFS是存取数据的分布式文件系统,那么对HDFS的操作,就是文件系统的基本操作,比如文件的创建.修改.删除.修改权限等,文件夹的创建.删除.重命名等.对HDFS的操作命令类似于Linux的she ...

  6. ORACLE数据库表解锁record is locked by another user

    出现此问题多由于操作Oracle执行完,没有COMMIT,直接把PL/SQL关闭掉,后来导致那张表被锁住,当编辑时就会出现这个信息,record is locked by another user! ...

  7. (转)X-Frame-Options响应头缺失漏洞

    原文:https://blog.csdn.net/ljl890705/article/details/78071601 x-frame-options响应头缺失漏洞. 故名思意,就是返回的响应头信息中 ...

  8. Python -- 网络编程 -- 简单抓取网页

    抓取网页: urllib.request.urlopen(url).read().decode('utf-8')  ---  (百度是utf-8,谷歌不是utf-8,也不是cp936,ascii也不行 ...

  9. postgresql进程及内存结

    一.进程和内存架构图 postgresql数据库启动时,先启动一个postmaster的主进程,然后fork出一些辅助子进程. 二.主进程postmaster -bash-4.2$ which pos ...

  10. Nginx图片防盗链【实战】

    访问我的博客 前言 博主目前在一家原创小说网站公司工作,由于站内的作品全部是原创,于是乎不可避免地会被一些盗版网站爬取盗版,对于防盗版一直没有很好的对策,让公司很是苦恼. 最近去一些盗版网站上搜索我们 ...