前言:

学习框架一个比较好的路径阅读源码.本文介绍的SqlSessionFactory和SqlSession.可以通过了解SqlSessionFactory接口和SqlSession接口以及两个的实现类入手,去看源码了解实现过程.最好能把项目下载到本地,慢慢分析实现过程.

Myabtis官网:http://www.mybatis.org/
github地址:https://github.com/mybatis/mybatis-3

MyBatis的持久化解决方案是将用户从原始的JDBC访问中解放出来,用户只需要定义需要操作的SQL语句,无须关注底层的JDBC操作,就可以以面向对象的方式来进行持久化层操作.底层数据库连接的获取,数据访问的实现,事务控制等都无须用户关心,从而将应用层从底层的JDBC/JTA API抽取出来.通过配置文件管理JDBC连接,让MyBatis解决持久化的实现.在MyBatis中的常见对象有SqlSessionFactory和SqlSession.本文这种介绍一下两者的概念和使用.


一、 SqlSessionFactory

SqlSessionFactory是MyBatis的关键对象,它是个单个数据库映射关系经过编译后的内存镜像.SqlSessionFactory对象的实例可以通过SqlSessionFactoryBuilder对象类获得,而SqlSessionFactoryBuilder则可以从XML配置文件或一个预先定制的Configuration的实例构建出SqlSessionFactory的实例.每一个MyBatis的应用程序都以一个SqlSessionFactory对象的实例为核心.同时SqlSessionFactory也是线程安全的,SqlSessionFactory一旦被创建,应该在应用执行期间都存在.在应用运行期间不要重复创建多次,建议使用单例模式.SqlSessionFactory是创建SqlSession的工厂.

//SqlSessionFactory接口源码如下所示:package org.apache.ibatis.session;import java.sql.Connection;public interface SqlSessionFactory {SqlSession openSession();//这个方法最经常用,用来创建SqlSession对象.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();}

二、SqlSession

SqlSession是MyBatis的关键对象,是执行持久化操作的独享,类似于JDBC中的Connection.它是应用程序与持久层之间执行交互操作的一个单线程对象,也是MyBatis执行持久化操作的关键对象.SqlSession对象完全包含以数据库为背景的所有执行SQL操作的方法,它的底层封装了JDBC连接,可以用SqlSession实例来直接执行被映射的SQL语句.每个线程都应该有它自己的SqlSession实例.SqlSession的实例不能被共享,同时SqlSession也是线程不安全的,绝对不能讲SqlSeesion实例的引用放在一个类的静态字段甚至是实例字段中.也绝不能将SqlSession实例的引用放在任何类型的管理范围中,比如Servlet当中的HttpSession对象中.使用完SqlSeesion之后关闭Session很重要,应该确保使用finally块来关闭它.

//SqlSession接口源码如下所示:package org.apache.ibatis.session;import java.io.Closeable;
import java.sql.Connection;
import java.util.List;
import java.util.Map;import org.apache.ibatis.executor.BatchResult;public interface SqlSession extends Closeable {<T> T selectOne(String statement);<T> T selectOne(String statement, Object parameter);<E> List<E> selectList(String statement);<E> List<E> selectList(String statement, Object parameter);<E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds);<K, V> Map<K, V> selectMap(String statement, String mapKey);<K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey);<K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey, RowBounds rowBounds);void select(String statement, Object parameter, ResultHandler handler);void select(String statement, ResultHandler handler);void select(String statement, Object parameter, RowBounds rowBounds, ResultHandler handler);int insert(String statement);int insert(String statement, Object parameter);int update(String statement);int update(String statement, Object parameter);int delete(String statement);int delete(String statement, Object parameter);void commit();void commit(boolean force);void rollback();void rollback(boolean force);List<BatchResult> flushStatements();void close();void clearCache();Configuration getConfiguration();<T> T getMapper(Class<T> type);Connection getConnection();
}

三、SqlSessionFactory和SqlSession实现过程

mybatis框架主要是围绕着SqlSessionFactory进行的,创建过程大概如下:

