myBatis源码学习之SqlSessionFactory

myBatis源码学习之SqlSessionFactory/***Createsan{@linkSqlSesion}outofaconnectionoraDataSource**@authorClintonBegin*///SqlSessionFactory接口,通过openSession方法获得SQLSessionpublicinterfaceSqlSessionFactory{SqlS

大家好,又见面了,我是你们的朋友全栈君。

上一篇博客 SqlSessionFactoryBuilder 中介绍了它的作用就是获得DefaultSqlSessionFactory

 

SqlSessionFactory是一个接口,其具体实现类是DefaultSqlSessionFactory,通过类名我们可以看到SqlSessionFactory是一个SqlSession工厂,用来生产SqlSession对象,SqlSession中有我们进行数据库操作的增删改查接口

 

SqlSessionFactory源码及注释:

 

/**
 * Creates an {@link SqlSesion} out of a connection or a DataSource
 * 
 * @author Clinton Begin
 */
 //SqlSessionFactory接口,通过openSession方法获得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();

}

 

DefaultSqlSessionFactory构造函数主要设置了一些属性包括是否支持事务,事务的类型及隔离等级和sql语句的执行类型等。

DefaultSqlSessionFactory设置的事务的管理主要有三种方式:

(1)使用JDBC的事务管理机制,就是利用java.sql.Connection对象完成对事务的提交

(2)使用MANAGED的事务管理机制,这种机制mybatis自身不会去实现事务管理,而是让程序的容器(JBOSS,WebLogic)来实现对事务的管理

(3)不支持任何事务

DefaultSqlSessionFactory设置的事务的隔离等级有5个:

(1)Connection.TRANSACTION_NONE表示不支持事务的常量
(2)Connection.TRANSACTION_READ_COMMITTED不可重复读和虚读可以发生
(3)Connection.TRANSACTION_READ_UNCOMMITTED表示可以发生脏读 (dirty read)、不可重复读和虚读 (phantom read) 的常量
(4)Connection.TRANSACTION_REPEATABLE_READ虚读可以发生
(5)Connection.TRANSACTION_SERIALIZABLE指示不可以发生脏读、不可重复读和虚读的常量

DefaultSqlSessionFactory设置的sql语句操作类型有以下4个(到了sql执行时具体分析):

(1)BatchExecutor用于执行批量sql操作

(2)ReuseExecutor会重用statement执行sql操作

(3)SimpleExecutor简单执行sql操作

(4)CachingExecutor 在查找数据库前先查找缓存,若没有找到的话调用delegate从数据库查询,并将查询结果存入缓存中。

DefaultSqlSessionFactory源码及注释:

/**
 * @author Clinton Begin
 */
 //实现了sqlSessionFactory,
public class DefaultSqlSessionFactory implements SqlSessionFactory {

  private final Configuration configuration;

  //传入配置文件生成的对象,配置文件中包含了mybatis的所有配置信息
  public DefaultSqlSessionFactory(Configuration configuration) {
    this.configuration = configuration;
  }
  
