Spring的数据访问哲学

news2024/10/7 9:24:20

目录

设计思路

了解Spring的数据访问异常体系

数据访问模板化


  • 设计思路

  • Spring的目标之一就是允许我们在开发应用程序时,能够遵循面向对象(OO)原则中的“针对接口编程”
  • Spring对数据访问的支持也不例外
  • 像很多应用程序一样,Spittr应用需要从某种类型的数据库中读取和写入数据
  • 为了避免持久化的逻辑分散到应用的各个组件中,最好将数据访问的功能放到一个或多个专注于此项任务的组件中
  • 这样的组件通常称为数据访问对象(data access object,DAO)或Repository
  • 为了避免应用与特定的数据访问策略耦合在一起,编写良好的Repository应该以接口的方式暴露功能
  • 下图展现了设计数据访问层的合理方式

  • 服务对象本身并不会处理数据访问,而是将数据访问委托给Repository
  • Repository接口确保其与服务对象的松耦合
  • 如上图所示,服务对象通过接口来访问Repository
  • 这样做会有几个好处:
  • 第一,它使得服务对象易于测试,因为它们不再与特定的数据访问实现绑定在一起
  • 实际上,你可以为这些数据访问接口创建mock实现,这样无需连接数据库就能测试服务对象,而且会显著提升单元测试的效率并排除因数据不一致所造成的测试失败
  • 此外,数据访问层是以持久化技术无关的方式来进行访问的
  • 持久化方式的选择独立于Repository,同时只有数据访问相关的方法才通过接口进行暴露
  • 这可以实现灵活的设计,并且切换持久化框架对应用程序其他部分所带来的影响最小
  • 如果将数据访问层的实现细节渗透到应用程序的其他部分中,那么整个应用程序将与数据访问层耦合在一起,从而导致僵化的设计
  • 接口是实现松耦合代码的关键,并且应将其用于应用程序的各个层,而不仅仅是持久化层
  • 还要说明一点,尽管Spring鼓励使用接口,但这并不是强制的——你可以使用Spring将bean(DAO或其他类型)直接装配到另一个bean的某个属性中,而不需要一定通过接口注入
  • 为了将数据访问层与应用程序的其他部分隔离开来,Spring采用的方式之一就是提供统一的异常体系
  • 这个异常体系用在了它支持的所有持久化方案中
  • 了解Spring的数据访问异常体系

  • SQLException表示在尝试访问数据库的时出现了问题,但是这个异常却没有告诉你哪里出错了以及如何进行处理
  • 可能导致抛出SQLException的常见问题包括:
    • 应用程序无法连接数据库
    • 要执行的查询存在语法错误
    • 查询中所使用的表和/或列不存在
    • 试图插入或更新的数据违反了数据库约束
  • SQLException的问题在于捕获到它的时候该如何处理
  • 事实上,能够触发SQLException的问题通常是不能在catch代码块中解决的
  • 大多数抛出SQLException的情况表明发生了致命性错误
  • 如果应用程序不能连接到数据库,这通常意味着应用不能继续使用了
  • 类似地,如果查询时出现了错误,那在运行时基本上也是无能为力
  • 如果无法从SQLException中恢复,那为什么我们还要强制捕获它呢?
  • 即使对某些SQLException有处理方案,我们还是要捕获SQLException并查看其属性才能获知问题根源的更多信息
  • 这是因为SQLException被视为处理数据访问所有问题的通用异常
  • 对于所有的数据访问问题都会抛出SQLException,而不是对每种可能的问题都会有不同的异常类型
  • 一些持久化框架提供了相对丰富的异常体系
  • 例如,Hibernate提供了二十个左右的异常,分别对应于特定的数据访问问题
  • 这样就可以针对想处理的异常编写catch代码块
  • 即便如此,Hibernate的异常是其本身所特有的
  • 正如前面所言,我们想将特定的持久化机制独立于数据访问层
  • 如果抛出了Hibernate所特有的异常,那我们对Hibernate的使用将会渗透到应用程序的其他部分
  • 如果不这样做的话,我们就得捕获持久化平台的异常,然后将其作为平台无关的异常再次抛出
  • 一方面,JDBC的异常体系过于简单了——实际上,它算不上一个体系
  • 另一方面,Hibernate的异常体系是其本身所独有的
  • 我们需要的数据访问异常要具有描述性而且又与特定的持久化框架无关
  • Spring所提供的平台无关的持久化异常
  • Spring JDBC提供的数据访问异常体系解决了以上的两个问题
  • 不同于JDBC,Spring提供了多个数据访问异常,分别描述了它们抛出时所对应的问题
  • Spring的数据访问异常要比JDBC所列的还要多
  • 尽管Spring的异常体系比JDBC简单的SQLException丰富得多,但它并没有与特定的持久化方式相关联
  • 这意味着我们可以使用Spring抛出一致的异常,而不用关心所选择的持久化方案
  • 这有助于我们将所选择持久化机制与数据访问层隔离开来
  • 这些异常都继承自DataAccessException
  • DataAccessException的特殊之处在于它是一个非检查型异常
  • 换句话说,没有必要捕获Spring所抛出的数据访问异常(当然,如果你想捕获的话也是完全可以的)
  • DataAccessException只是Sping处理检查型异常和非检查型异常哲学的一个范例
  • Spring认为触发异常的很多问题是不能在catch代码块中修复的
  • Spring使用了非检查型异常,而不是强制开发人员编写catch代码块(里面经常是空的)
  • 这把是否要捕获异常的权力留给了开发人员
  • 为了利用Spring的数据访问异常,我们必须使用Spring所支持的数据访问模板
  • 数据访问模板化

  • 模板方法模式
  • 在某些特定的步骤上,处理过程会将其工作委派给子类来完成一些特定实现的细节
  • 这是过程中变化的部分
  • 模板方法将过程中与特定实现相关的部分委托给接口,而这个接口的不同实现定义了过程中的具体行为
  • 这也是Spring在数据访问中所使用的模式
  • 不管我们使用什么样的技术,都需要一些特定的数据访问步骤
  • 例如,我们都需要获取一个到数据存储的连接并在处理完成后释放资源
  • 这都是在数据访问处理过程中的固定步骤,但是每种数据访问方法又会有些不同,我们会查询不同的对象或以不同的方式更新数据,这都是数据访问过程中变化的部分
  • Spring将数据访问过程中固定的和可变的部分明确划分为两个不同的类:模板(template)和回调(callback)
  • 模板管理过程中固定的部分
  • 而回调处理自定义的数据访问代码
  • 下图展现了这两个类的职责

  • Spring的数据访问模板类负责通用的数据访问功能
  • 对于应用程序特定的任务,则会调用自定义的回调对象
  • 如图所示,Spring的模板类处理数据访问的固定部分——事务控制、管理资源以及处理异常
  • 同时,应用程序相关的数据访问——语句、绑定参数以及整理结果集——在回调的实现中处理
  • 事实证明,这是一个优雅的架构,因为你只需关心自己的数据访问逻辑即可
  • 针对不同的持久化平台,Spring提供了多个可选的模板
  • 如果直接使用JDBC,那你可以选择JdbcTemplate
  • 如果你希望使用对象关系映射框架,那Mybatis或JpaTemplate可能会更适合你

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

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

