文档章节

Mybatis 常用的几个对象

learn_more
 learn_more
发布于 2016/02/17 14:57
字数 1221
阅读 177
收藏 3

1、SqlSessionFactoryBuilder

这个类可以被实例化、使用和丢弃,一旦创建了 SqlSessionFactory,就不再需要它了。因此 SqlSessionFactoryBuilder 实例的最佳范围是方法范围(也就是局部方法变量)。你可以重用 SqlSessionFactoryBuilder 来创建多个 SqlSessionFactory 实例,但是最好还是不要让其一直存在以保证所有的 XML 解析资源开放给更重要的事情。那么SqlSessionFactoryBuilder一旦使用它创建完了SqlSessionFactory 就可以销毁了,这样也可以保证整个应用只有一个SqlSessionFactory 

2、SqlSessionFactory

每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为中心的。SqlSessionFactory 的实例可以通过 SqlSessionFactoryBuilder 获得。而 SqlSessionFactoryBuilder 则可以从 XML 配置文件或一个预先定制的 Configuration 的实例构建出 SqlSessionFactory 的实例。

可以从 XML 文件中构建 SqlSessionFactory ,也可以从 Java 程序而不是 XML 文件中创建。

SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由对它进行清除或重建。使用 SqlSessionFactory 的最佳实践是在应用运行期间不要重复创建多次,多次重建 SqlSessionFactory 被视为一种代码“坏味道(bad smell)”。因此 SqlSessionFactory 的最佳范围是应用范围。有很多方法可以做到,最简单的就是使用单例模式或者静态单例模式。


3、SqlSession

每个线程都应该有它自己的 SqlSession 实例。SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的范围是请求或方法范围。绝对不能将 SqlSession 实例的引用放在一个类的静态域,甚至一个类的实例变量也不行。也绝不能将 SqlSession 实例的引用放在任何类型的管理范围中,比如 Serlvet 架构中的 HttpSession。如果你现在正在使用一种 Web 框架,要考虑 SqlSession 放在一个和 HTTP HttpRequest请求对象相似的范围中。换句话说,每次收到的 HTTP 请求,就可以打开一个 SqlSession,返回一个响应,就关闭它。这个关闭操作是很重要的,你应该把这个关闭操作放到 finally 块中以确保每次都能执行关闭。下面的示例就是一个确保 SqlSession 关闭的标准模式:

SqlSession session = sqlSessionFactory.openSession();

try {

  // do work

} finally {

  session.close();

}

在你的所有的代码中一致性地使用这种模式来保证所有数据库资源都能被正确地关闭。

Spring 依赖注入框架可以创建线程安全的、基于事务的 SqlSession 和映射器(mapper)并将它们直接注入到你的 bean 中,因此它们的生命周期将交给Spring管理。

4、SqlSessionTemplate

他是org.mybatis.spring包下面的类,而且他还实现sqlSession,但是他sqlSession的操作都是由他内部的成员sqlSessionProxy处理完成的,这个对象的实例其实是DefaultSqlSession。无论如何,他是Spring相关的,他的生命周期应该由Spring的来管理,那么涉及到 sqlSession的管理,事务的隔离,甚至缓存的控制。这些内部都已经处理完成,我们使用时只需要直接调用 SqlSessionTemplate 的数据操作方法,对于session的关闭,我们不需要担心,另外,虽然 SqlSessionTemplate 是在Spring采用构造方法的方式注入,默认就是一个单例,但是我们在应用当中,实际每次一个事务我们都会实例化一个DefaultSqlSession,而且处理完之后也会关闭,如果一个事务中有多个数据操作,那么他们使用的是同一个sqlsession。对于一个拥有事务的sqlsession,他的关闭时期是在事务提交的时候关闭,换句话说,关闭sqlsession是事务应该负责的,但是如果没有被事务管理,你们自己进行关闭。

每次执行数据操作时获取sqlsession的代码:

SqlSessionHolder holder = (SqlSessionHolder)TransactionSynchronizationManager.getResource(sessionFactory);
SqlSession session = sessionHolder(executorType, holder);
if(session != null) {
    return session; // 如果已经存在,那么直接返回
} else {
    if(LOGGER.isDebugEnabled()) {
        LOGGER.debug("Creating a new SqlSession");
    }
    session = sessionFactory.openSession(executorType); // 如果不存在,应该生成,而且存放在SessionHolder中管理
    registerSessionHolder(sessionFactory, executorType, exceptionTranslator, session);
    return session;
}


代理执行数据操作的代码

