【JdbcTemplate】为什么使用JdbcTemplate的这些API必须要加try catch?

Spring JdbcTemplate核心应用与性能优化实践 数据库访问层是Java企业应用的核心组件,传统JDBC API虽然功能完备但存在大量模板代码。Spring框架通过JdbcTemplate实现了轻量级数据访问,其核心原理是通过模板方法模式封装资源管理逻辑,开发者只需关注SQL与业务逻辑。这种设计在微服务架构中尤其重要,能减少40%以上的持久层代码量,同时保持对SQL的完全控制权。JdbcTemplate特别适合需要平衡开发效率与执行性能的场景,如高频CRUD操作、批量数据处理等。结合HikariCP连接池和声明式事务管理,可以构建出高性能的数据访问层。对于 阅读详情

软件版本 java8 spring-jdbc-4.1.6.RELEASE.jar

简单查询

首先我们来看这样一段代码。

Map map = jdbcTemplate.queryForMap("SELECT * FROM t_user WHERE user_id = '123'");

看起来只是非常简单的一句查询,它使用jdbcTemplate#queryForMap方法去查询一个user_id = '123'的用户,并将查询结果返回到Map。

看似一切都很正常合理。但是,事情真的有这么简单吗?

如果有人review了你的代码突然这么反问你,那么在这简单的背后往往都暗藏了一些猫腻。

背后那些不为人知的秘密

我们先进queryForMap方法去看一下。

public Map<String, Object> queryForMap(String sql) throws DataAccessException {
	return (Map)this.queryForObject(sql, this.getColumnMapRowMapper());
}

果然,从queryForMap的方法能看到,

  1. 它抛出了一个非检查性异常DataAccessException,

  2. 并且我们能发现queryForMap内部,实际是调用的queryForObject方法。

我们再进queryForObject方法去看一下。

public <T> T queryForObject(String sql, RowMapper<T> rowMapper) throws DataAccessException {
	List<T> results = this.query(sql, rowMapper);
	return DataAccessUtils.requiredSingleResult(results);
}

从queryForObject的方法我们能得到一下信息,

  1. 它抛出了一个非检查性异常DataAccessException,

  2. 根据方法的返回参数判断,它的返回值为单个实体,也就是说queryForMap方法的返回值也只是一条数据。

  3. 对返回值做了requiredSingleResult检查。

我们再进requiredSingleResult方法去看一下。

spring-tx-4.1.6.RELEASE.jar

public static <T> T requiredSingleResult(Collection<T> results) throws IncorrectResultSizeDataAccessException {
	int size = results != null ? results.size() : 0;
	if (size == 0) {
		throw new EmptyResultDataAccessException(1);
	} else if (results.size() > 1) {
		throw new IncorrectResultSizeDataAccessException(1, size);
	} else {
		return results.iterator().next();
	}
}

好家伙!原来坑就在这里,

  1. 如果查询结果集为空,则会抛出EmptyResultDataAccessException,

  2. 如果查询结果集大于1,则会抛出IncorrectResultSizeDataAccessException,

  3. 只有当查询结果集等于一条数据时,才能正常返回数据。

spring-tx-5.1.14.RELEASE.jar

public static <T> T requiredSingleResult(@Nullable Collection<T> results) throws IncorrectResultSizeDataAccessException {
	if (CollectionUtils.isEmpty(results)) {
		throw new EmptyResultDataAccessException(1);
	} else if (results.size() > 1) {
		throw new IncorrectResultSizeDataAccessException(1, results.size());
	} else {
		return results.iterator().next();
	}
}

@Nullable
public static <T> T nullableSingleResult(@Nullable Collection<T> results) throws IncorrectResultSizeDataAccessException {
	if (CollectionUtils.isEmpty(results)) {
		throw new EmptyResultDataAccessException(1);
	} else if (results.size() > 1) {
		throw new IncorrectResultSizeDataAccessException(1, results.size());
	} else {
		return results.iterator().next();
	}
}

这里我还贴出了 5.x 版本的源码。在 5.x 版本的queryForObject方法,是使用的nullableSingleResult方法进行结果集的校验。