相关文章

chatgpt赋能python:Python中使用Numpy获取数组元素的方法

Python中使用Numpy获取数组元素的方法 作为一种高级数据处理和科学计算库,numpy在python中被广泛使用。对于从事科研数据处理工作的工程师和研究人员来说,numpy已经成为必须要掌握的工具之一。 本文将讨论如何在Python中使用Numpy获取数组元素。我们将…

理解分布式锁的实现过程

背景:分布式锁在后端开发者会用到,它有哪些特点呢? 在分布式系统中,一个应用部署在多台机器当中,在某些场景下, 为了保证数据一致性,要求在同一时刻,同一任务只在一个节点上运行&am…

【计算机网络复习】第七章 物理层

物理层的位置和基本功能 u 网络体系结构的最底层,实现真正的数据传输 u 将二进制数据编码或调制成信号,发送到传输介质(传输媒体); u 从传输介质接收信号,转换成二进制数据 物理层的主要功能 u 规定了与传输介质的接口的特…

chatgpt赋能python:判断Python中的字符类型

判断Python中的字符类型 在Python编程中,有时我们需要判断一个字符的类型。Python提供了几种方法来判断字符类型。本文将介绍这些方法并提供示例代码。 1. 使用内置函数ord() ord()函数可以返回一个字符的Unicode编码。使用这个方法我们可以判断一个字符是否是数…

【LGR-142-Div.4】洛谷入门赛 #13 考后分析与题解

洛谷入门赛 #Round 13 比赛分析与总结T1 魔方魔方题目背景题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 提示数据规模与约定 分析AC代码注意 T2 教学楼教学楼题目背景题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 样例 #2样例输入 #2样例输出 #2 提示样例…

尚硅谷甄选--更新中

文章目录 搭建后台管理系统模板项目初始化2.1.1环境准备2.1.2初始化项目2.2项目配置一、eslint配置1.1vue3环境代码校验插件1.2修改.eslintrc.cjs配置文件1.3.eslintignore忽略文件1.4运行脚本 二、配置**prettier**2.1安装依赖包2.2.prettierrc.json添加规则2.3.prettierignor…

Shell编程条件语句(if、case)

目录 一、Shell条件语句 1.条件表达式测试 2.文件测试 3.整数值比较 4.字符串比较 5.逻辑测试 二、if 条件语句(串行执行) (1)单分支结构 (2)双分支结构 (3)多分支结构 三…

C语言之数据在内存中的存储习题讲解

