MyBatis之八:需要说明的几个java api的生命周期以及封装
学习mybatis不得不了解SqlSessionFactoryBuilder、SqlSessionFactory、SqlSession。这里主要是讲解它们的生命周期以及一般最佳实践。 一般来说对象的生命周期也就是对象创建到销毁的过程,如果在这个过程中,如果实现的代码质量不佳,那么很容易造成程序上的错误或者效率的降低。
1、SqlSessionFactoryBuilder
SqlSessionFactoryBuilder可以被jvm虚拟机所实例化、使用或者销毁。一旦使用SqlSessionFactoryBuilder对象创建SqlSessionFactory后,SqlSessionFactoryBuilder类就不需要存在了,也就是,不需要保持对象的状态,可以随意的由jvm销毁。因此SqlSessionFactoryBuilder对象的最佳使用范围是方法内部。
2、SqlSessionFactory
SqlSessionFactory对象是由SqlSessionFactoryBuilder创建。一旦创建SqlSessionFactory类的实例,该实例应该在应用程序执行期间都存在,根本不需要每一次操作数据库时都创建,所以其最佳实践方式就是单例模式,或者使用Spring框架来实现单例模式对SqlSessionFactory对象进行有效管理(后续会讲解)。
3、SqlSession
SqlSession对象由SqlSessionFactory类创建,需要注意的是,每个线程都应该有它自己的SqlSession实例。SqlSession的实例不能共享,是线程不安全的,其实我们去扒看SqlSession接口定义,可以发现,里面定义了数据的增删改查以及事务处理以及实例对象的关闭。那么很显然在操作该对象的时候必须要保持其线程安全,不然在并发情况下肯定会乱套。或者将SqlSession实例对象存放在一个类的静态字段甚至是实例字段中。
4、简单封装
由1、2、3得知,SqlSessionFactoryBuilder会被jvm自动销毁、SqlSessionFactory不需要每次操作数据库都创建、SqlSession必须是线程安全的,那么针对这3点,以下做了一个简单封装。
SyncSqlSessionFactory类主要是获取SqlSessionFactory单例对象
package com.mybatis.util; import java.io.IOException;
import java.io.InputStream; import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder; public class SyncSqlSessionFactory { private static SqlSessionFactory sqlSessionFactory; private SyncSqlSessionFactory() {
} synchronized public static SqlSessionFactory getSqlSessionFactory() { try {
if (sqlSessionFactory == null) {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources
.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder()
.build(inputStream);
}
} catch (IOException e) {
e.printStackTrace();
} return sqlSessionFactory;
}
}
SafeSqlSessionUtil类保证SqlSession线程安全的前提下封装了事务的回滚提交操作。
package com.mybatis.util;
import org.apache.ibatis.session.SqlSession;
public class SafeSqlSessionUtil {
private static ThreadLocal<SqlSession> threadLocal = new ThreadLocal<SqlSession>();
public static SqlSession getSqlSession() {
SqlSession sqlSession = threadLocal.get();
return sqlSession == null ? SyncSqlSessionFactory.getSqlSessionFactory()
.openSession() : sqlSession;
}
public static void commit() {
if (threadLocal.get() != null) {
threadLocal.get().commit();
threadLocal.get().close();
threadLocal.set(null);
}
}
public static void rollback() {
if (threadLocal.get() != null) {
threadLocal.get().rollback();
threadLocal.get().close();
threadLocal.set(null);
}
}
}
5、使用示例
try {
SqlSession sqlSession = SafeSqlSessionUtil.getSqlSession();
//基本操作
sqlSession.delete("");
sqlSession.update("");
sqlSession.select("",null);
} catch (Exception e) {
SafeSqlSessionUtil.rollback();
}finally{
SafeSqlSessionUtil.commit();
}
6、需要说明的地方
synchronized:如果某个synchronized方法是static的,那么当线程访问该方法时,它锁的并不是synchronized方法所在的对象,而是synchronized方法所在的类所对应的Class对象。Java中,无论一个类有多少个对象,这些对象会对应唯一一个Class对象,因此当线程分别访问同一个类的两个对象的两个static,synchronized方法时,它们的执行顺序也是顺序的,也就是说一个线程先去执行方法,执行完毕后另一个线程才开始。
ThreadLocal:线程级别的隔离。它通过为每个线程提供一个独立的变量副本解决了变量并发访问的冲突问题。多数情况下ThreadLocal比直接使用synchronized同步机制解决线程安全问题更简单,更方便,且结果程序拥有更高的并发性。
理解得更加通俗一点就是一个是锁机制进行时间换空间,一个是存储拷贝进行空间换时间。
MyBatis之八:需要说明的几个java api的生命周期以及封装的更多相关文章
- [转]JAVA虚拟机的生命周期
JAVA虚拟机体系结构 JAVA虚拟机的生命周期 一个运行时的Java虚拟机实例的天职是:负责运行一个java程序.当启动一个Java程序时,一个虚拟机实例也就诞生了.当该程序关闭退出,这个虚拟机实例 ...
- java 静态变量生命周期(类生命周期)
Static: 加载:java虚拟机在加载类的过程中为静态变量分配内存. 类变量:static变量在内存中只有一个,存放在方法区,属于类变量,被所有实例所共享 销毁:类被卸载时,静态变量被销毁,并释放 ...
- Java类的生命周期详解
引言 最近有位细心的朋友在阅读笔者的文章时,对java类的生命周期问题有一些疑惑,笔者打开百度搜了一下相关的问题,看到网上的资料很少有把这个问题讲明白的,主要是因为目前国内java方面的教材大多只是告 ...
- 【转】Java 类的生命周期详解
一. 引 言 最近有位细心的朋友在阅读笔者的文章时,对java类的生命周期问题有一些疑惑,笔者打开百度搜了一下相关的问题,看到网上的资料很少有把这个问题讲明白的,主要是因为目前国内java方面的教材大 ...
- 【转载】详解java类的生命周期
原文地址:http://blog.csdn.net/zhengzhb/article/details/7517213 引言 最近有位细心的朋友在阅读笔者的文章时,对java类的生命周期问题有一些疑惑, ...
- Java线程的生命周期(转)
Java线程的生命周期 一个线程的产生是从我们调用了start方法开始进入Runnable状态,即可以被调度运行状态,并没有真正开始运行,调度器可以将CPU分配给它,使线程进入Running状态,真正 ...
- Java 对象的生命周期
Java对象的生命周期 在Java中,对象的生命周期包含下面几个阶段: 1. 创建阶段(Created) 2. 应用阶段(In Use) 3. 不可见阶段(Invisib ...
- Java虚拟机(三)垃圾标记算法与Java对象的生命周期
前言 这一节我们来简单的介绍垃圾收集器,并学习垃圾标记的算法:引用计数算法和根搜索算法,为了更好的理解根搜索算法,会在文章的最后介绍Java对象在虚拟机中的生命周期. 1.垃圾收集器概述 垃圾收集器( ...
- [Java]类的生命周期(上)类的加载和连接[转]
本文来自:曹胜欢博客专栏.转载请注明出处:http://blog.csdn.net/csh624366188 类加载器,顾名思义,类加载器(class loader)用来加载 Java 类到 Java ...
随机推荐
- group by调优的一些测试
表结构信息: mysql> show create table tb\G*************************** 1. row ************************** ...
- ASP.NET缓存策略经验谈
要提升ASP.NET应用程序的性能,最简单.最有效的方式就是使用内建的缓存引擎.虽然也能构建自己的缓存,但由于缓存引擎已提供了如此多的功能,所以完全不必如此麻烦.在很大程度上,ASP.NET开发者在W ...
- [转] ArcGIS engine中气泡标注的添加、修改
小生 原文 ArcGIS engine中气泡标注的添加.修改! 你微微地笑着,不同我说什么话.而我觉得,为了这个,我已等待得久了. ...
- hdu1998 bjfu1272奇数阶幻方构造
这题就是一个sb题,本来很水,硬是说得很含混.奇数阶幻方构造其实有好多方法,这题既不special judge,也不说清楚,以为这样能把水题变成难题似的,简直想骂出题人. /* * Author : ...
- 如何设置适当的ramp-up period值
如何设置适当的值并不轻易. 首先,假如要使用大量线程的话,ramp-up period 一般不要设置成零. 因为假如设置成零,Jmeter将会在测试的开始就建立全部线程并立即发送访问请求, 这样一来就 ...
- TRANSLATE
语法格式: TRANSLATE(expr, from_string, to_string) 示例如下: SELECT TRANSLATE('ab 你好 bcdefg', 'abcdefg', '123 ...
- ORA-12162: TNS:net service name is incorrectly specified
今天在进行修改oracle_sid环境变量的时候,将相关的环境变量值去掉,从而不能进入sqlplus,报错如下: [oracle@kel ~]$ sqlplus / as sysdba SQL*Plu ...
- 在ubuntu下安装chrome
To add PPA in Ubuntu 14.04 / 13.10 / 13.04 / 12.10 / 12.04 First download and install the key from G ...
- C++ 我想这样用(四)
嗯,已经是第四篇了,这篇起我就要开始细说语法了,不过在那之前再次申明下主旨:"C++我想这样用" 系列文案是为C程序员打造的,不是C++程序员. 我的终极目标是:让那些觊觎面向对象 ...
- SRM 508 DIV1 500pt(DP)
题目简述 给定一个大小为 n的序列(n<=10)R,要求你计算序列A0, A1, ..., AN-1的数量,要求A序列满足A0 + A1 + ... + AN-1 = A0 | A1 | ... ...