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同步机制解决线程安全问题更简单,更方便,且结果程序拥有更高的并发性。

  理解得更加通俗一点就是一个是锁机制进行时间换空间,一个是存储拷贝进行空间换时间。

转载于:https://www.cnblogs.com/wucj/p/5162213.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/262082.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

.Net如何统计在线人数

统计在线用户的作用不言而喻&#xff0c;就是为了网站管理者可以知道当前用户的多少&#xff0c;然后根据用户数量来观察服务器或者程序的性能&#xff0c;从而可以直观的了解到网站的吸引力或者网站程序的效率现在&#xff0c;我们就介绍一个简单明了的方法来统计在线用户的多…

EFI BIOS下的磁盘管理工具Diskpart,Efifmt与Efichk(转)

Diskpart.efi GPT分区格式工具下载&#xff1a; EfiDiskUtility v1.3(X64).rarhttp://pan.baidu.com/share/link?shareid174670&uk3204866771 EFI BIOS作为一种创新的BIOS架构,自然有其独特之初,今天我给大家一下运行在EFI Shell环境下几款由Microsoft开发的磁盘管理工具.…

php负责传递数据,php传递数据的方法有哪些

php传递数据的方法有哪些发布时间&#xff1a;2021-03-19 09:10:54来源&#xff1a;亿速云阅读&#xff1a;58作者&#xff1a;小新这篇文章将为大家详细讲解有关php传递数据的方法有哪些&#xff0c;小编觉得挺实用的&#xff0c;因此分享给大家做个参考&#xff0c;希望大家阅…

ubuntu远程桌面连接命令rdesktop连接windows远程桌面详解

sudo apt-get install rdesktoprdesktop 124.42.120.174:1433 呵呵&#xff0c;连接成功了。 -f 全屏-a 16位色默认端口是3389&#xff08;linux 22 sh&#xff09;注意&#xff1a;windows 的服务中的 Terminal Servies 需要开启。我的电脑 右键 属性 远程中&#xff0c;勾选 …

那一瞬...

那一日&#xff0c;那一月&#xff0c;那一年&#xff0c;那一世... 仓央嘉措 那一日 我闭目在经殿的香雾中 蓦然听见你诵经的真言 那一月 我摇动所有的经筒&#xff0c;不为超度 只为触摸你的指尖 那一年 磕长头匍匐在山路&#xff0c;不为觐见 只为贴着你的温暖 那…

除了工作怎么交朋友_夫妻感情不好怎么办?夫妻关系紧张该如何解决?

夫妻感情不好怎么办?夫妻关系紧张该如何解决&#xff1f;1. 象征两人的兴趣随着年龄的增长而多样化。年轻的时候往往因为他们之间的差异而互相吸引&#xff0c;但当他们在中老年则需要更多的安慰或关心&#xff0c;理解&#xff0c;需求就不同了。当你发现自己的志向迥然不同时…

php学习_与mysql的连接 2013.01.04

我之前学习了一点mysql&#xff0c;所以跳过了两讲关于mysql的部分。 不知道为什么&#xff0c;我没有打开wamp时&#xff0c;在ie浏览器中输入http://localhost&#xff0c;就无法显示。后来打开了之后&#xff0c;才能在浏览器显示.php文件内容。.php文件是服务器端的&#x…

受管制的代码

其实整个.NET项目都是运行在.NET Framework上的托管代码&#xff0c;这个道理和JAVA虚拟机的机制是类似的。 最简单的说呢&#xff0c;受托管的代码不能直接写内存&#xff0c;是安全的&#xff0c;而非托管代码是非安全代码&#xff0c;可以使用指针操作内存。 一般的项目使…

javascript真的是异步的吗?且看setTimeout的实现原理以及setTimeout(0)的使用场景

在今天之前我一直以为setTimeout这个函数是异步的&#xff0c;无意中看到了一篇关于setTimeout的文章。发现自己曾经的认识全是错误的&#xff0c;赶紧总结下。 先看一段代码&#xff1a; var start new Date(); setTimeout(function(){var end new Date();console.log("…

java websocket修改为同步_服务端向客户端推送消息技术之websocket的介绍