上个博客我们讲到了整型家族,对于整型家族来说有有符号和无符号之分 short signed short unsigned short int signed int unsigned int char在VS环境上其实是signed char unsigned char 对于有符号的char来说,把二进制位序列中的最高位当成符号位 对于无符号的char来…

【计算机组成原理与体系结构】控制器

目录 一、CPU的功能与基本结构 二、指令周期的数据流 三、数据通路 四、硬布线控制器 五、微程序控制器 六、微指令 一、CPU的功能与基本结构 运算器基本结构 控制器基本结构 CPU的基本结构 二、指令周期的数据流 取址周期 间址周期 中断周期 指令周期流程 三、数据通路 …

微信云开发

微信云数据库 快速开始:小程序/小游戏 | 微信开放文档 (qq.com) 首先微信云开发需要一个真实小程序的 AppID,而不能使用测试号。 然后点击这个开通云开发 云的环境大概是这样的 首先我们要初始化 否则会像这样,报错 写在app.js的 onLaunc…

LearnOpenGL-高级OpenGL-11.抗锯齿

本人初学者,文中定有代码、术语等错误,欢迎指正 文章目录 抗锯齿多重采样锯齿产生原因多重采样方式 OpenGL的MSAA例子:提示GLFW离屏MSAA例子1:多重采样帧缓冲传送到屏幕上例子2:采样多重采样帧缓冲的纹理缓冲与后期效果…

【华为OD统一考试B卷 | 100分】太阳能板最大面积(C++ Java JavaScript Python)

题目描述 给航天器一侧加装长方形或正方形的太阳能板(图中的红色斜线区域),需要先安装两个支柱(图中的黑色竖条),再在支柱的中间部分固定太阳能板。 但航天器不同位置的支柱长度不同,太阳能板的安装面积受限于最短一侧的那根支柱长度。如图: 现提供一组整形数组的支柱高…

chatgpt赋能python:如何升级你的Python到最新版本

如何升级你的Python到最新版本 Python作为一种强大的编程语言,拥有广泛的用途,从网站开发到数据科学,都可以使用它来实现。然而,Python不断更新,每个新版本都带来了新的功能和改进,因此升级Python到最新版…

二叉树概念(二)

平衡二叉树 AVL树(Adelson-Velsky 和 Landis) 左子树和右子树的高度之差的绝对值小于等于1 C++ 中,可以直接使用 std::set 类作为平衡二叉树;Java 中,可以直接使用 TreeSet。在 Python 中,没有内置的库可以用来模拟平衡二叉树。 力扣 红黑树 (Red-Black Tree) 是一种二…

Shell脚本数组简介及运用

目录 一、数组简介 二、数组支持的数据类型 三、定义数组 四、获取数组某个索引处的值 五、遍历数组元素 六、获取数组长度 七、截取数组元素 八、数组的元素替换 1.临时替换 2.永久替换 九、删除元素或数组 十、数组追加元素 1.满元素数组追加 2.非满元素数组追…

【模块三:职业成长】39|能力维度四:如何从做技术到为企业创造生存优势?

你好,我是郭东白。今天这节课是架构师能力维度的第四部分,我们来继续探索架构师成长过程的能力跃迁。不过今天我们会连续讲两个跃迁:从跨域架构师到总架构师(首席架构师)的跃迁;从总架构师再到 CTO 的跃迁。…

浅尝 xen 虚拟化

前言 之前分享过使用 oVirt 部署私有虚拟化环境, oVirt 是基于 KVM 虚拟化开发了一系列的管理工具, 以 Web Console /CLI 的方式交付使用. 今天记录和分享的是在 VMware Workstation 中使用 Alpine 作为基础操作系统部署 xen 虚拟化环境的简单测试. xen 基本概念 xen 可以理…

chatgpt赋能python:Python的发音

Python的发音 Python是一种广泛使用的编程语言,用于web开发、数据分析、科学计算等众多领域。然而,Python这个词汇的发音在不同的地方却存在差异。在本文中,我们将介绍Python的发音,解决大家的困惑。 发音方式 Python在英语中常…

【数学建模系列】TOPSIS法的算法步骤及实战应用——MATLAB实现

文章目录 TOPSIS简介方法和原理数学定义数学语言描述现实案例 正负理想解定义实例 量纲 TOPSIS法的算法步骤1.用向量规范化的方法求得规范决策矩阵2.构成加权规范阵C(c~ij~)~m*n~3.确定正负理想解的距离4.计算各方案到正理想解与负理想解的距离5.计算各方案的综合评价指数6.排列…

STM32源码阅读记录之HAL库(SystemTick)

问题 HAL_Delay是怎么做到可以延迟控制的? 分析记录 步骤01:看函数本身 void HAL_Delay(uint32_t Delay); /*** brief 此函数根据变量递增提供最小延迟(以毫秒为单位)。* note 在默认的实现中,SysTick计时器是时基的来源。它用…