SqlSession sqlSession = SqlSessionUtils.getSqlSession(SqlSessionTemplate.this.sqlSessionFactory,SqlSessionTemplate.this.executorType, SqlSessionTemplate.this.exceptionTranslator); // 获取DefaultSqlSession
Object unwrapped;// 返回值,会默认被缓存在内存中(一级缓存)
try {
    Object t = method.invoke(sqlSession, args); // 代理调用数据操作方法
    if(!SqlSessionUtils.isSqlSessionTransactional(sqlSession, SqlSessionTemplate.this.sqlSessionFactory)) {
        sqlSession.commit(true); // 判断这个sqlsession是否是被事务容器所管理,没有被管理则自己提交,被管理则事务提交
    }
    unwrapped = t;
} catch (Throwable var11) {
    unwrapped = ExceptionUtil.unwrapThrowable(var11);
    if(SqlSessionTemplate.this.exceptionTranslator != null && unwrapped instanceof PersistenceException) {
        SqlSessionUtils.closeSqlSession(sqlSession, SqlSessionTemplate.this.sqlSessionFactory);// 关闭sqlsession
        sqlSession = null;
        DataAccessException translated = SqlSessionTemplate.this.exceptionTranslator.translateExceptionIfPossible((PersistenceException)unwrapped);
        if(translated != null) {
            unwrapped = translated;
        }
    }
    throw (Throwable)unwrapped;
} finally {
    if(sqlSession != null) {
        SqlSessionUtils.closeSqlSession(sqlSession, SqlSessionTemplate.this.sqlSessionFactory); // 关闭sqlsession
    }

}




© 著作权归作者所有

learn_more
粉丝 93
博文 240
码字总数 210196
作品 0
深圳
程序员
私信 提问
全网首例全栈实践(五)Spring Boot 集成Mybatis

一、概述 我们的Spring Boot后续项目使用的都是MySQL。Spring Boot连接MySQL的方式包括JDBC,Spring JPA,Hibeirnate,Mybatis等,本文主要带大家实践Mybatis的集成。 MyBatis 前身是apache的...

充电实践
02/02
0
0
mybatis session创建过程(2)

session创建过程  在mybatis的常规用法当中,通过sqlSessionFactory.openSession()来创建SqlSession对象,这里的sqlSessionFactory就是在解析配置后生成的SqlSession的工厂。  在openSessi...

晴天哥
2018/07/05
0
0
呸呸呸/sense-support

#为什么要做一个“sense”脚手架 java开发中常用的框架其实就是几个,spring(mvc),hibernate,mybatis,lucene,使用的数据库也就那么几种,mysql,redis,memcahced,mongodb。在遥远的“远...

呸呸呸
2016/11/10
0
0
SSM框架之MyBatis3专题1:MyBatis入门

1 框架 百度百科介绍:框架(Framework)是整个或者部分系统的可重用设计,表现为一组抽象构件以及构件实例间交互的方法;另一种定义认为,框架是可被应用功能开发者制定的应用骨架。可以说,...

糖醋白糖
2018/06/26
0
0
Mybatis源码分析之SqlSessionFactory(一)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 https://blog.csdn.net/t4i2b10X4c22nF6A/article/details/100137596...

JAVA高级架构v
08/28
0
0

没有更多内容

加载失败,请刷新页面

加载更多

使用CSS自定义属性构建骨架屏

写在前面 几天前看到薄荷前端团队分享的《前端骨架屏方案小结》,突然回想起一年前看到的max bock写的《Building Skeleton Screens with CSS Custom Properties》,翻译整理写下出此文,分享...

前端老手
昨天
9
0
Docker常用命令小记

除了基本的<font color="blue">docker pull</font>、<font color="blue">docker image</font>、<font color="blue">docker ps</font>,还有一些命令及参数也很重要,在此记录下来避免遗忘。 ......

程序员欣宸
昨天
9
0
MAT使用-jvm内存溢出问题分析定位

1.MAT简介: MAT 全称 Eclipse Memory Analysis Tools 是一个分析 Java堆数据的专业工具,可以计算出内存中对象的实例数量、占用空间大小、引用关系等,看看是谁阻止了垃圾收集器的回收工作,...

xiaomin0322
昨天
5
0
内网和外网之间的通信(端口映射原理)

首先解释一下“内网”与“外网”的概念: 内网:即所说的局域网,比如学校的局域网,局域网内每台计算机的IP地址在本局域网内具有互异性,是不可重复的。但两个局域网内的内网IP可以有相同的...

Jack088
昨天
6
0
3.深入jvm内核-原理、诊断与优化-4. GC算法和种类

一、GC算法和种类 GC的概念 GC算法 引用计数法 标记清除 标记压缩 复制算法 可触及性 Stop-The-World GC的对象是堆空间和永久区 引用计数法 老牌垃圾回收算法 通过引用计算来回收垃圾 使用者...

hexiaoming123
昨天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部