Spring 核心技术解析【纯干货版】- IX:Spring 数据访问模块 Spring-Jdbc 模块精讲

在现代企业级应用中,数据访问层的稳定性和高效性至关重要。为了简化和优化数据库操作,Spring Framework 提供了 Spring-JDBC 模块,旨在通过高度封装的 JDBC 操作,简化开发者的编码负担,减少冗余代码,同时提升系统的健壮性和可维护性。Spring-JDBC 模块的核心组成之一,JdbcTemplate,是开发者在数据库交互中最常用的工具,它不仅大幅度减少了样板代码,还自动处理了事务和异常管理。本文将深入探讨 Spring-JDBC 模块的基本功能、核心组件以及事务管理机制,帮助开发者更好地理解和使用该模块,从而提升数据访问的效率与安全性。


文章目录

      • 1、Spring-Jdbc 模块介绍
        • 1.1、Spring-Jdbc 模块概述
        • 1.2、Spring-Jdbc 模块依赖
        • 1.3、Spring-Jdbc 模块作用
      • 2、Spring-Jdbc 核心组件
        • 2.1、配置文件和依赖
        • 2.2、配置 Spring 容器
        • 2.3、启动 Spring 容器
        • 2.4、使用 `EmpDao` 类中的方法
      • 3、Spring-Jdbc 事务管理
        • 3.1、Spring JDBC 事务管理概述
        • 3.2、使用 `@Transactional` 进行声明式事务管理
        • 3.3、编程式事务管理
        • 3.4、事务传播行为
      • X、后记


1、Spring-Jdbc 模块介绍

1.1、Spring-Jdbc 模块概述

Spring JDBC 模块,是一个提供了对 JDBC 访问的高度抽象的模块,它简化了使用 JDBC 进行数据库操作的过程。

Spring JDBC 模块,它包含了一个 JdbcTemplate 类,该类封装了诸如查询、更新、事务处理等常用操作,使得编写数据库交互代码变得更加简洁且不易出错。JdbcTemplate 还能自动处理资源管理和异常翻译,提高了代码的健壮性。

1.2、Spring-Jdbc 模块依赖

Spring-Jdbc 模块的依赖有三个,分别是 Spring-Beans 模块、Spring-Core 模块和 Spring-Tx 模块。

其中 Spring Beans 模块是对 Spring Bean 进行定义,实现 IOC 基础功能的模块。Spring-Core 是 Spring 中的基础模块,它提供了框架运行所必需的核心功能。而 Spring Tx 模块,是 Spring 中处理事务管理的模块。

1.3、Spring-Jdbc 模块作用

Spring-JDBC 的主要作用:

  1. 简化 JDBC 操作:Spring-JDBC 提供了 JdbcTemplate 类,封装了 JDBC 的核心操作(如连接管理、SQL 执行、结果集处理等),开发者只需关注 SQL 语句和业务逻辑,无需手动处理资源管理(如关闭连接、结果集等)。
  2. 减少样板代码:传统的 JDBC 代码需要手动处理 ConnectionStatementResultSet 等资源的创建和释放,容易出错且代码冗长。Spring-JDBC 通过模板方法模式,自动处理这些资源,减少了重复代码。
  3. 异常处理:Spring-JDBC 将 JDBC 的 SQLException 转换为 Spring 的 DataAccessException 异常体系,提供了更清晰的异常层次结构,便于开发者处理数据库操作中的错误。
  4. 事务管理:Spring-JDBC 与 Spring 的事务管理模块无缝集成,支持声明式事务管理(通过注解或 XML 配置),简化了事务控制的实现。
  5. 支持多种数据库操作:除了基本的 CRUD 操作,Spring-JDBC 还支持批量操作、存储过程调用、复杂结果集映射等功能。
  6. 与 ORM 框架集成:Spring-JDBC 可以与其他 ORM 框架(如 Hibernate、MyBatis)结合使用,提供更灵活的数据访问方式。

2、Spring-Jdbc 核心组件

