- 作者简介
- 内容提要
- 关于本书
- 路线图
- 代码规范与下载
- 作者在线
- 封面插图简介
- 前言
- 译者序
- 致谢
- 第1部分 Spring 的核心
- 第1章 Spring 之旅
- 第2章 装配 Bean
- 第3章 高级装配
- 第4章 面向切面的 Spring
- 第2部分 Web 中的 Spring
- 第5章 构建 Spring Web 应用程序
- 第6章 渲染 Web 视图
- 第7章 Spring MVC 的高级技术
- 第8章 使用 Spring Web Flow
- 第9章 保护 Web 应用
- 第3部分 后端中的 Spring
- 第10章 通过 Spring 和 JDBC 征服数据库
- 第11章 使用对象-关系映射持久化数据
- 第12章 使用 NoSQL 数据库
- 第13章 缓存数据
- 第14章 保护方法应用
- 第4部分 Spring 集成
- 第15章 使用远程服务
- 第16章 使用 Spring MVC 创建 REST API
- 第17章 Spring消息
- 第18章 使用 WebSocket 和 STOMP 实现消息功能
- 第19章 使用 Spring 发送 Email
- 第20章 使用 JMX 管理 Spring Bean
- 第21章 借助 Spring Boot 简化 Spring 开发
10.1.1 了解 Spring 的数据访问异常体系
这里有一个关于跳伞运动员的经典笑话,这个运动员被风吹离正常路线后降落在树上并高高地挂在那里。后来,有人路过,跳伞运动员就问他自己在什么地方。过路人回答说:“你在离地大约20尺的空中。”跳伞运动员说:“你一定是个软件分析师。”过路人回应说“你说对了。你是怎么知道的呢?”“因为你跟我说的话百分百正确,但丝毫用处都没有。”
这个故事已经听过很多遍了,每次过路人的职业或国籍都会有所不同。但是这个故事使我想起了JDBC中的SQLException。如果你曾经编写过JDBC代码(不使用Spring),你肯定会意识到如果不强制捕获SQLException的话,几乎无法使用JDBC做任何事情。SQLException表示在尝试访问数据库的时出现了问题,但是这个异常却没有告诉你哪里出错了以及如何进行处理。
可能导致抛出SQLException的常见问题包括:
应用程序无法连接数据库;
要执行的查询存在语法错误;
查询中所使用的表和/或列不存在;
试图插入或更新的数据违反了数据库约束。
SQLException的问题在于捕获到它的时候该如何处理。事实上,能够触发SQLException的问题通常是不能在catch代码块中解决的。大多数抛出SQLException的情况表明发生了致命性错误。如果应用程序不能连接到数据库,这通常意味着应用不能继续使用了。类似地,如果查询时出现了错误,那在运行时基本上也是无能为力。
如果无法从SQLException中恢复,那为什么我们还要强制捕获它呢?
即使对某些SQLException有处理方案,我们还是要捕获SQLException并查看其属性才能获知问题根源的更多信息。这是因为SQLException被视为处理数据访问所有问题的通用异常。对于所有的数据访问问题都会抛出SQLException,而不是对每种可能的问题都会有不同的异常类型。
一些持久化框架提供了相对丰富的异常体系。例如,Hibernate提供了二十个左右的异常,分别对应于特定的数据访问问题。这样就可以针对想处理的异常编写catch代码块。
即便如此,Hibernate的异常是其本身所特有的。正如前面所言,我们想将特定的持久化机制独立于数据访问层。如果抛出了Hibernate所特有的异常,那我们对Hibernate的使用将会渗透到应用程序的其他部分。如果不这样做的话,我们就得捕获持久化平台的异常,然后将其作为平台无关的异常再次抛出。
一方面,JDBC的异常体系过于简单了——实际上,它算不上一个体系。另一方面,Hibernate的异常体系是其本身所独有的。我们需要的数据访问异常要具有描述性而且又与特定的持久化框架无关。
Spring所提供的平台无关的持久化异常
Spring JDBC提供的数据访问异常体系解决了以上的两个问题。不同于JDBC,Spring提供了多个数据访问异常,分别描述了它们抛出时所对应的问题。表10.1对比了Spring的部分数据访问异常以及JDBC所提供的异常。
从表中可以看出,Spring为读取和写入数据库的几乎所有错误都提供了异常。Spring的数据访问异常要比表10.1所列的还要多。(在此没有列出所有的异常,因为我不想让JDBC显得太寒酸。)
表10.1 JDBC的异常体系与Spring的数据访问异常
JDBC的异常 | Spring的数据访问异常 |
BatchUpdateException | BadSqlGrammarException |
BatchUpdateException | NonTransientDataAccessResourceException |
尽管Spring的异常体系比JDBC简单的SQLException丰富得多,但它并没有与特定的持久化方式相关联。这意味着我们可以使用Spring抛出一致的异常,而不用关心所选择的持久化方案。这有助于我们将所选择持久化机制与数据访问层隔离开来。
看!不用写catch代码块
表10.1中没有体现出来的一点就是这些异常都继承自DataAccessException。DataAccessException的特殊之处在于它是一个非检查型异常。换句话说,没有必要捕获Spring所抛出的数据访问异常(当然,如果你想捕获的话也是完全可以的)。
DataAccessException只是Sping处理检查型异常和非检查型异常哲学的一个范例。Spring认为触发异常的很多问题是不能在catch代码块中修复的。Spring使用了非检查型异常,而不是强制开发人员编写catch代码块(里面经常是空的)。这把是否要捕获异常的权力留给了开发人员。
为了利用Spring的数据访问异常,我们必须使用Spring所支持的数据访问模板。让我们看一下Spring的模板是如何简化数据访问的。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论