(1)、定义一个Configuration对象,其中包含数据源、事务、mapper文件资源以及影响数据库行为属性设置settings(2)、通过配置对象,则可以创建一个SqlSessionFactoryBuilder对象(3)、通过 SqlSessionFactoryBuilder 获得SqlSessionFactory 的实例。(4)、SqlSessionFactory 的实例可以获得操作数据的SqlSession实例,通过这个实例对数据库进行操作

并且如果想按照上述方式得到SqlSessionFactory,最好使用下面的mybatis-config.xml类似的配置.在这里mybatis-config.xml配置文件是没有和Spring配置文件整合过得,如果项目中mybaits的配置文件和Spring配置文件整合过了,则下面的代码运行估计会出错,因为一般spring和mybatis整合过之后,mybatis的配置文件基本没有存在的必要了,之前在mybatis中配置的数据源和事务这两个方面,一般的做法都会spring的配置文件,则下面的代码加载mybatis-config.xml的时候,得不到必要的信息,创建的过程中会有问题.所以在这里先给一份mybatis-config.xml单独的配置文件.

<?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>   <!-- 加载类路径下的属性文件 -->  <properties resource="db.properties"/>  <!-- 设置类型别名 -->  <typeAliases>  <typeAlias type="cn.itcast.javaee.mybatis.app04.Student" alias="student"/>  </typeAliases>  <!-- 设置一个默认的连接环境信息 -->  <environments default="mysql_developer">  <!-- 连接环境信息,取一个任意唯一的名字 -->  <environment id="mysql_developer">  <!-- mybatis使用jdbc事务管理方式 -->  <transactionManager type="jdbc"/>  <!-- mybatis使用连接池方式来获取连接 -->  <dataSource type="pooled">  <!-- 配置与数据库交互的4个必要属性 -->  <property name="driver" value="${mysql.driver}"/>  <property name="url" value="${mysql.url}"/>  <property name="username" value="${mysql.username}"/>  <property name="password" value="${mysql.password}"/>  </dataSource>  </environment>  <!-- 连接环境信息,取一个任意唯一的名字 -->  <environment id="oracle_developer">  <!-- mybatis使用jdbc事务管理方式 -->  <transactionManager type="jdbc"/>  <!-- mybatis使用连接池方式来获取连接 -->  <dataSource type="pooled">  <!-- 配置与数据库交互的4个必要属性 -->  <property name="driver" value="${oracle.driver}"/>  <property name="url" value="${oracle.url}"/>  <property name="username" value="${oracle.username}"/>  <property name="password" value="${oracle.password}"/>  </dataSource>  </environment>  </environments>  <!-- 加载映射文件-->  <mappers>  <mapper resource="cn/itcast/javaee/mybatis/app14/StudentMapper.xml"/>  </mappers>  </configuration>  

下面的这行代码功能是通过配置文件mybatis-config.xml,创建SqlSessionFactory对象,然后产生SqlSession,执行SQL语句.而mybatis的初始化发生在:

SqlSessionFactory sqlSessionFactory =  new SqlSessionFactoryBuilder().build(resourceAsStream);

如果是spring和mybaits整合之后的配置文件,一般以这种方式实现,SqlSessionFactory的创建:

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"><property name="dataSource" ref="dataSource"></property><!-- 自动扫描mapping.xml文件 --><property name="mapperLocations" value="classpath:com/cn/mapper/*.xml"></property>
</bean>

关于SqlSessionFactory和SqlSession两个对象给一个具体的使用过程:

package com.cn.testIUserService;import java.io.IOException;
import java.io.InputStream;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;import com.cn.entity.User;public class MyBatisTest {public static void main(String[] args) {try {//读取mybatis-config.xml文件InputStream resourceAsStream = Resources.getResourceAsStream("mybatis-config.xml");//初始化mybatis,创建SqlSessionFactory类的实例SqlSessionFactory sqlSessionFactory =  new SqlSessionFactoryBuilder().build(resourceAsStream);//创建session实例SqlSession session = sqlSessionFactory.openSession();/** 接下来在这里做很多事情,到目前为止,目的已经达到得到了SqlSession对象.通过调用SqlSession里面的方法,* 可以测试MyBatis和Dao层接口方法之间的正确性,当然也可以做别的很多事情,在这里就不列举了*///插入数据User user = new User();user.setC_password("123");user.setC_username("123");user.setC_salt("123");//第一个参数为方法的完全限定名:位置信息+映射文件当中的idsession.insert("com.cn.dao.UserMapping.insertUserInformation", user);//提交事务session.commit();//关闭sessionsession.close();} catch (IOException e) {e.printStackTrace();}}
}

