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,一经查实,立即删除!

相关文章

探秘AI的两大核心:决策式AI与生成式AI‌

目录 一、引言 二、从定义上来看 1. 决策式AI&#xff08;Discriminative AI&#xff09; 2. 生成式AI&#xff08;Generative AI&#xff09; 三、从技术原理上来看 1. 决策式AI&#xff08;Discriminative AI&#xff09; 2. 生成式AI&#xff08;Generative AI&#…

2.5学习

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

sed变量中特殊字符/处理方式

个人博客地址&#xff1a;sed变量中特殊字符/处理方式 | 一张假钞的真实世界 如果变量值中包含斜杠&#xff08;/&#xff09;特殊字符&#xff0c;在使用sed命令的做行内字符串替换时可以使用井号&#xff08;#&#xff09;做为sed语法分隔符&#xff0c;如下&#xff1a; G…

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/…

vue2-v-if和v-for的优先级

vue2-v-if和v-for的优先级 1.v-if和v-for的作用 v-if是条件渲染&#xff0c;只有条件表达式true的情况下&#xff0c;才会渲染v-for是基于一个数组来渲染一个列表&#xff0c;在v-for的时候&#xff0c;保证给每个元素添加独一无二的key值&#xff0c;便于diff算法进行优化 …

通过C/C++编程语言实现“数据结构”课程中的链表

引言 链表(Linked List)是数据结构中最基础且最重要的线性存储结构之一。与数组的连续内存分配不同,链表通过指针将分散的内存块串联起来,具有动态扩展和高效插入/删除的特性。本文将以C/C++语言为例,从底层原理到代码实现,手把手教你构建完整的链表结构,并深入探讨其应…

《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;实现自动化处…

13.代理模式(Proxy Pattern)

定义 代理模式&#xff08;Proxy Pattern&#xff09; 是一种结构型设计模式&#xff0c;它通过提供一个代理对象来控制对目标对象的访问。代理对象作为客户端与目标对象之间的中介&#xff0c;间接地访问目标对象的功能。代理模式可以在不改变目标对象的情况下增加一些额外的…

DBeaver连接MySQL提示Access denied for user ‘‘@‘ip‘ (using password: YES)的解决方法

在使用DBeaver连接MySQL数据库时&#xff0c;如果遇到“Access denied for user ip (using password: YES)”的错误提示&#xff0c;说明用户认证失败。此问题通常与数据库用户权限、配置错误或网络设置有关。本文将详细介绍解决此问题的步骤。 一、检查用户名和密码 首先&am…

Python进行模型优化与调参

在数据科学与机器学习领域,模型的优化与调参是提高模型性能的重要步骤之一。模型优化可以帮助提高模型的准确性和泛化能力,而合理的调参则能够充分发挥模型的潜力。这篇教程将重点介绍几种常用的模型优化与调参方法,特别是超参数调整和正则化技术的应用。这些技术能够有效地…

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;影响所有…

wordpress外贸独立站常用询盘软件

LiveChat LiveChat是一家提供实时聊天软件的公司&#xff0c;帮助企业通过其平台与客户进行即时通讯&#xff0c;提高客户满意度和忠诚度。他们的产品允许企业在网站、应用程序或电子邮件等多个渠道与客户互动&#xff0c;从而提升客户体验并促进销售增长。 LiveChat的软件特…

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;…