websocket的介绍在讲解WebSocket前&#xff0c;我们先来看看下面这种场景&#xff0c;在HTTP协议下&#xff0c;怎么实现。需求&#xff1a;在网站中&#xff0c;要实现简单的聊天&#xff0c;这种情况怎么实现呢&#xff1f;如下图&#xff1a;​当发送私信的时候&#xff0c;…

Extjs checkbox 多删除

var BankOrderstore new Ext.data.JsonStore //数据源({url: "../Handler/TxnRefund.ashx",totalProperty: ToTalRecord,root: "ResultData",listeners:{beforeload: function () {this.baseParams {"method": "QU…

汇编学习笔记(二)--数据处理的两个基本问题

1.div 除数 有8位和16位两种&#xff0c;在一个reg或者内存单元中 被除数 默认放在ax或者ax和dx中&#xff0c;如果除数位8位&#xff0c;被除数为16位&#xff0c;默认放在ax中&#xff1b; 如果除数为16位&#xff0c;被除数为32位&#xff0c;在dx和ax中存放&#xff0c;dx存…

oracle对sga统计信息不对,oracle 索引失效原因及解决方法

一、以下的方法会引起索引失效‍1,<>2,单独的>,3,like "%_" 百分号在前.4,表没分析.5,单独引用复合索引里非第一位置的索引列.6,字符型字段为数字时在where条件里不添加引号.7,对索引列进行运算.需要建立函数索引.8,not in ,not exist.9,当变量采用的是time…

python random randint_python中random.randint和random.randrange的区别详解

在python中&#xff0c;通过导入random库&#xff0c;就能使用randint 和 randrange 这两个方法来产生随机整数。那这两个方法的区别在于什么地方呢&#xff1f;让我们一起来看看&#xff01; 区别: randint 产生的随机数区间是包含左右极限的&#xff0c;也就是说左右都是闭区…

How to change max_allowed_packet size

2019独角兽企业重金招聘Python工程师标准>>> How to change max_allowed_packet size up vote 116 down vote favorite 40I am having a problem with BLOB fields in my MySQL database - when uploading files larger than approx 1M…

cmake,make,nmake的用法

于是开始找跨平台的编译工具&#xff0c;其中最有名的两个是 cmake 和 scons&#xff0c;cmake 之所以出名估计是因为 KDE 4 从 autotools 转向用 cmake 来编译。而 scons 则是 lighttpd 原来用的编译工具&#xff0c;它现在也转向 Python 了。cmake 和 python 大概代表了新一代…

CSS中em和px单位的区别(转)

这里引用的是Jorux的“95%的中国网站需要重写CSS”的文章&#xff0c;题目有点吓人&#xff0c;但是确实是现在国内网页制作方面的一些缺陷。我一直也搞不清楚px与em之间的关系和特点&#xff0c;看过以后确实收获很大。平时都是用px来定义字体&#xff0c;所以无法用浏览器字体…

oracle的age datetime,python cx_Oracle插入TIMESTAMP字段后显示格式问题?

目标&#xff1a;A张表内有个 TIMESTAMP 字段&#xff0c;需要读取后插入到B表中&#xff1b;问题&#xff1a;使用 cx_Oracle模块读取该字段时显示为 datetime.datetime(2016, 9, 1, 0, 0, 1, 288000) 样式&#xff1b;使用 executemany 方法插入B表后&#xff0c;再次读取B表…

.net runtime占用cpu_.net 中的StringBuilder和TextWriter区别

最近闲来之余&#xff0c;看了一些开源的类库&#xff0c;看到有些类库喜欢用TextWriter类来记录相关的字符串数据&#xff0c;感到比较好奇&#xff0c;为啥不用StringBuilder类对象。于是在网上搜索了一番&#xff0c;总结了相关笔记。StringBuilder类在 .net 中,字符串作为一…

微信页面弹出窗口,底部不随窗口滑动而滚动

公司是做微信第三方公众平台&#xff0c;有一个购物系统&#xff0c;现在需要将商品页面模仿淘宝的样式&#xff0c;就是点击购物车或购买按钮&#xff0c;会弹出一个窗口&#xff0c;显示sku和数量。本来就是一个做java后台的&#xff0c;前端布局不是很懂&#xff0c;上网搜索…