  public SqlSession openSession() {
	//executor类型是默认的simple
    return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, false);
  }

  //autoCommit  true为不支持事务,false为支持事务
  public SqlSession openSession(boolean autoCommit) {
    return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, autoCommit);
  }

  public SqlSession openSession(ExecutorType execType) {
    return openSessionFromDataSource(execType, null, false);
  }
  // TransactionIsolationLevel 事务隔离等级,有5种,详见下面说明
  public SqlSession openSession(TransactionIsolationLevel level) {
    return openSessionFromDataSource(configuration.getDefaultExecutorType(), level, false);
  }

  //执行类型,有4种,BatchExecutor、ReuseExecutor、SimpleExecutor和CachingExecutor
  public SqlSession openSession(ExecutorType execType, TransactionIsolationLevel level) {
    return openSessionFromDataSource(execType, level, false);
  }

  public SqlSession openSession(ExecutorType execType, boolean autoCommit) {
    return openSessionFromDataSource(execType, null, autoCommit);
  }

  public SqlSession openSession(Connection connection) {
    return openSessionFromConnection(configuration.getDefaultExecutorType(), connection);
  }

  public SqlSession openSession(ExecutorType execType, Connection connection) {
    return openSessionFromConnection(execType, connection);
  }

  public Configuration getConfiguration() {
    return configuration;
  }
  //最终是获得一个sqlsession
  private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
    Transaction tx = null;
    try {
	  //获得配置文件中的environment配置
      final Environment environment = configuration.getEnvironment();
	  //事务工厂,通过xml配置文件中的transactionManager 元素配置的type来选择事务
	  //JDBC是直接全部使用JDBC的提交和回滚功能。它依靠使用链接的数据源来管理事务的作用域
	  //MANAGED这个类型什么都不做,它从不提交、回滚和关闭连接,而是让窗口来管理事务的全部生命周期
      final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
	  //TransactionIsolationLevel事务的隔离级别有5个
	  //Connection.TRANSACTION_NONE表示不支持事务的常量
	  //Connection.TRANSACTION_READ_COMMITTED不可重复读和虚读可以发生
	  //Connection.TRANSACTION_READ_UNCOMMITTED表示可以发生脏读 (dirty read)、不可重复读和虚读 (phantom read) 的常量
	  //Connection.TRANSACTION_REPEATABLE_READ虚读可以发生
	  //Connection.TRANSACTION_SERIALIZABLE指示不可以发生脏读、不可重复读和虚读的常量
	  //脏读:如果一个事务对数据进行了更新,但事务还没有提交,另一个事务就可以“看到”该事务没有提交的更新结果。这样造成的问题是,
	  //如果第一个事务回滚,那么第二个事务在此之前所“看到”的数据就是一笔脏数据。
      //不可重复读:指同个事务在整个事务过程中对同一笔数据进行读取,每次读取结果都不同。如果事务1在事务2的更新操作之前读取一次数据,
	  //在事务2的更新操作之后再读取同一笔数据一次,两次结果是不同的。所以TRANSACTION_READ_COMMITTED是无法避免不可重复读和虚读。 
      //幻读:指同样一个查询在整个事务过程中多次执行后,查询所得的结果集是不一样的。幻读针对的是多笔记录。
      tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
	  //execType是sql操作类型
	  //BatchExecutor用于执行批量sql操作
	  //ReuseExecutor会重用statement执行sql操作
      //SimpleExecutor简单执行sql操作
      //CachingExecutor 在查找数据库前先查找缓存,若没有找到的话调用delegate从数据库查询,并将查询结果存入缓存中。
      final Executor executor = configuration.newExecutor(tx, execType);
	  //返回SqlSession
      return new DefaultSqlSession(configuration, executor, autoCommit);
    } catch (Exception e) {
      closeTransaction(tx); // may have fetched a connection so lets call close()
      throw ExceptionFactory.wrapException("Error opening session.  Cause: " + e, e);
    } finally {
      ErrorContext.instance().reset();
    }
  }

  private SqlSession openSessionFromConnection(ExecutorType execType, Connection connection) {
    try {
      boolean autoCommit;
      try {
        autoCommit = connection.getAutoCommit();
      } catch (SQLException e) {
        // Failover to true, as most poor drivers
        // or databases won't support transactions
        autoCommit = true;
      }
	  //获得配置文件中的environment配置
      final Environment environment = configuration.getEnvironment();
	  //事务工厂,通过xml配置文件中的transactionManager 元素配置的type来选择事务
	  //JDBC是直接全部使用JDBC的提交和回滚功能。它依靠使用链接的数据源来管理事务的作用域
	  //MANAGED这个类型什么都不做,它从不提交、回滚和关闭连接,而是让窗口来管理事务的全部生命周期
      final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
      final Transaction tx = transactionFactory.newTransaction(connection);
	  //execType是sql操作类型
	  //BatchExecutor用于执行批量sql操作
	  //ReuseExecutor会重用statement执行sql操作
      //SimpleExecutor简单执行sql操作
      //CachingExecutor 在查找数据库前先查找缓存,若没有找到的话调用delegate从数据库查询,并将查询结果存入缓存中。
      final Executor executor = configuration.newExecutor(tx, execType);
	  //返回SqlSession
      return new DefaultSqlSession(configuration, executor, autoCommit);
    } catch (Exception e) {
      throw ExceptionFactory.wrapException("Error opening session.  Cause: " + e, e);
    } finally {
      ErrorContext.instance().reset();
    }
  }
  //事务工厂,mybatis对于事务的管理有两种形式,
  //(1)使用JDBC的事务管理机制,就是利用java.sql.Connection对象完成对事务的提交
  //(2)使用MANAGED的事务管理机制,这种机制mybatis自身不会去实现事务管理,而是让程序的容器(JBOSS,WebLogic)来实现对事务的管理
  private TransactionFactory getTransactionFactoryFromEnvironment(Environment environment) {
    if (environment == null || environment.getTransactionFactory() == null) {
	  //没有配置的话就使用manage形式
      return new ManagedTransactionFactory();
    }
    return environment.getTransactionFactory();
  }

  private void closeTransaction(Transaction tx) {
    if (tx != null) {
      try {
        tx.close();
      } catch (SQLException ignore) {
        // Intentionally ignore. Prefer previous error.
      }
    }
  }

}

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/143945.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • CImage 类

    CImage 类CImage提供增强的位图支持,包括加载和保存采用JPEG、GIF、BMP和可移植网络图形格式的图像(PNG)格式。说明无法在Windows运行时中执行的应用程序中使用此类及其成员。语法classCImage成员公共构造函数公共构造函数 “属性” 说明 CImage::CImage 构造函数。 公共方法公共方法 “属性” 说明 CImage::AlphaBlend 显示具有透明或半透明像素的位图。 CImage:.

  • linux连接蓝牙键盘_双系统蓝牙键盘切换

    linux连接蓝牙键盘_双系统蓝牙键盘切换后记:写完这篇文章后又先后重新连接过两次,每次都会下意识担心,完了完了这次可能再也连不上了(想起当初一直连不上双系统,被蓝牙键盘支配的日日夜夜),结果我按着自己写的这篇文章来搞,还不是每次都成功了hh.一、参考文献为了方便查阅,先列出参考文献。这些文章中有的内容已经过时,有的是配置的环境不一样。1.Ubuntu和Windows双系统蓝牙键盘配对——20142.Ubunt…

    2022年10月15日
  • JSP实用教程(基础入门教程)

    一、JSP技术概述  在Sun正式发布JSP(JavaServerPages)之后,这种新的Web应用开发技术很快引起了人们的关注。JSP为创建高度动态的Web应用提供了一个独特的开发环境。按照Sun的说法,JSP能够适应市场上包括ApacheWebServer、IIS4.0在内的85%的服务器产品。即使您对ASP”一往情深”,我们认为,关注

  • HikariPool-1 – Connection is not available, request timed out after 30000ms.

    HikariPool-1 – Connection is not available, request timed out after 30000ms.HikariPool是号称史上最快的数据库连接池,而且目前来看确实是这样的,SpringBoot2.0也已经采用HikariCP作为默认连接池配置.近期项目也将druid切成了HikariPool,但HikariPool仍然不够稳定,经常出现获取不到数据库连接,连接数不够的问题尝试修改HikariPool连接池配置,增大最大连接数,MaximumPoolSize由30改为100…

  • 如何使用ABAP代码反序列化JSON字符串成ABAP结构「建议收藏」

    如何使用ABAP代码反序列化JSON字符串成ABAP结构「建议收藏」如何使用ABAP代码反序列化JSON字符串成ABAP结构

  • python怎么安装jieba库_python索引

    python怎么安装jieba库_python索引https://my.oschina.net/u/4360005/blog/3588295使用jieba库分词一.什么是jieba库1.jieba库概述jieba是优秀的中文分词第三方库,中文文本需要通过分词获得单个词语。2.jieba库的使用:(jieba库支持3种分词模式)通过中文词库的方式识…4019/04/0200:00…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号