Spring JDBC及声明式事务

目录

Spring JDBC基础概念        

Spring声明式事务

 事务传播方式


Spring JDBC基础概念        

        Spring JDBC 封装了原生的JDBC API,使得处理关系型数据库更加简单。Spring JDBC的核心是JdbcTemplate,里面封装了大量数据库CRUD的操作。使用Spring JDBC有如下步骤:

1、pom增加依赖

        <dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.2.20.RELEASE</version></dependency><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.6</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>5.2.22.RELEASE</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.16</version></dependency><dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId><version>1.2.3</version></dependency>

spring-context是spring的核心,负责容器中对象实例创建;spring-jdbc是对原生jdbc的封装;logback-classic主要为了数据库操作时辅助信息的日志输出。

2、IOC容器实例化数据源对象dataSource和JdbcTemplate对象

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:tx="http://www.springframework.org/schema/tx"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttps://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/txhttps://www.springframework.org/schema/tx/spring-tx.xsdhttp://www.springframework.org/schema/aophttps://www.springframework.org/schema/aop/spring-aop.xsd"><context:component-scan base-package="com.text"/><bean id="dataSource"  class="org.springframework.jdbc.datasource.DriverManagerDataSource"><property name="driverClassName" value="com.mysql.cj.jdbc.Driver"></property><property name="url" value="jdbc:mysql://xxx.xxx.xxx.xxx:3306/test"></property><property name="username" value="test"></property><property name="password" value="test"></property></bean><bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"><property name="dataSource" ref="dataSource"></property></bean>
</beans>

 3、在各个DAO实现类中注入JdbcTemplate对象,通过JdbcTemplate的API实现数据库CRUD

JdbcTemplate的API重要的API:

  • jdbcTemplate.query* :各种查询方法
  • jdbcTemplate.update:各种新增、修改、删除等方法

示例:学生信息查询、新增

package com.text.dao.impl;import com.text.dao.StudentDao;
import com.text.entity.Student;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;import javax.annotation.Resource;@Repository
public class StudentDaoImpl implements StudentDao {@Resourceprivate JdbcTemplate jdbcTemplate;@Overridepublic Student getById(String id) throws Exception {String sql = "select * from student where id = ?";Student student = jdbcTemplate.queryForObject(sql, new Object[]{id}, new BeanPropertyRowMapper<>(Student.class));return student;}@Overridepublic void insert(Student student) throws Exception {String sql = "insert into student(id,name,age) values (?,?,?)";jdbcTemplate.update(sql,new Object[]{student.getId(),student.getName(),student.getAge()});}
}

Spring声明式事务

        上文的案例中,没有添加事务支持,如果在Service层封装了Dao层并且做了批量操作的动作,在批量操作时系统出现异常,会出现部分数据提交到数据库的情况,不满足数据同时提交、同时回滚的情况,参考代码如下:

1、Service服务类

package com.text.service;import com.text.entity.Student;public interface StudentService {void batchSave() throws Exception;Student searchById(String id) throws Exception;
}
package com.text.service.impl;import com.text.dao.StudentDao;
import com.text.entity.Student;
import com.text.service.StudentService;
import org.springframework.stereotype.Service;import javax.annotation.Resource;@Service
public class StudentServiceImpl implements StudentService {@Resourceprivate StudentDao studentDao;@Overridepublic void batchSave() throws Exception {for(int i=10;i<=20;i++) {if(i==15) {throw new RuntimeException("系统出现异常");}Student student = new Student(i+"","张三"+i,20);this.studentDao.insert(student);}}@Overridepublic Student searchById(String id) throws Exception {return this.studentDao.getById(id);}
}

 2、测试类