nullableSingleResult翻译为可为空的单一结果,我个人觉得这个方法的命名是具有误导性的,更推荐使用requiredSingleResult。

推荐的使用方式

其实对于查询结果集为空时,我们并不希望它直接抛出异常,所以我们可以把EmptyResultDataAccessException捕获一下,并返回一个空的Map。

Map<String, Object> map = null;
try {
	map = jdbcTemplate.queryForMap("SELECT * FROM t_user WHERE user_id = '123'");
} catch (EmptyResultDataAccessException e) {
	map = Collections.EMPTY_MAP;
}

小结一下

我们在使用JdbcTemplate的这两个查询API时必须要加try {} catch () {}进行处理:

  1. queryForMap

  2. queryForObject

想想,如果我们不进行异常捕获或处理,当查询结果集为空时,是很容易导致线上事故的。

彩蛋

今天对我来说是特别的一天,因为今天是我的生日!

今天我还邀请了两个同事,一起去大井巷的秀孃孃串串打了个卡,生日过的也算是蛮开心的呢。

宝贝给我说,我又老了一岁了!我永远都会比她大一岁,她好开心啊!

哈哈,确实是酱紫。

祝自己25岁生日快乐呀🎂🎂🎂!Happy birthday to me!

Spring JdbcTemplate批量操作实战:原理、性能优化与避坑指南 在Java企业级应用开发中,数据库批处理是提升数据持久化性能的核心技术之一。其原理在于将多条结构相同的SQL语句打包,通过JDBC的PreparedStatement机制一次性发送给数据库执行,从而大幅减少网络往返和数据库解析开销。这项技术对于处理海量数据插入、更新等场景具有极高的工程价值,能够将线性增长的操作耗时优化为近似常数级别,广泛应用于数据迁移、批量导入和实时统计等高性能需求场景。本文聚焦于Spring框架中的JdbcTemplate批处理实现,深入剖析其两种使用模式——BatchPreparedS 阅读详情

相关推荐

Spring JDBC深度解析:连接治理、事务协同与生产级调优

JDBC是Java数据库交互的底层契约,而Spring JDBC并非简单封装,而是面向高并发、多数据源、强一致场景的连接治理协议。其核心在于统一异常体系(DataAccessException)、线程安全的Connection生命周期管理(依托DataSource与TransactionSynchronizationManager),以及与HikariCP等连接池的深度协同。技术价值体现在可控的SQL执行路径、零ORM开销的精准资源调度、跨数据库的异常语义抽象。典型应用场景包括金融系统DAO层重构、MyBa

chuliaoqiao4046的博客 409

mysql try catch语句_java连接数据库一定要用try catch语句吗

