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.rhkb.cn/news/13326.html

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

相关文章

【漫画机器学习】082.岭回归(或脊回归)中的α值(alpha in ridge regression)

岭回归&#xff08;Ridge Regression&#xff09;中的 α 值 岭回归&#xff08;Ridge Regression&#xff09;是一种 带有 L2​ 正则化 的线性回归方法&#xff0c;用于处理多重共线性&#xff08;Multicollinearity&#xff09;问题&#xff0c;提高模型的泛化能力。其中&am…

深入理解和使用定时线程池ScheduledThreadPoolExecutor

文章目录 前言认识定时线程池什么是定时线程池&#xff1f;定时线程池基本API使用定时线程池的应用场景1、定时任务调度2、缓存过期清理3、心跳检测4、延迟任务执行 定时线程池scheduleAtFixedRate与scheduleWithFixedDelay区别scheduleAtFixedRate案例demo&#xff08;period&…

【React】合成事件语法

React 合成事件是 React 为了处理浏览器之间的事件差异而提供的一种跨浏览器的事件系统。它封装了原生的 DOM 事件&#xff0c;提供了一致的事件处理机制。 合成事件与原生事件的区别&#xff1a; 合成事件是 React 自己实现的&#xff0c;封装了原生事件。合成事件依然可以通…

中小企业的采购流程,采购管理是如何进行的?

经营中小企业的&#xff0c;都明白高效采购管理的重要性。我见过不少中小企业&#xff0c;采购环节混乱无序&#xff0c;花费大量成本&#xff0c;却难以保障物资的优质供应。然而到底该如何梳理采购流程&#xff0c;怎样开展采购管理工作呢&#xff1f;这让众多中小企业主愁眉…

在线教程丨YOLO系列10年更新11个版本,最新模型在目标检测多项任务中达SOTA

YOLO (You Only Look Once) 是计算机视觉领域中最具影响力的实时目标检测算法之一&#xff0c;以其高精度与高效性深受业界青睐&#xff0c;广泛应用于自动驾驶、安防监控、医疗影像等领域。 该模型最早于 2015 年由华盛顿大学研究生 Joseph Redmon 发布&#xff0c;开创了将目…

IOPS与吞吐量、读写块大小及延迟之间的关系

IOPS&#xff08;每秒输入/输出操作次数&#xff09;、吞吐量、读写块大小及延迟是衡量存储系统性能的四个关键指标&#xff0c;它们之间存在密切的关系。以下从多个方面详细说明这些指标之间的关系&#xff1a; 1. IOPS与吞吐量的关系 公式关系&#xff1a;吞吐量&#xff0…

DeepSeek 部署过程中的问题

文章目录 DeepSeek 部署过程中的问题一、部署扩展&#xff1a;docker 部署 DS1.1 部署1.2 可视化 二、问题三、GPU 设置3.1 ollama GPU 的支持情况3.2 更新 GPU 驱动3.3 安装 cuda3.4 下载 cuDNN3.5 配置环境变量 四、测试 DeepSeek 部署过程中的问题 Windows 中 利用 ollama 来…

DeepSeek RAGFlow构建本地知识库系统

学习目标 DeepSeek RAGFlow 构建本地知识库系统 学习内容 下载安装Docker 1.1 Docker 是什么 1.2 下载Docker 1.3 安装Docker配置DockerRAGFlow 配置 3.1 下载RAGFlow 3.2 RAGFlow配置 3.3 启动RAGFlow Docker新建知识库 4.1 查看本机IP 4.2 OLLAMA_HOST 变量配置 4.3 添加模…

11 享元(Flyweight)模式

享元模式 1.1 分类 &#xff08;对象&#xff09;结构型 1.2 提出问题 做一个车管所系统&#xff0c;将会产生大量的车辆实体&#xff0c;如果每一个实例都保存自己的所有信息&#xff0c;将会需要大量内存&#xff0c;甚至导致程序崩溃。 1.3 解决方案 运用共享技术有效…

arcgis for js范围内天地图高亮,其余底图灰暗