package com.text;import com.text.entity.Student;
import com.text.service.StudentService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class Application {public static void main(String[] args) throws Exception {ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");StudentService studentService = context.getBean("studentServiceImpl", StudentService.class);Student student = studentService.searchById("1");System.out.println(student);studentService.batchSave();}
}

3、运行结果分析:

 

从程序运行结果可以看出,程序循环插入10条数据时,程序每次都获取新的数据库连接,程序执行到第15条时,系统发生异常,前面10-14条数据提交到了数据库,不满足10条数据同时提交或同时回滚,通过配置事务管理器可以解决此问题。

        Spring声明式事务是针对编程式事务而言的,编程式事务就是在程序内部手工的编写Commit和Rollback方法进行事务的提交和回滚,编写相对麻烦,本文重点讨论基于注解声明式事务

        Spring声明式事务,实现的原理就是AOP的环绕通知,在程序全部执行正常后,自动提交事务,在程序出现异常时,自动回滚事务。实现基于注解Spring声明式事务,经过如下步骤:

1、配置事务管理器及开启注解形式的声明式事务

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:tx="http://www.springframework.org/schema/tx"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttps://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/txhttps://www.springframework.org/schema/tx/spring-tx.xsdhttp://www.springframework.org/schema/aophttps://www.springframework.org/schema/aop/spring-aop.xsd"><context:component-scan base-package="com.text"/><bean id="dataSource"  class="org.springframework.jdbc.datasource.DriverManagerDataSource"><property name="driverClassName" value="com.mysql.cj.jdbc.Driver"></property><property name="url" value="jdbc:mysql://xxx.xxx.xxx.xxx:3306/test"></property><property name="username" value="test"></property><property name="password" value="test"></property></bean><bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"><property name="dataSource" ref="dataSource"></property></bean><!--事务管理器--><bean id="transactionManager"     class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"/></bean><!-- 启用注解形式声明式事务 --><tx:annotation-driven transaction-manager="transactionManager"/>
</beans>

2、在需要事务的服务类上添加注解@Transactional

package com.text.service.impl;import com.text.dao.StudentDao;
import com.text.entity.Student;
import com.text.service.StudentService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;import javax.annotation.Resource;@Service
public class StudentServiceImpl implements StudentService {@Resourceprivate StudentDao studentDao;@Transactional //添加事务支持@Overridepublic void batchSave() throws Exception {for(int i=10;i<=20;i++) {if(i==15) {throw new RuntimeException("系统出现异常");}Student student = new Student(i+"","张三"+i,20);this.studentDao.insert(student);}}@Overridepublic Student searchById(String id) throws Exception {return this.studentDao.getById(id);}
}

3、测试类(和上面一致),运行后结果:

     

从运行结果看出,由于service的批量插入方法上添加了事务支持,批量新增时,用的是同一个数据库连接,系统发生异常后,数据没有出现部分提交的情况。

 事务传播方式

        Spring事务的默认的事务传播特性是Required,即当前环境没有事务,则创建一个事务,如果已经在一个事务中,则加入这个事务中。几种事务传播特性如下:

  1. required  如果有事务正在运行,当前方法就在这个事务内运行,否则就启动一个新的事务,并在自己的事务内运行;
  2. requires_new 总是主动开启事务;如果存在外层事务,就将外层事务挂起
  3. supports 如果不存在外层事务,就不开启事务;否则使用外层事务
  4. not_supported 当前的方法不应该运行在事务中,如果当前有运行的事务,将它挂起
  5. mandatory 当前的方法必须运行在事务内部,如果没有正在运行的事务,就抛出异常
  6. never 当前的方法不应该运行在事务中,如果运行在事务中就抛出异常
  7. nested 如果有事务在运行,当前的方法就应该在这个事务的嵌套事务内运行,否则就启动一个新的事务,并在它自己的事务内运行    

示例:requires_new 总是主动开启事务;如果存在外层事务,就将外层事务挂起

A方法调用了B和C,其中A,B和C采用的是requires_new 传播特性,则程序内部事务如下示意图:

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

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

相关文章

[uni-app]小兔鲜-02项目首页

轮播图 轮播图组件需要在首页和分类页使用, 封装成通用组件 准备轮播图组件 <script setup lang"ts"> import type { BannerItem } from /types/home import { ref } from vue // 父组件的数据 defineProps<{list: BannerItem[] }>()// 高亮下标 const…

影响6个时序Baselines模型的代码Bug

前言 我是从去年年底开始入门时间序列研究&#xff0c;但直到最近我读FITS这篇文章的代码时&#xff0c;才发现从去年12月25号就有人发现了数个时间序列Baseline的代码Bug。如果你已经知道这个Bug了&#xff0c;那可以忽略本文&#xff5e; 这个错误最初在Informer&#xff0…

安科瑞Acrel-1000DP分布式光伏监控系统在鄂尔多斯市鄂托克旗巴音乌苏六保煤矿5MW分布式光伏项目中的应用

安科瑞 华楠 摘 要&#xff1a;分布式光伏发电就是将太阳能光伏板分散布置在各个区域&#xff0c;通过小规模、模块化的方式实现电能的并网或独立使用&#xff0c;这种发电方式具有就近发电、就近并网、就近转换、就近使用的特点。近年来&#xff0c;技术进步和政策支持推动了光…

Python在AI中的应用--使用决策树进行文本分类

Python在AI中的应用--使用决策树进行文本分类 文本分类决策树什么是决策树 scikit算法 使用scikit的决策树进行文章分类一个文本分类的Python代码使用的scikit APIs说明装入数据集决策树算法类类构造器&#xff1a; 构造决策树分类器产生输出评估输出结果分类准确度分类文字评估…

计算机前沿技术-人工智能算法-大语言模型-最新论文阅读-2024-09-22

计算机前沿技术-人工智能算法-大语言模型-最新论文阅读-2024-09-22 引言: 全球最热销的国产游戏-《黑神话: 悟空》不仅给世界各地玩家们带来愉悦&#xff0c;而且对计算机人工智能研究也带来新的思考。在本期的论文速读中&#xff0c;我们带来一篇关于视觉语言模型&#xff0…

漫步者头戴式耳机好用吗?漫步者、西圣、万魔顶级机型测评对比

现在市面上有很多头戴式耳机&#xff0c;它们都基本精进主动降噪功能&#xff0c;以让大家在生活中能更少受到噪音的干扰&#xff0c;所以对于有降噪需求的人来说&#xff0c;头戴式耳机就是很适合他们的一种耳机。作为一名数码测评博主&#xff0c;也有很多人问我漫步者头戴式…

C++的vector优化

1、C中的动态数组一般是特指vector类 2、vector需要优化的原因之一是当我们push_back元素到数组中时&#xff0c;如果原来分配给动态数组的内存不够用了&#xff0c;那么就会找一块更大的内存空间分配给数组&#xff0c;把旧的内容复制到新的内存中去&#xff0c;这就是导致程…

大数据处理从零开始————3.Hadoop伪分布式和分布式搭建

1.伪分布式搭建&#xff08;不会用&#xff0c;了解就好不需要搭建&#xff09; 这里接上一节。 1.1 伪分布式集群概述 伪分布式集群就是只有⼀个服务器节点的分布式集群。在这种模式中&#xff0c;我们也是只需要⼀台机器。 但与本地模式不同&#xff0c;伪分布式采⽤了分布式…

C++简单缓冲区类设计

目录 1.引言 2.静态缓冲区 3.动态缓冲区 4.数据引用类 5.自动数据引用类 6.几种缓冲区的类关系图 7.注意事项 8.完整代码 1.引言 在C中&#xff0c;设计静态和动态缓冲区类时&#xff0c;需要考虑的主要差异在于内存管理的方式。静态缓冲区类通常使用固定大小的内存区域…

红绿灯倒计时读秒数字识别系统源码分享

红绿灯倒计时读秒数字识别检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of …

Power Automate 设置流Owner不生效的bug

在查找某个功能没生效时&#xff0c;定位到是一个Power automate的流停了&#xff0c;查看原因是因为创建流的owner被disable了 但是当把流的owner更新为可用的用户时&#xff0c;流依旧没被触发&#xff0c;触发的条件很简单&#xff0c;某个表的记录创建时&#xff0c;因为是…

Java流程控制语句——条件控制语句详解(附有流程图)#Java条件控制语句有哪些?#if-else、switch

在 Java 编程中&#xff0c;条件控制语句用于控制程序的执行路径&#xff0c;决定根据某些条件来选择执行某段代码或跳过某段代码。它们是 Java 编程的重要组成部分&#xff0c;帮助开发者根据不同的输入、状态或数据流来编写更加灵活和动态的代码。在本文中&#xff0c;我们将…

CORE MVC 过滤器 (筛选器)

MVC FrameWork MVCFramework MVC Core 过滤器 分 同步、异步 1、 授权筛选器 IAuthorizationFilter&#xff0c;IAsyncAuthorizationFilter 管道中运行的第一类筛选器&#xff0c;用来确定发出请求的用户是否有权限发出当前请求 2、资源筛选器 IResourceFilter &#xff0c;…

部分监督多器官医学图像分割中的标记与未标记分布对齐|文献速递--基于多模态-半监督深度学习的病理学诊断与病灶分割

Title 题目 Labeled-to-unlabeled distribution alignment for partially-supervised multi-organ medical image segmentation 部分监督多器官医学图像分割中的标记与未标记分布对齐 01 文献速递介绍 多器官医学图像分割&#xff08;Mo-MedISeg&#xff09;是医学图像分析…

【Python报错已解决】ModuleNotFoundError: No module named ‘tensorflow‘

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 专栏介绍 在软件开发和日常使用中&#xff0c;BUG是不可避免的。本专栏致力于为广大开发者和技术爱好者提供一个关于BUG解决的经…

DAY16||513.找树左下角的值 |路径总和|从中序与后序遍历序列构造二叉树

513.找树左下角的值 题目&#xff1a;513. 找树左下角的值 - 力扣&#xff08;LeetCode&#xff09; 给定一个二叉树的 根节点 root&#xff0c;请找出该二叉树的 最底层 最左边 节点的值。 假设二叉树中至少有一个节点。 示例 1: 输入: root [2,1,3] 输出: 1示例 2: 输入: […

Techub专访顾荣辉教授:解密CertiK的安全战略路线

当 Web3 安全审计公司还在争抢审计份额时&#xff0c;CertiK 已经开始将目光瞄准即将进军 Web3 的传统商业巨头。CertiK 不仅在传统行业进行白帽行动获得如苹果公司的官方感谢&#xff0c;还是 Web3 行业唯一一家拥有 SOC 2 和 ISO 认证的 Web3 的安全公司。基于此&#xff0c;…

猫头虎 分享已解决Bug: || Module not found: Can‘t resolve ‘react‘ 解决方案

&#x1f42f;猫头虎 分享已解决Bug&#xff1a; || Module not found: Cant resolve react 解决方案 摘要: 今天猫头虎带大家解决一个常见的前端问题&#xff0c;尤其是在 React 项目中&#xff0c;很多开发者在安装依赖包时&#xff0c;遇到过 Module not found: Cant resol…

裁剪视频如何让画质不变?一文教会你

当我们想要从一段视频中提取精华&#xff0c;裁剪视频就成了必不可少的技能。 但是&#xff0c;如何做到在裁剪过程中不损害画质&#xff0c;保持视频原有的清晰度和流畅度呢&#xff1f; 这不仅需要技巧&#xff0c;还需要对视频编辑有一定的了解。 本文将为你介绍四种裁剪…

基于SSM的图书管理管理系统的设计与实现 (含源码+sql+视频导入教程)

&#x1f449;文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1 、功能描述 基于SSM的图书管理管理系统4拥有两种角色&#xff0c;用户可以浏览评论图书、登录注册&#xff0c;管理员可以进行图书馆管理、用户管理、分类管理等功能 1.1 背景描述 图书书店销售管理…