importjava.sql.Connection;importjava.sql.DriverManager;importjava.sql.ResultSet;importjava.sql.Statement;publicclassa{publicstaticvoidmain(String[]args){try{Stringurl="jd...import java.sql.Connection;...

weixin_35648264的博客 1351

Java面试高频考点:ConcurrentHashMap与Stream API解析

在Java并发编程中,ConcurrentHashMap作为线程安全的哈希表实现,通过分段锁和CAS机制显著提升性能。其核心原理在于减小锁粒度,利用volatile保证可见性,并通过无锁化操作降低竞争开销。类似地,Java 8引入的Stream API通过中间操作与终止操作的分离实现惰性求值,这种设计既能提升数据处理效率,又能支持链式编程风格。这些技术广泛应用于高并发系统、大数据处理等场景,是Java开发者必须掌握的底层机制。理解ConcurrentHashMap的锁优化策略和Stream API的延迟执行

weixin_33994429的博客 441

java try catch语句_java中try 与catch的使用

try{//代码区}catch(Exception e){//异常处理}代码区如果有错误,就会返回所写异常的处理。首先要清楚,如果没有try的话,出现异常会导致程序崩溃。而try则可以保证程序的正常运行下去,比如说:try{int i = 1/0;}catch(Exception e){........}一个计算的话,如果除数为0,则会报错,如果没有try的话,程序直接崩溃。用try的话,则可以让...

weixin_42509766的博客 1141

LightTools中VBA宏的编写入门

LightTools和VBA联动

bestgamer的博客 2346

深入解析SPLL单相软件锁相环:从SOGI原理到PI系数调优实践

本文深入解析SPLL单相软件锁相环技术,从SOGI原理到PI系数调优实践,详细介绍了其在数字电源设计中的应用。通过数学推导和实际调试经验,帮助工程师快速掌握锁相环的核心参数计算和优化方法,提升电网相位追踪的精确度和响应速度。

weixin_30316097的博客 380

在写java代码的时候,什么时候加入try{}catch(){}语句。什么时候去捕捉异常?

try/catch的功能是捕捉异常,所以在需要这个功能的时候就需要try/catch. 1)java中即使不会发生异常的代码也是可以用try/catch,catch句不会被认为不可达代码. 2)常见需要捕捉的异常 a.IO异常:使用输入输出流读写文件的时候, b.类型转换异常:不确定被转换变量是否满足条件的时候,如下 String str = "a"; Integer.parseInt(str); c.DB异常:数据库操作时常伴随有异常的发生 如:加载驱动,创建Connection,St.

cherry_vicent的专栏 1620

OFDM接收机同步——分组检测

上一篇讲了OFDM发射机中的长短训练序列生成原理,基于此可以得到长短训练序列的准确数值,为接收机中的符号同步中的相关运算提供基础。 进入符号同步前,首先来看OFDM接收机中的第一步——分组检测。分组检测就是检测突发传输方式的信道上是否有新的数据到达,算法的好坏直接影响着接收机的后续工作性能。 一、本文意义 基于《基于xilinx fpga 的ofdm的通信系统基带设计》这本教材中分组检测算法原理,通过matlab编程仿真验证“延时相关+保持长度”分组检测算法的有效性。同时,通过仿真证明教材上的判决公式的问题

boayel的博客 2200

Spring JdbcTemplate捕获异常

遇到的问题在使用JdbcTemplate 时,若SQL语句执行遇到错误,则会在控制台中打印出SQLExecption 错误信息。若想使用try…catch…捕获SQLExecption 异常,会发现无法捕获到该类型的异常,代码如下:try{ // 使用JdbcTemplate访问数据库 }catch (SQLException e) { // 异常处理 } 因为,此时IDE会提示:

猿长大人 5904

ROS2+PYTHON VENV虚拟环境配置方法

ROS2+PYTHON VENV配置方法本篇针对的是python。

下雨夏云的博客 555

HighTec安装(官网免费)编译 嘎嘎详细~

安装软件最好有自己的一套安装规则,工程软件除了安装主体外还会有很多其他的东西,比如license或者还会有一些驱动,如果所有都随意安装会导致你需要卸载,或者更新软件时,有的需要将原来软件卸载干净,如果没有清晰的安装路径那真是灾难啊~请确保此目录中只有个人许可证。这样基本的配置就ok了,下面打开hightec软件检验下license是否识别到了,会让你选个工作区,建议自己建一个,要不你以后就找不到了,,,如下图拉到下面,按照要求填写信息,随便写就行,注意主要的MAC地址要填本机的物理地址,然后点击2即可。

weixin_60793044的博客 1万+

JDBC操作

JDBC架构:java DataBase Connectivity 用来将java代码和数据库进行链接 为多种关系型数据库DBMS提供统一的访问方式,目的就是用 java来操作数据库。 目的就是为了访问数据库 数据库有很多:Oracle,mysql,sqlserver 操作数据库是通过驱动来操作的。这个驱动程序就是一个jar包 不同数据库,其驱动程序也不一样。 由于各种驱动程序不一样,所以通过jdbc来进行管理这些驱动程序,从而,为多种关系型数据库DBMS提供【统一】的访问方式 结构: java代码-》j

这里是菠萝味菠萝啤的博客 320

Synopsys SCL许可证服务器搭建详解:从安装到生成.dat文件

本文详细解析了Synopsys SCL许可证服务器的完整搭建流程,从系统环境准备、SCL安装到生成.dat文件。重点阐述了如何正确获取HOST ID、配置License文件以及调试常见故障,为数字芯片设计工程师提供了一套从零到一的实战避坑指南,确保EDA工具链稳定运行。

weixin_29306011的博客 609

自己动手写一个spring之jdbc_1

本文看下手写spring,jdcb部分内容。

wang0907的博客 314

【unity实战】Cinemachine虚拟相机实战,使用InputSystem+Cinemachine+CharacterController复刻各种主流游戏的相机控制

这里主要是探讨如何使用InputSystem+Cinemachine+CharacterController复刻各种主流游戏的相机控制,我们主要专注Cinemachine实战效果,所以并不会深入讨论Cinemachine和CharacterController比较细节的参数介绍。注意:前面为了测试方便,我还是先用的旧的输入系统代替InputSystem【推荐100个unity插件之10】Unity最全的最详细的Cinemachine(虚拟相机系统)介绍,详细案例讲解,快速上手。

向宇的博客,专注php/web全栈 unity游戏开发,欢迎大家评论纠错 3747

大数据Alluxio面试题及参考答案

Alluxio 在大数据生态里的定位是作为数据编排层,能在不同计算框架和存储系统之间起到桥梁的作用。它的核心功能在于加速数据访问,让大数据应用能够更高效地使用数据。Alluxio 把数据存储和数据处理分离开来,使计算框架可以在不考虑底层存储细节的情况下访问数据,这样就提高了系统的灵活性和可扩展性。Alluxio 和 HDFS 既存在关联又有区别。从关联方面来看,HDFS 是一种广泛使用的分布式文件系统,很多大数据应用都将其作为主要的数据存储系统。Alluxio 可以和 HDFS 集成,把 HDFS 当作底层

大模型大数据攻城狮的专栏 860

Java外观模式:简化复杂系统的设计艺术与实践

外观模式是结构型设计模式中的经典实现,其核心思想是通过定义统一的高层接口来封装复杂的子系统调用。这种模式在软件工程中主要解决系统复杂度管理问题,通过隐藏内部实现细节来降低模块间的耦合度。从技术原理看,外观模式运用了迪米特法则(最少知识原则),客户端只需与外观对象交互而无需了解子系统细节。在Java生态中,Spring框架的JdbcTemplate是外观模式的典型应用,它封装了JDBC的复杂操作流程,使数据库访问代码量减少70%以上。该模式特别适用于微服务架构中的聚合服务设计、第三方SDK集成等场景,能有效提

weixin_30252709的博客 420

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

JdbcTemplet----queryForObject抛出异常

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录问题场景解决方法 问题场景 在框架中使用spring获取数据源,常使用jdbcTemplet对数据源进行操作,妻中有一个api,queryForObject,  queryForObject有且只能查询一条数据,如果数据库中没有这条数据或者数据库中这条数据有相同的记录就会默认抛出一个异常,例如: 该异常提示预期的结果长度是1,但是实际结果是0. 解决方法 在dao实现层中抛出该方法的异常,如下 @Override p

红莲灭的博客 521

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

【SpringBoot框架篇】18.使用Netty加websocket实现在线聊天功能

使用netty加websocket实现在线聊天功能

皓亮君的博客 1万+

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

【SpringBoot框架篇】10.API接口限流实战

文章目录简介限流算法漏桶算法令牌桶算法基于guava的RateLimiter实现引入依赖自定义注解自定义切面类编写web接口压测 简介 对接口限流的目的是通过对并发访问/请求进行限速,或者对一个时间窗口内的请求进行限速来保护系统,一旦达到限制速率则可以拒绝服务、排队或等待、降级等处理 限流算法 常用的限流算法由:楼桶算法和令牌桶算法。 漏桶算法 漏桶(Leaky Bucket)算法思路很简单,水(请求)先进入到漏桶里,漏桶以一定的速度出水(接口有响应速率),当水流入速度过大会直接溢出(访问频率超过接口响应速

皓亮君的博客 1万+

Java异常处理核心原理与企业级实践指南

Java异常处理是JVM层面的结构化控制流机制,而非简单的错误兜底。其本质基于Throwable继承体系,通过Checked/Unchecked异常分类实现编译期契约与运行时语义分离。throw语句触发athrow字节码指令,throws声明构建调用链异常契约,而try-with-resources等语法糖背后是异常抑制(addSuppressed)与资源确定性释放的底层保障。该机制的技术价值在于将外部故障(如IO超时)与编程错误(如空指针)解耦,支撑高可用系统中的分级响应、全链路追踪与业务指标化。本文聚焦

weixin_33888907的博客 316

MiniSpring框架学习笔记-JDBC 访问框架:如何抽取 JDBC 模板并隔离数据库?

MiniSpring JDBC框架设计与数据库解耦 本文介绍了MiniSpring框架中JDBC访问层的设计思路,主要包含两部分内容: 原生JDBC分析:通过示例代码展示了JDBC访问数据库的完整流程,包括驱动加载、连接获取、SQL执行和资源释放,并解释了JDBC如何通过标准API和厂商驱动实现与不同数据库的解耦。 模板方法模式应用:通过抽象固定流程(连接管理、资源释放等)和变化点(SQL、参数绑定、结果映射),设计了StatementCallback和PreparedStatementCallback等回

dai_tou_dage的博客 335

JDBC核心技术解析与Java数据库连接实践

JDBC(Java Database Connectivity)是Java语言访问关系型数据库的标准API,通过统一的接口规范屏蔽了底层数据库差异。其核心原理基于驱动管理机制,不同类型的JDBC驱动(Type1-Type4)适应不同场景,其中Type4纯Java驱动凭借优异的性能成为现代应用首选。在工程实践中,PreparedStatement防SQL注入、try-with-resources资源管理、连接池优化等技巧尤为关键。结合MySQL Connector/J等具体驱动实现,JDBC广泛应用于从传统单

weixin_33938733的博客 342

Java异常处理中的安全陷阱与防御实践

异常处理是编程中的基础概念,用于捕获和管理程序运行时的错误。其核心原理是通过try-catch-finally等机制控制非正常流程,确保程序健壮性。从安全视角看,不当的异常处理会带来严重技术风险,例如异常信息过度暴露可能导致敏感数据泄露,成为攻击者进行信息收集的入口;资源未正确释放则可能引发资源耗尽,造成拒绝服务攻击。在实际的工程实践中,尤其在Java Web开发领域,必须将安全性融入异常处理机制。这包括对异常信息进行分层处理与脱敏,防止堆栈跟踪等调试信息泄露系统内部结构;利用try-with-resour

weixin_34297704的博客 531

外观模式解析与Spring实战应用

外观模式(Facade Pattern)是GoF设计模式中经典的结构型模式,通过为复杂子系统提供统一接口来简化调用过程。其核心原理是引入中间层来封装多个子系统的交互细节,客户端只需与外观对象交互而无需了解内部实现。这种模式在降低系统耦合度、提高安全性和简化接口方面具有显著优势,特别适用于Spring框架等复杂系统架构。在工程实践中,外观模式常与DispatcherServlet、API Gateway等组件结合,广泛应用于微服务架构、支付系统集成等场景。通过合理运用外观模式,开发者可以构建出更清晰、更易维护

weixin_30628077的博客 378

《Java 100 天进阶之路》第88篇:JDBC与连接池(2026版)

摘要:从 JDBC 基础到连接池调优,一篇打通 Java 数据库访问全链路。深度解析 Statement vs PreparedStatement 防注入原理,对比 HikariCP 与 Druid 选型与核心参数配置,结合 2026 年技术趋势,拓展虚拟线程 + 传统 JDBC、R2DBC 响应式双模架构,以及动态治理(Nacos/Apollo 联动)、可观测性(OpenTelemetry)、安全加固(环境变量 + K8s Secret)等企业级实践。附生产级配置模板与面试高频题,从“会用”到“精通”。

折哥|智能物流与Java实战,副高数据库工程师。深耕出版社物流WMS/OMS(线体/立库/VGA),也分享Java进阶与OMS电商对接。Oracle→PG实战派。相信沉淀可迁移能力,分享通用技术,不藏不虚。 5261
上一篇: 【JAVA系列】Java8、Java7、Java5新特性
下一篇: 【IDE】那些你必须安装的插件 - Intellij IDEA - 持续更新
tanpenggood
博客等级 码龄9年 129粉丝 197原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值