在GIS地图开发中&#xff0c;有时我们需要突出显示某个特定区域&#xff0c;而将其他区域灰暗处理&#xff0c;以达到视觉上的对比效果。本文将介绍如何使用ArcGIS for JavaScript实现这一功能&#xff0c;具体效果为&#xff1a;在指定范围内&#xff0c;天地图高亮显示&#…

Spring AI + Ollama 实现 DeepSeek-R1 API 服务和调用

随着大语言模型的快速发展&#xff0c;越来越多的开发者开始探索如何将这些强大的推理模型本地化运行。DeepSeek-R1&#xff0c;作为一款性能卓越的开源AI模型&#xff0c;以其低成本和出色的推理能力在技术圈内引起了广泛关注。本文将详细介绍如何使用Ollama部署DeepSeek-R1&a…

Ubuntu 20.04配置网络

1&#xff0c;检查自己网络是否配通。 网络配置成功显示的网络图标 不成功的网络图标 如果看不见网络图标&#xff0c;可以使用ping命令。连接一下百度网。 ping www.baidu.com ping失败的样子 ping成功的样子 2&#xff0c;接下来进入正题&#xff0c;我们开始配置网络。 这…

ElasticSearch入门

目录 1._cat 2.索引一个 document 3.查询document 4.更新document 5.删除document 或 index 6.批量_bulk API 1._cat Get/_cat/nodes 查看所有节点 Get/_cat/indices 查看所有索引&#xff08;indices &#xff1a;index的复数) Get/_cat/master 查看…

java练习(8)

ps:题目来自力扣 给你一个数组 nums 和一个值 val&#xff0c;你需要 原地 移除所有数值等于 val 的元素。元素的顺序可能发生改变。然后返回 nums 中与 val 不同的元素的数量。 假设 nums 中不等于 val 的元素数量为 k&#xff0c;要通过此题&#xff0c;您需要执行以下操作…

Java常用类

文章目录 包装类(Wrapper)包装类的继承体系装箱和拆箱包装类与String类型的相互转换 String类创建 String 对象的两种方式String 类的常见方法案例演示 StringBuffer类类的继承体系String VS StringBufferStringBuffer构造器String 和 StringBuffer 相互转换StringBuffer 类常见…

算法设计与分析三级项目--管道铺设系统

摘 要 该项目使用c算法逻辑&#xff0c;开发环境为VS2022&#xff0c;旨在通过Prim算法优化建筑物间的连接路径&#xff0c;以支持管线铺设规划。可以读取文本文件中的建筑物名称和距离的信息&#xff0c;并计算出建筑物之间的最短连接路径和总路径长度&#xff0c;同时以利用…

【C语言系列】深入理解指针(5)

深入理解指针&#xff08;5&#xff09; 一、sizeof和strlen的对比1.1sizeof1.2strlen1.3sizeof和strlen的对比 二、数组和指针笔试题解析2.1 一维数组2.2 字符数组2.2.1代码1&#xff1a;2.2.2代码2&#xff1a;2.2.3代码3&#xff1a;2.2.4代码4&#xff1a;2.2.5代码5&#…

设计模式——策略模式

设计模式——策略模式 简单介绍一个例子 策略模式是设计模式里面比较简单的设计模式&#xff0c;其特点简单又实用&#xff0c;并且可以让你的代码看起来高大上&#xff0c;维护代码时还方便扩张 多重条件语句不易维护&#xff0c;而使用策略模式可以避免使用多重条件语句&…

【玩转 Postman 接口测试与开发2_018】第14章:利用 Postman 初探 API 安全测试

《API Testing and Development with Postman》最新第二版封面 文章目录 第十四章 API 安全测试1 OWASP API 安全清单1.1 相关背景1.2 OWASP API 安全清单1.3 认证与授权1.4 破防的对象级授权&#xff08;Broken object-level authorization&#xff09;1.5 破防的属性级授权&a…

MySQL的 MVCC详解

MVCC是多版本并发控制&#xff0c;允许多个事务同时读取和写入数据库&#xff0c;而无需互相等待&#xff0c;从而提高数据库的并发性能。 在 MVCC 中&#xff0c;数据库为每个事务创建一个数据快照。每当数据被修改时&#xff0c;MySQL不会立即覆盖原有数据&#xff0c;而是生…