针对上面的代码给出详细的说明关于SqlSessionFactory和SqlSession创建过程涉及的内容.

结合上述SqlSessionFactory和SqlSession使用过程和结构图,涉及到的方法为下面步骤,结合源码中的方法为下面的步骤:

第一步首先SqlSessionFactoryBuilder去读取mybatis的配置文件,然后build一个DefaultSqlSessionFactory,即得到SqlSessionFactory
//源码中涉及的包和具体方法为:
//涉及的包为:package org.apache.ibatis.session;//第一个类为:SqlSessionFactoryBuilder,设计到此类的方法为下面部分:
public SqlSessionFactory build(InputStream inputStream) {return build(inputStream, null, null);}public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {try {//通过XMLConfigBuilder解析配置文件,解析的配置相关信息都会封装为一个Configuration对象XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);//然后返回一个DefaultSqlSessionFactoryreturn build(parser.parse());} 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.}}}//得到DefaultSqlSessionFactorypublic SqlSessionFactory build(Configuration config) {return new DefaultSqlSessionFactory(config);}//第二个类为:DefaultSqlSessionFactory,涉及的方法为:public DefaultSqlSessionFactory(Configuration configuration) {this.configuration = configuration;}
第二步,获取到SqlSessionFactory之后,就可以利用SqlSessionFactory方法的openSession来获取SqlSession对象了。
private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {Transaction tx = null;try {//通过Confuguration对象去获取Mybatis相关配置信息, Environment对象包含了数据源和事务的配置// execType为执行器类型,配置文件中定义// SimpleExecutor -- SIMPLE 就是普通的执行器。//ReuseExecutor -执行器会重用预处理语句(prepared statements)//BatchExecutor --它是批量执行器final Environment environment = configuration.getEnvironment();final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);//定义执行器,是对statement的封装final Executor executor = configuration.newExecutor(tx, execType);//最后返回一个SqlSessionreturn 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();}
}

得到SqlSession对象之后就可以利用SqlSession内部的方法进行CRUD操作了。

注意一点,Connection对象是在SqlSession对象创建之后进行CURD操作中创建的。深入查找之后找到在ManagedTransaction类中找到获取Connection对象的关键代码如下:

  protected void openConnection() throws SQLException {if (log.isDebugEnabled()) {log.debug("Opening JDBC Connection");}//dataSource 来源有三种,JndiDatasource,PooledDataSource,UnpooledDataSource,配置文件中定义this.connection = this.dataSource.getConnection();if (this.level != null) {this.connection.setTransactionIsolation(this.level.getLevel());}}

PooledDataSource和UnPooledDataSource的区别是PooledDataSource使用了连接池。为什么使用连接池呢?因为创建一个Connection对象的过程,在底层就相当于和数据库建立的通信连接,在建立通信连接的过程,消耗了非常多的时间,而往往我们建立连接后(即创建Connection对象后),就执行一个简单的SQL语句,然后就要抛弃掉,这是一个非常大的资源浪费!mybatis针对这一个问题提出的PooledDataSource使用了连接池。关于数据库连接池的知识点,可以自行百度,在这里就不扩展介绍了.

MyBatis常用对象SqlSessionFactory和SqlSession介绍和运用相关推荐

  1. MyBatis复习(三):MyBatis核心对象SqlSessionFactory和SqlSession

    MyBatis有两个核心对象:SqlSessionFactory.SqlSession   

  2. 二、MyBatis常用对象分析 封装工具类

    1.0 MyBatis 对象分析 (1) Resources 类 Resources 类,顾名思义就是资源,用于读取资源文件.其有很多方法通过加载并解析资源文件,返回不同类型的 IO 流对象. (2) ...

  3. sqlsessionfactory和sqlsession

    目录 前言: 一. SqlSessionFactory 二.SqlSession 三.SqlSessionFactory和SqlSession实现过程 前言: 学习框架一个比较好的路径阅读源码,本文介 ...

  4. 【MyBatis系列7】原来SqlSession只是个甩手掌柜,真正干活的却是Executor等四大对象

    Executor原理分析 前言 MyBatis架构分层 Executor BaseExecutor SimpleExecutor ReuseExecutor BatchExecutor 三种常用批量插 ...

  5. mybats实操-前期入门写法分析,SqlSessionFactory 获取SqlSession, 系统核心配置文件 mybatis-config.xml,SQL映射XML文件,MyBatis缓存

    标题 偏向这一块的配置 打个预防针 尽量别用中文路径 尤其配置文件 1.导入数据库(smbms_db.sql) 下载maven并且配置环境变量 去IDEA配置好maven 以后maven项目直接用 m ...

  6. MyBatis中SqlSessionFactory和SqlSession简解

    mybatis官网中文文档:https://mybatis.org/mybatis-3/zh/sqlmap-xml.html mybatis-spring官方中文文档:https://mybatis. ...

  7. 笔记·mybatis核心对象和全局配置文件

    jar包官网: https://mvnrepository.com/artifact/org.mybatis 介绍: 持久化: 持久,即把数据(如内存中的对象)保存到可以永久保存的存储设备中,持久化的 ...

  8. Mybatis框架中SqlSessionFactory

    首先SqlSessionFactory与SqlSession都是同一个接口 SqlSessionFactory是通过SqlSessionFactoryBuilder的build方法创建的 而build ...

  9. Mybatis搞两下(sqlsession,动态代理)

    本文主要介绍和,其中动态代理实操了源码,我觉得值得一看,能加深你对Mybatis底层文件的映射,代理类进行的CRUD的操作,即使他本身也是通过SqlSession来执行增删改查的操作. SqlSess ...

最新文章

  1. JAVE SE 学习day_09:sleep线程阻塞方法、守护线程、join协调线程同步方法、synchronized关键字解决多线程并发安全问题
  2. 【计算机视觉】深度相机(六)--Kinect v2.0 手势样本库制作
  3. ubuntu使用fail2ban_如何在Ubuntu 20.04上安装和配置Fail2ban
  4. mysql jdbc 批量_MYSQL 之 JDBC(十四):批量处理JDBC语句提高处理效率
  5. “秒开”浏览器实现起来有多难?
  6. 在linux安装requests库命令,在Linux--Ubuntu18.04环境下安装requests库
  7. 加密芯片在汽车无钥匙启动行业的应用
  8. 硬盘分区变为RAW文件系统后的解决办法
  9. Java实现简单工厂模式
  10. 【c语言数学函数库】
  11. mysql里cis_CIS MySQL存储库表修复过程
  12. tinyTorrent: 从头写一个 Deno 的 BitTorrent 下载器
  13. Primeng12+ 使用 full-calendar
  14. mysql dlz驱动,bind dlz mysql的配备
  15. android连接雷电模拟器,android studio连接雷电模拟器 【AS 模拟器】
  16. vue 全景图 photo-sphere-viewer 实现
  17. eap方法 华为手机怎么连wifi_怎样为WLAN选择最佳的EAP?
  18. 装饰器设计模式代码套路-咖啡加奶
  19. 百度地图API_BMap接口的使用形式
  20. Word2016中添加目录

热门文章

  1. python中isin函数_pandas中的isin函数详解
  2. mysql 枚举 enum用法_mysql中的枚举类型ENUM的用法:
  3. Mac OS中利用ffmpeg为视频添加字幕
  4. Java~Map集合详解
  5. 如何给视频添加特效?快速制作特效视频
  6. 双十一选什么充电宝比较好?口碑好的充电宝品牌推荐
  7. 深富策略北资集体休市
  8. 华为的豪赌:用5G为折叠屏手机“护航”
  9. 最优服务次序问题算法c语言,《算法分析与设计》最优服务次序问题的答案-20210414020541.docx-原创力文档...
  10. 基于karate数据的2层GCN实现的节点分类问题