JdbcTemplate 为 Spring JDBC 的核心类,提供数据 CRUD 方法。本节介绍对于 JdbcTemplate 的使用。

2.1、配置文件和依赖

使用 Maven,确保在 pom.xml 中正确引入了相关的 Spring JDBC 和数据库连接池的依赖。例如:

    <dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.3.39</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>5.3.39</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.33</version></dependency></dependencies>
2.2、配置 Spring 容器

首先,确保我们的 Spring 配置文件配置正确,并且已经引入了 Spring 的上下文和 JDBC 配置。例如:

<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><!-- 配置数据源 --><bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource"><property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/yourdb"/><property name="username" value="yourusername"/><property name="password" value="yourpassword"/></bean><!-- 配置JdbcTemplate --><bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"><property name="dataSource" ref="dataSource"/></bean><!-- 配置EmpDao --><bean id="empDao" class="com.example.EmpDao"><property name="jdbcTemplate" ref="jdbcTemplate"/></bean>
</beans>
2.3、启动 Spring 容器

在 Spring 项目中,通常使用 ClassPathXmlApplicationContext 来加载配置文件并启动容器。我们可以在 main 方法中使用如下代码启动 Spring 容器:

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class Main {public static void main(String[] args) {// 加载 Spring 配置文件ApplicationContext context = new ClassPathXmlApplicationContext("spring-bean.xml");// 获取 EmpDao Bean 并调用方法EmpDao empDao = (EmpDao) context.getBean("empDao");// 调用 EmpDao 中的方法empDao.addEmployee("John Doe", 30);empDao.deleteEmployee(5);}
}
2.4、使用 EmpDao 类中的方法

确保我们的 EmpDao 类已经正确配置了增删改查的方法,并且使用了 JdbcTemplate。例如:

import org.springframework.jdbc.core.JdbcTemplate;public class EmpDao {private JdbcTemplate jdbcTemplate;public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {this.jdbcTemplate = jdbcTemplate;}public void addEmployee(String name, int age) {String sql = "INSERT INTO employee (name, age) VALUES (?, ?)";jdbcTemplate.update(sql, name, age);}public void deleteEmployee(int id) {String sql = "DELETE FROM employee WHERE id = ?";jdbcTemplate.update(sql, id);}
}

3、Spring-Jdbc 事务管理

Spring JDBC 提供了对事务管理的支持,使得数据库操作的事务管理更加简洁和统一。通过 Spring 的事务管理,我们可以在操作数据库时保证事务的一致性和原子性,避免数据的不一致性。

Spring 提供了两种事务管理机制:

  1. 编程式事务管理:通过代码显式地控制事务的开始、提交、回滚。
  2. 声明式事务管理:通过配置和注解(@Transactional)来实现自动的事务管理,Spring 会自动控制事务的开始、提交、回滚。
3.1、Spring JDBC 事务管理概述

Spring 提供了 DataSourceTransactionManager 来管理 JDBC 事务,它实现了 PlatformTransactionManager 接口,Spring 会通过该类来控制事务的生命周期。

  • 事务的状态:通常有 begin(开始)、commit(提交)、rollback(回滚)。
  • 传播行为:事务的传播方式,决定了一个方法被调用时,当前事务的状态。
3.2、使用 @Transactional 进行声明式事务管理

最常用的方式是通过 @Transactional 注解实现声明式事务管理。Spring 会在方法执行前开启事务,执行完毕后提交事务。如果出现异常,事务会回滚。

例子:使用 @Transactional 注解

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.annotation.Transactional;public class EmpDao {private JdbcTemplate jdbcTemplate;public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {this.jdbcTemplate = jdbcTemplate;}// 使用 @Transactional 注解,声明式事务管理@Transactionalpublic void addEmployeeAndDepartment(String empName, int empAge, String deptName) {String addEmployeeSql = "INSERT INTO employee (name, age) VALUES (?, ?)";jdbcTemplate.update(addEmployeeSql, empName, empAge);String addDepartmentSql = "INSERT INTO department (name) VALUES (?)";jdbcTemplate.update(addDepartmentSql, deptName);// 模拟一个错误,事务应该回滚if (empAge < 0) {throw new RuntimeException("Invalid age");}}
}

在上面的例子中:

  • @Transactional 注解表示在 addEmployeeAndDepartment 方法执行时,Spring 会自动管理事务。
  • 如果方法正常执行,事务会提交。
  • 如果方法抛出异常,Spring 会自动回滚事务。

配置支持事务管理:

为了让 Spring 管理事务,我们需要在配置文件中启用事务管理器,并且确保 Spring 容器扫描事务管理相关注解。

<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsd"><!-- 配置事务管理器 --><bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource"><property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/yourdb"/><property name="username" value="yourusername"/><property name="password" value="yourpassword"/></bean><bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"/></bean><!-- 开启事务管理 --><tx:annotation-driven transaction-manager="transactionManager"/>
</beans>
3.3、编程式事务管理

如果不想使用声明式事务,可以使用编程式事务管理。在这种方式中,我们需要显式地使用 PlatformTransactionManager 来控制事务。

例子:编程式事务管理

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;public class EmpDao {private JdbcTemplate jdbcTemplate;private PlatformTransactionManager transactionManager;public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {this.jdbcTemplate = jdbcTemplate;}public void setTransactionManager(PlatformTransactionManager transactionManager) {this.transactionManager = transactionManager;}public void addEmployeeAndDepartment(String empName, int empAge, String deptName) {// 创建事务定义DefaultTransactionDefinition def = new DefaultTransactionDefinition();def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);TransactionStatus status = transactionManager.getTransaction(def);try {String addEmployeeSql = "INSERT INTO employee (name, age) VALUES (?, ?)";jdbcTemplate.update(addEmployeeSql, empName, empAge);String addDepartmentSql = "INSERT INTO department (name) VALUES (?)";jdbcTemplate.update(addDepartmentSql, deptName);// 模拟一个错误,事务应该回滚if (empAge < 0) {throw new RuntimeException("Invalid age");}// 提交事务transactionManager.commit(status);} catch (Exception e) {// 回滚事务transactionManager.rollback(status);throw e; // 抛出异常}}
}

在编程式事务管理中,我们需要手动创建事务定义(DefaultTransactionDefinition),并使用 PlatformTransactionManager 来开始、提交或回滚事务。

3.4、事务传播行为

事务的传播行为决定了事务在多个方法调用之间如何传播。常见的传播行为有:

  • PROPAGATION_REQUIRED:如果当前没有事务,则新建一个事务;如果已有事务,则加入当前事务(默认行为)。
  • PROPAGATION_REQUIRES_NEW:无论当前是否有事务,都会新建一个事务。
  • PROPAGATION_NESTED:支持事务嵌套。如果当前事务存在,则会在当前事务内开启一个子事务。

我们可以通过设置 @Transactional 注解的 propagation 属性来控制传播行为,例如:

@Transactional(propagation = Propagation.REQUIRES_NEW)
public void addEmployeeAndDepartmentWithNewTransaction(String empName, int empAge, String deptName) {// 新建事务,独立于外部事务
}

X、后记

通过本文的讲解,我们深入了解了 Spring-JDBC 模块如何通过 JdbcTemplate 类,简化 JDBC 操作,并自动处理数据库连接、事务管理和异常翻译等繁琐任务。Spring-JDBC 不仅减轻了开发者的工作量,还能显著提高代码的可读性和可维护性。无论是常见的增删改查操作,还是复杂的事务控制,Spring-JDBC 都提供了极其简洁和灵活的解决方案。掌握这些核心技术,将为开发者带来更高效、可靠的数据库交互体验。希望大家能将本文中的知识点应用到实际开发中,不断优化和提升自己的技术水平。

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

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

相关文章

2.5学习

misc buuctf-假如给我三天光明 下载附件后得到了一个压缩包和一个图片&#xff0c;压缩包为加密压缩包&#xff0c;需要解出密码&#xff0c;然后注意到这个图片并非简单的一个封面&#xff0c;在下方还有诸多点&#xff0c;有黑有灰。经过搜索&#xff0c;发现这是盲文通过与…

java进阶1——JVM

java进阶——JVM 1、JVM概述 作用 Java 虚拟机就是二进制字节码的运行环境&#xff0c;负责装载字节码到其内部&#xff0c;解释/编译为对 应平台上的机器码指令行&#xff0c;每一条 java 指令&#xff0c;java 虚拟机中都有详细定义&#xff0c;如怎么取操 作数&#xff0c…

搭建集成开发环境PyCharm

1.下载安装Python&#xff08;建议下载并安装3.9.x&#xff09; https://www.python.org/downloads/windows/ 要注意勾选“Add Python 3.9 to PATH”复选框&#xff0c;表示将Python的路径增加到环境变量中 2.安装集成开发环境Pycharm http://www.jetbrains.com/pycharm/…

《redis4.0 通信模块源码分析(一)》

【redis导读】redis作为一款高性能的内存数据库&#xff0c;面试服务端开发&#xff0c;redis是绕不开的话题&#xff0c;如果想提升自己的网络编程的水平和技巧&#xff0c;redis这款优秀的开源软件是很值得大家去分析和研究的。 笔者从大学毕业一直有分析redis源码的想法&…

开源安全一站式构建!开启企业开源治理新篇章

在如今信息技术日新月异、飞速发展的数字化时代&#xff0c;开源技术如同一股强劲的东风&#xff0c;为企业创新注入了源源不断的活力&#xff0c;然而&#xff0c;正如一枚硬币有正反两面&#xff0c;开源技术的广泛应用亦伴随着不容忽视的挑战。安全风险如影随形&#xff0c;…

DeePseek结合PS!批量处理图片的方法教程

​ ​ 今天我们来聊聊如何利用deepseek和Photoshop&#xff08;PS&#xff09;实现图片的批量处理。 传统上&#xff0c;批量修改图片尺寸、分辨率等任务往往需要编写脚本或手动处理&#xff0c;而现在有了AI的辅助&#xff0c;我们可以轻松生成PS脚本&#xff0c;实现自动化处…

Verilog基础(三):过程

过程(Procedures) - Always块 – 组合逻辑 (Always blocks – Combinational) 由于数字电路是由电线相连的逻辑门组成的,所以任何电路都可以表示为模块和赋值语句的某种组合. 然而,有时这不是描述电路最方便的方法. 两种always block是十分有用的: 组合逻辑: always @(…

2024年12月 Scratch 图形化(一级)真题解析 中国电子学会全国青少年软件编程等级考试

202412 Scratch 图形化&#xff08;一级&#xff09;真题解析 中国电子学会全国青少年软件编程等级考试 一、单选题(共25题&#xff0c;共50分) 第 1 题 点击下列哪个按钮&#xff0c;可以将红框处的程序放大&#xff1f;&#xff08; &#xff09; A. B. C. D. 标…

C++【深入 STL--list 之 迭代器与反向迭代器】

接前面的手撕list(上)文章&#xff0c;由于本人对于list的了解再一次加深。本文再次对list进行深入的分析与实现。旨在再一次梳理思路&#xff0c;修炼代码内功。 1、list 基础架构 list底层为双向带头循环链表&#xff0c;问题是如何来搭建这个list类。可以进行下面的考虑&am…

如何打开vscode系统用户全局配置的settings.json

&#x1f4cc; settings.json 的作用 settings.json 是 Visual Studio Code&#xff08;VS Code&#xff09; 的用户配置文件&#xff0c;它存储了 编辑器的个性化设置&#xff0c;包括界面布局、代码格式化、扩展插件、快捷键等&#xff0c;是用户全局配置&#xff08;影响所有…

STM32 ADC模数转换器

ADC简介 ADC&#xff08;Analog-Digital Converter&#xff09;模拟-数字转换器 ADC可以将引脚上连续变化的模拟电压转换为内存中存储的数字变量&#xff0c;建立模拟电路到数字电路的桥梁 12位逐次逼近型ADC&#xff0c;1us转换时间 输入电压范围&#xff1a;0~3.3V&#xff0…

(2025,LLM,下一 token 预测,扩散微调,L2D,推理增强,可扩展计算)从大语言模型到扩散微调

Large Language Models to Diffusion Finetuning 目录 1. 概述 2. 研究背景 3. 方法 3.1 用于 LM 微调的高斯扩散 3.2 架构 4. 主要实验结果 5. 结论 1. 概述 本文提出了一种新的微调方法——LM to Diffusion (L2D)&#xff0c;旨在赋予预训练的大语言模型&#xff08;…

学习threejs,pvr格式图片文件贴图

&#x1f468;‍⚕️ 主页&#xff1a; gis分享者 &#x1f468;‍⚕️ 感谢各位大佬 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍⚕️ 收录于专栏&#xff1a;threejs gis工程师 文章目录 一、&#x1f340;前言1.1 ☘️PVR贴图1.2 ☘️THREE.Mesh…

tkvue 入门,像写html一样写tkinter

介绍 没有官网&#xff0c;只有例子 安装 像写vue 一样写tkinter 代码 pip install tkvue作者博客 修改样式 import tkvue import tkinter.ttk as ttktkvue.configure_tk(theme"clam")class RootDialog(tkvue.Component):template """ <Top…

Java—不可变集合

不可变集合&#xff1a;不可以被修改的集合 创建不可变集合的应用场景 如果某个数据不能被修改&#xff0c;把它防御性地拷贝到不可变集合中是个很好的实践。当集合对象被不可信的库调用时&#xff0c;不可变形式是安全的。 简单理解&#xff1a;不想让别人修改集合中的内容…

每日Attention学习18——Grouped Attention Gate

模块出处 [ICLR 25 Submission] [link] UltraLightUNet: Rethinking U-shaped Network with Multi-kernel Lightweight Convolutions for Medical Image Segmentation 模块名称 Grouped Attention Gate (GAG) 模块作用 轻量特征融合 模块结构 模块特点 特征融合前使用Group…

响应式编程_04Spring 5 中的响应式编程技术栈_WebFlux 和 Spring Data Reactive

文章目录 概述响应式Web框架Spring WebFlux响应式数据访问Spring Data Reactive 概述 https://spring.io/reactive 2017 年&#xff0c;Spring 发布了新版本 Spring 5&#xff0c; Spring 5 引入了很多核心功能&#xff0c;这其中重要的就是全面拥抱了响应式编程的设计思想和实…

html中的表格属性以及合并操作

表格用table定义&#xff0c;标签标题用caption标签定义&#xff1b;用tr定义表格的若干行&#xff1b;用td定义若干个单元格&#xff1b;&#xff08;当单元格是表头时&#xff0c;用th标签定义&#xff09;&#xff08;th标签会略粗于td标签&#xff09; table的整体外观取决…

基于Springboot+vue的租车网站系统

基于SpringbootVue的租车网站系统是一个现代化的在线租车平台&#xff0c;它结合了Springboot的后端开发能力和Vue的前端交互优势&#xff0c;为用户和汽车租赁公司提供了一个高效、便捷、易用的租车体验和管理工具。以下是对该系统的详细介绍&#xff1a; 一、系统架构 后…

蓝桥杯之c++入门(二)【输入输出(上)】

目录 前言1&#xff0e;getchar和 putchar1.1 getchar()1.2 putchar() 2&#xff0e;scanf和 printf2.1 printf2.1.1基本用法2.1.2占位符2.1.3格式化输出2.1.3.1 限定宽度2.1.3.2 限定小数位数 2.2 scanf2.2.1基本用法2.2.2 占位符2.2.3 scanf的返回值 2.3练习练习1&#xff1a…