【MyBatis】作用域生命周期(四)
🚗MyBatis学习·第四站~
🚩起始站:MyBatis概述&环境搭建(一)
🚩本文已收录至专栏:数据库学习之旅
👍希望您能有所收获
一.引入
为了使用方便,我们经常能看到各种教程都将MyBatis抽离为工具类去读取配置文件,许多人可能会按照自己的想法进行一些修改,如果不理解不同作用域和生命周期类别,可能会由于错误的使用导致非常严重的并发问题。
如果选择使用依赖注入框架则可以创建线程安全的、基于事务的 SqlSession 和映射器,并将它们直接注入到你的 bean 中,可以直接忽略它们的生命周期。否则需要自己多多留意。
二.SqlSessionFactoryBuilder
SqlSessionFactoryBuilder
类可以被实例化、使用和丢弃,一旦创建了 SqlSessionFactory,就不再需要它了。
使用 SqlSessionFactoryBuilder 实例的最佳作用域是方法作用域(也就是局部方法变量)。 此外也可以重用 SqlSessionFactoryBuilder 来创建多个 SqlSessionFactory 实例,但不建议一直保留着它,以保证所有的 XML 解析资源可以被释放给更重要的事情。
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
上述示例SqlSessionFactoryBuilder对象使用完便会被丢弃。
三.SqlSessionFactory
SqlSessionFactory
一旦被创建就应该在应用的运行期间一直存在,没有任何理由丢弃它或重新创建另一个实例。
使用 SqlSessionFactory 的最佳实践是在应用运行期间不要重复创建多次,多次重建 SqlSessionFactory 被视为一种代码“坏习惯”。因此 SqlSessionFactory 的最佳作用域是应用作用域。 有很多方法可以做到,最简单的就是使用单例模式或者静态(static)单例模式。
private static SqlSessionFactory sqlSessionFactory = null;static {try {String resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);} catch (IOException e) {e.printStackTrace();}}
例如上述我们可以使用静态代码块实现单例模式,确保SqlSessionFactory只被创建一次。
四.SqlSession
每个线程都应该有它自己的 SqlSession 实例。SqlSession 的实例不是线程安全的,因此是不能被共享的,
它的最佳的作用域是请求或方法作用域。 绝对不能将 SqlSession 实例的引用放在一个类的静态域,甚至一个类的实例变量也不行。
以下是错误示例
,有的人可能不懂又图使用省事,可能进行如下改造:
private static SqlSession sqlSession = null;static {try {String resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);// 错误×sqlSession = sqlSessionFactory.openSession();} catch (IOException e) {e.printStackTrace();}}
也绝不能将 SqlSession 实例的引用放在任何类型的托管作用域中,比如 Servlet 框架中的 HttpSession。
如果你现在正在使用一种 Web 框架,考虑将 SqlSession 放在一个和 HTTP 请求相似的作用域中。 换句话说,每次收到 HTTP 请求,就可以打开一个 SqlSession,返回一个响应后,就关闭它。 这个关闭操作很重要,为了确保每次都能执行关闭操作,你应该把这个关闭操作放到 finally 块中。
在JDK 7版本中出现了一种新的句式: try(资源),它会自动帮助我们close资源,下面的示例就是一个确保 SqlSession 关闭的标准模式:
try (SqlSession session = sqlSessionFactory.openSession()) {// 你的应用逻辑代码
}
在所有代码中都遵循这种使用模式,可以保证所有数据库资源都能被正确地关闭。
五.Mapper映射器实例
映射器是一些绑定映射语句的接口。映射器接口的实例是从 SqlSession 中获得的。
BlogMapper mapper = session.getMapper(BlogMapper.class);
虽然从技术层面上来讲,任何映射器实例的最大作用域与请求它们的 SqlSession 相同。但方法作用域才是映射器实例的最合适的作用域。 也就是说,映射器实例应该在调用它们的方法中被获取,使用完毕之后即可丢弃。 映射器实例并不需要被显式地关闭。尽管在整个请求作用域保留映射器实例不会有什么问题,但是你很快会发现,在这个作用域上管理太多像 SqlSession 的资源会让你忙不过来。 因此,最好将映射器放在方法作用域内。就像下面的例子一样:
try (SqlSession session = sqlSessionFactory.openSession()) {BlogMapper mapper = session.getMapper(BlogMapper.class);// 你的应用逻辑代码
}
六.封装使用示例
网上还有一些使用ThreadLocal优化封装的工具类就不在此赘述,以下为按照上述讲解进行简单封装与使用的示例:
工具类:
public class SqlSessionUtils {// 单例模式创建private static SqlSessionFactory sqlSessionFactory = null;// 使用静态代码块实例化SqlSessionFactorystatic {try {String resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);} catch (IOException e) {e.printStackTrace();}}// 每次调用返回一个SqlSessionpublic static SqlSession getSqlSession() {return sqlSessionFactory.openSession();}
}
使用:
// 可自动close释放资源,注意需要自己commit提交事务
try (SqlSession sqlSession = SqlSessionUtils.getSqlSession()) {// 可以打印查看获取的SqlSession是否为同一对象System.err.println(sqlSession);// 获取映射器接口的实例NewsMapper newsMapper = sqlSession.getMapper(NewsMapper.class);// ....业务逻辑
}
相关文章:
【MyBatis】作用域生命周期(四)
🚗MyBatis学习第四站~ 🚩起始站:MyBatis概述&环境搭建(一) 🚩本文已收录至专栏:数据库学习之旅 👍希望您能有所收获 一.引入 为了使用方便,我们经常能看到各种教程都将MyBatis抽离为工具类…...
腾讯一面—Android 系统启动流程详解
正文AMS 是 Android 中最核心的服务之一,主要负责系统中四大组件的启动、切换、调度及应用进程的管理和调度等工作,其职责与操作系统中的进程管理和调度模块相类似,它本身也是一个 Binder 的实现类,应用进程能通过 Binder 机制调用…...
【Python知识点桂电版】02组合数据类型
一、序列序列简介序列是指一种包含多项数据的数据结构,分为不可变序列和可变序列。可变序列可修改序列内的元素如列表,二不可变序列一旦建立就不能修改其中的元素,字符串和元组属于不可变序列。列表和元组的创建列表:列表名 [元素…...
LeetCode100_100. 相同的树
LeetCode100_100. 相同的树 一、描述 给你两棵二叉树的根节点 p 和 q ,编写一个函数来检验这两棵树是否相同。 如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。 示例 1: 输入:p [1,2,3], q […...
javaEE 初阶 — 网络层中 IP 协议 的报文结构
文章目录IP 协议报文4位版本号4位首部长度8位服务类型16位总长度(字节数)8位生存时间(TTL)与 8位协议16位首部校验和32位源 IP 地址与32位目标 IP 地址动态分配的 IP 地址NAT 网络地址转换IPv6IP 协议报文 4位版本号 这里的 IP 协…...
iOS swift UICollectionView
文章目录1.纯代码自定义UICollectionViewCell2.禁止滑动(弹簧效果)3.UICollectionView的长按拖动2.在一个控制器中放两个UICollectionView或者UITableView,代理方法要怎么写1.纯代码自定义UICollectionViewCell import UIKitclass NewDeviceBottomColle…...
计算机三级数据库 填空题汇总
计算机三级 数据库 IDEF0需求建模方法由箭头和(活动/方框/矩形)两种元素构成。、从安全性角度考虑,防火墙技术是用来保证数据库应用系统的(网络)环境安全的。在UML的状态机图中,状态之间的转移是由&#x…...
【Java学习】初识Java
JavaSEJava初识1. Java简介2.Java环境的安装与配置3. 开发第一个Java程序Java初识 学前疑问:(带着疑问去学习,在学习中自行探索答案) Java是什么?能做什么?发展前景如何?需要学习哪些内容&…...
LabVIEW网络服务安全
LabVIEW网络服务安全如何保护Web服务?当许多人考虑安全性时,他们会考虑加密、用户ID和密码。用户ID和密码用于授权(告诉目标谁在发出请求)。加密保护客户端和服务器之间的通信流量,以便未经授权的个人无法拦截和读取发…...
基于MaixBit(K210芯片)的图像识别猜拳手势博弈装置
本文介绍了一种基于嵌入式平台开发的图像识别部署装置,其主要功能包括实现机器与人的“猜拳博弈”,其组成分为三个部分:手势检测数据集图像识别模型训练模型格式部署maixbit开发板部署手势检测数据集:本项目的数据集包括三种标签&…...
leetcode 41~50 学习经历
leetcode 41~50 学习经历41. 缺失的第一个正数42. 接雨水43. 字符串相乘44. 通配符匹配45. 跳跃游戏 II46. 全排列47. 全排列 II48. 旋转图像49. 字母异位词分组50. Pow(x, n)小结41. 缺失的第一个正数 给你一个未排序的整数数组 nums ,请你找出其中没有出现的最小的…...
SQL注入原理及漏洞利用(入门级)
文章目录一、什么是SQL注入漏洞?二、 SQL查询语句三、SQL注入分类数字型(整型)注入字符型注入搜索型注入四、SQL注入漏洞形成原因一、什么是SQL注入漏洞? 攻击者利用Web应用程序对用户输入验证上的疏忽,在输入的数据中…...
2023/2/26 Vue学习笔记 配置代理解决跨域[CORS ]的问题
利用vue的脚手架巧妙的解决ajax跨域的问题 1 我们首先利用springboot服务搭建 注意这里引出了跨域[CORS ]的问题: Access to XMLHttpRequest at http://localhost:5000/getUserInfo from origin http://localhost:8080 has been blocked by CORS policy: No Access-Control-A…...
算法练习--深拷贝与浅拷贝
🎀个人主页:努力学习前端知识的小羊 感谢你们的支持:收藏🎄 点赞🍬 加关注🪐 文章目录算法地址算法题解分析深拷贝与浅拷贝在练习算法时,遇到了深拷贝与浅拷贝的问题,于是就了解了一…...
Wireshark “偷窥”浏览器与服务器三次握手
本文使用的是Wireshark 4.0.3, Java 11 编写简易服务器,客户端使用Chrome浏览器移动端开发或是前、后端开发又或是高大上的云计算都脱离不了网络,离开了网络的计算机就是一个孤岛,快速上手开发、背面试八股文固然有些急功近利,但确…...
基于stm32温湿度采集平台开发
基于stm32温湿度采集平台开发这里记录一下自己以前课设报告,但是论文中图片和文字、公式太多了,懒得粘贴了,需要完整的可q我963_160_156,也可在微信公众号 *高级嵌入式软件* 里回复 *温湿度* 查看完整版文章摘 要关键词第一章 绪论…...
单机模拟kafka分布式集群(演示生产、消费数据过程)
用单机搭建kafka伪分布式集群,其实集群的概念并不复杂 先说明一下,以下的每个服务启动后都需要新开一个终端来启动另外的服务(因为是集群,自然会用多个终端) 首先下载kafka 提取码:dvz4 或者直接去官网下载kafka_2.11-1.0.0.tgz t…...
办公室人员离岗识别检测系统 yolov7
办公室人员离岗识别检测系统根据yolov7网络模型深度学习技术,办公室人员离岗识别检测算法能够7*24小时全天候自动识别人员是否在岗位。YOLOv7 在 5 FPS 到 160 FPS 范围内,速度和精度都超过了所有已知的目标检测器,并在V100 上,30…...
Android从屏幕刷新到View的绘制(一)之 Window、WindowManager和WindowManagerService之间的关系
0. 相关分享 Android从屏幕刷新到View的绘制(一)之 Window、WindowManager和WindowManagerService之间的关系 Android从屏幕刷新到View的绘制(二)之Choreographer、Vsync与屏幕刷新 1. 相关类 WindowManagerService,…...
#多源数据融合#:HSI与Lidar
Lidar数据与HSI数据融合应该注意的问题 融合激光雷达(lidar)数据和高光谱数据可以提高地物特征的识别和分类准确性。以下是一些融合这两种数据的注意事项: 数据预处理 由于激光雷达数据和高光谱数据的特点不同,需要对两种数据进…...
android 权限控制与进程隔离
每次介绍说是做系统安全的,面试和领导首先就是说配selinux,实在很无语。虽然权限控制是安全很重要一环。 linux的进程就是系统运行中的程序(process),是正在执行的一个程序或者命令,每一个进程都是一个运行的实体,都有自己的地址空间,并占用一定的系统资源。Linux环境下…...
链表(一):移除链表元素、设计链表等力扣经典链表题目
203.移除链表元素相关题目链接:力扣 - 移除链表元素题目重现给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val val 的节点,并返回 新的头节点 。思路链表的删除操作如上图所示,我们需要先找到要删除的…...
计算机网络 第4章 作业1
一、选择题 1. 由网络层负责差错控制与流量控制,使分组按序被递交的传输方式是_________(C) A.电路交换 B.报文交换 C.基于虚电路的分组交换 D.基于数据报的分组交换 2. TCP/IP 参考…...
Redis-Java代码使用示例
在我之前的项目中,使用Redis是我们团队自己封装了一个Redis操作类,但是这只是在Spring提供的RedisTemplate上做了一层封装而已,当时使用不是很熟练,都是一边在网上查资料,一边使用;这篇文章会介绍两种使用方…...
acwing3485最大异或和(trie树,贪心)
给定一个非负整数数列 a,初始长度为 N。 请在所有长度不超过 M 的连续子数组中,找出子数组异或和的最大值。 子数组的异或和即为子数组中所有元素按位异或得到的结果。 注意:子数组可以为空。 输入格式 第一行包含两个整数 N,M。 第二行…...
EasyRecovery16免费的电脑的数据恢复工具
常见的数据恢复有两种方式,第一种方式是找别人恢复,按照市场价来说,数据恢复的价格每次在100-500之间,但这种方式容易使自己设备上的隐私资料泄露出去,不安全。 另一种方式则是自己学会数据恢复的方法,有问…...
银行数字化转型导师坚鹏:平安银行数字化转型—橙E网战略研究
平安银行对公业务数字化转型案例—橙E网战略研究课程背景: 很多银行存在以下问题:不清楚银行对公业务数字化转型能否成功?不知道其它银行对公业务数字化转型的实际做法? 课程特色:用实战案例解读平安银行对公业务…...
tun驱动之open
tun驱动对应的设备文件是:/dev/net/tun,其详细信息如下: crw-rw-rw- 1 root root 10, 200 2月 26 08:05 tun 主次设备号的定义如下: #define MISC_MAJOR 10 #define TUN_MINOR 200 由于tun驱动属于misc设备驱动,因此用…...
计算机网络体系结构
计算机网络体系结构是指计算机网络中各个层次和功能组成的结构体系,它定义了计算机网络中各层次之间的协议和接口,以实现不同类型、不同规模、不同性能的计算机之间的互联和通信,同时提供各种网络服务和应用。计算机网络体系结构通常被分为多…...
基础夯实,字节内部总结240道算法LeetCode刷题笔记,直呼太全
1、什么是算法算法(algorithm,[ˈlɡərɪəm],计算程序):就是定义良好的计算过程,他取一个或一组的值为输入,并产生出一个或一组值作为输出。简单来说算法就是一系列的计算步骤,用来将输入数据转化成输出结…...
wordpress滑动门/青岛app开发公司
鉴于numpy中矩阵的运算居多,所以以下内容中参与运算的数据元素都默认为矩阵,且以矩阵的逐元素相乘这个操作为例子进行说明。 numpy中的广播(broadcast)说白了就是干一件事——扩展矩阵,而且扩展对象都是纬度比较小的矩阵,将维度较…...
网站的二级页面在哪里做/网站seo快速排名
提起openstack的安装,整个人感觉都不好了,搞了将近一周时间也没能搞定Redhat、CentOS 6.5系统的安装,最后换到CentOS7.0上一次安装成功。为了以后少走弯路,记下自己愚钝的脚步。 第一次安装openstack,拿到的服务器是Re…...
虎丘网站建设/优化方案怎么写
JPA是什么 Java Persistence API:用于对象持久化的API Java EE 5.0平台标准的ORM规范,使得应用程序以统一的方式访问持久层。 JPA和Hibernate的关系 JPA是Hibernate的一个抽象(就像JDBC和JDBC驱动的关系): 1)JPA是规范…...
资源站建站技术/搜狗收录批量查询
看错误是类没有找到,但是代码中确实有这个类,编译没错,执行的时候报这个异常。 我同事的机器没事,我的有问题。 想了一下差别,就是.classPath文件不一致。 后来进 project - properties-java build path - Order and E…...
可以做公司宣传的网站有哪些/互联网营销师证书含金量
Log4J是Apache的一个开放源代码项目(http://logging.apache.org/log4j/docs/),它是一个日志操作包。通过使用Log4J,可以指定日志信息输出的目的地,控制每一条日志的输出格式,定义日志信息的级别。所有这些功能通过一个配置文件灵活进行配置。…...
珠海建设网站首页/百度搜索指数入口
ASP代码审计学习笔记 -5.文件下载漏洞 文件下载漏洞 漏洞代码: <% function download(f,n) on error resume next Set SCreateObject("Adodb.Stream") S.Mode3 S.Type1 S.Open S.LoadFromFile(f) if Err.Number>0 then …...