当前位置: 首页 > 知识库问答 >
问题:

Spring DAO与Spring ORM与Spring JDBC

柴瀚昂
2023-03-14

我正在研究Spring支持的数据访问技术,我注意到它提到了多个选项,但我不确定它们之间的区别:

  • Spring-DAO(http://docs.spring.io/spring/docs/2.0.8/reference/dao.html)
  • Spring-orm(http://docs.spring.io/spring/docs/3.0.x/spring-framework-reference/html/orm.html)
  • Spring-JDBC(http://docs.spring.io/spring/docs/3.0.x/spring-framework-reference/html/jdbc.html)

据我所知,Spring JDBC提供了模板,用于减少通过简单的旧方法访问数据库的样板代码--您编写自己的SQL查询。

Spring-ORM提供了通过ORM技术访问数据库的简化模板,如Hibernate、My(i)Batis等。

Spring-DAO根据Spring的网站

Spring中的数据访问对象(Data Access Object,DAO)支持旨在以一致的方式轻松地使用数据访问技术,如JDBC、Hibernate或JDO

此外,还有另一个项目spring-data也可用(http://projects.Spring.io/spring-data/)。现在,它是Spring支持的所有数据访问技术的父项目,还是只是Spring-dao的一个新名称?

共有1个答案

华鹭洋
2023-03-14

这里是对每一种提到的技术的介绍。

春刀

Spring-DAO不是一个严格意义上的spring模块,而是一种约定,它应该指示您编写DAO并将其编写好。因此,它既不提供接口,也不提供实现或模板来访问数据。在编写DAO时,您应该使用@repository对它们进行注释,以便将链接到底层技术(JDBC、Hibernate、JPA等)的异常一致地转换为适当的DataAccessException子类。

例如,假设您现在正在使用Hibernate,并且您的服务层捕获HibernateException以便对其作出反应。如果您更改为JPA,您的DAOs接口不应改变,服务层仍将使用捕获HibernateException的块进行编译,但您永远不会输入这些块,因为您的DAOs现在抛出的是JPAPersistenceException。通过在DAO上使用@repository,链接到底层技术的异常被转换为SpringDataAccessException;您的服务层捕获这些异常,如果您决定更改持久性技术,则仍然会抛出相同的SpringDataAccessExceptions,因为Spring已转换本机异常。

但请注意,由于以下原因,这种方法的使用有限:

  1. 通常不应捕获持久性异常,因为提供程序可能回滚了事务(取决于确切的异常子类型),因此不应使用替代路径继续执行
  2. 提供程序中的异常层次结构通常比Spring提供的要丰富,并且没有从一个提供程序到另一个提供程序的确定映射。依赖这个是危险的。不过,使用@repository注释DAO是一个好主意,因为bean将由扫描过程自动添加。此外,Spring还可以为注释添加其他有用的特性。

Spring-JDBC

Spring-JDBC提供了JdbcTemplate类,它删除了管道代码,并帮助您集中精力处理SQL查询和参数。您只需使用datasource配置它,然后就可以编写如下代码:

int nbRows = jdbcTemplate.queryForObject("select count(1) from person", Integer.class);

Person p = jdbcTemplate.queryForObject("select first, last from person where id=?", 
             rs -> new Person(rs.getString(1), rs.getString(2)), 
             134561351656L);

Spring-JDBC还提供了一个JdbcDaoSupport,您可以扩展它来开发您的DAO。它基本上定义了两个属性:一个DataSource和一个JdbcTemplate,这两个属性都可以用于实现DAO方法。它还提供了一个从SQL exceptions到spring DataAccessExceptions的异常转换程序。

对于每种技术,配置基本上都是将DataSourcebean注入到某种SessionFactoryEntityManagerFactory等bean中。对于纯JDBC来说,不需要这样的集成类(除了JdbcTemplate),因为JDBC只依赖于一个数据源。

如果您计划使用像JPA或Hibernate这样的ORM,您将不需要spring-jdbc,而只需要这个模块。

Spring-Data

最初的想法是提供一种技术,使开发人员以技术无关的方式编写DAO(查找方法)和实体类的接口,并且仅基于配置(DAO上的注释&实体+spring配置,无论是基于XML还是基于Java)来决定实现技术,无论是JPA(SQL)还是redis,hadoop等(NOSQL)。

如果您遵循spring为finder方法名称定义的命名约定,那么对于最简单的情况,甚至不需要提供与finder方法相对应的查询字符串。对于其他情况,您必须在finder方法的注释中提供查询字符串。

当加载应用程序上下文时,spring为DAO接口提供代理,它包含与数据访问技术相关的所有样板代码,并调用配置的查询。

Spring-Data专注于非SQL技术,但仍然为JPA(唯一的SQL技术)提供了一个模块。

接下来是什么

知道了所有这些,你现在必须决定选择什么。这里的好消息是,您不需要为技术做出一个确定的最终选择。这实际上就是Spring的力量所在:作为开发人员,在编写代码时专注于业务,如果做得很好,更改底层技术就是一个实现或配置细节。

    null

Spring提供了一个用于事务管理的API。如果您计划使用spring进行数据访问,那么也应该使用spring进行事务管理,因为它们很好地集成在一起。对于spring支持的每种数据访问技术,都有一个与之匹配的本地事务的事务管理器,如果需要分布式事务,也可以选择JTA。它们都实现了相同的API,因此(再一次)技术选择只是一个可以更改的配置,而不会对业务代码产生进一步的影响。

注意:Spring文档

您提到的Spring文档的链接相当古老。以下是最新版本(4.1.6,涵盖所有主题)的文档:

    null
    null
 类似资料:
  • 在C语言中,假设每个算法被赋予完全相同的一组进程,那么先到先得、最短作业优先和循环之间的周转时间是否相等?还是调度算法不同?

  • 问题内容: 为了为 HTML5 Doctype 定义字符集,我应该使用哪种表示法? 短: 长: 问题答案: 在HTML5中,它们是等效的。使用较短的一个,更容易记住和键入。浏览器支持很好,因为它是为向后兼容而设计的。

  • 连接的多个输入都相当于Yes的时候才会输出Yes。 用法 Your browser does not support the video tag. 案例:小闹钟 功能:今天15:10:00,响起猫叫声小闹钟 工作原理 当所有的输入都是Yes的时候,与节点才输出Yes。

  • 问题内容: 似乎有三种 相同的 方法可以独立于平台获取依赖于平台的“文件分隔符”: 我们如何决定何时使用哪个? 它们之间甚至有什么区别吗? 问题答案: 可以通过调用命令行参数或使用命令行参数覆盖 获取默认文件系统的分隔符。 获取默认文件系统。 获取文件系统的分隔符。请注意,作为一种实例方法,在需要代码在一个JVM中对多个文件系统进行操作的情况下,可以使用该方法将不同的文件系统传递给代码(而不是默认

  • 问题内容: 我今天刚刚与一些同事讨论了python的db-api fetchone vs fetchmany vs fetchall。 我确定每个应用程序的用例都取决于我正在使用的db-api的实现,但是总的来说,fetchone,fetchmany,fetchall的用例是什么? 换句话说,以下等效项是什么?还是其中之一比其他人更受青睐?如果是这样,在哪些情况下? 问题答案: 我认为这确实取决于

  • 问题内容: 即时创建元素并能够移动元素的最佳方法是什么?例如,假设我要创建一个矩形,圆形和多边形,然后选择这些对象并四处移动。 我了解HTML5提供了三个使之成为可能的元素:svg,canvas和div。对于我想做什么,这些元素中的哪一个将提供最佳性能? 为了比较这些方法,我正在考虑创建三个视觉上相同的网页,每个网页中都有页眉,页脚,小部件和文本内容。第一页中的小部件将完全使用元素创建,第二页中的

  • 问题内容: 之间有什么区别,和? 问题答案: 将等待,直到所有资产完成下载为止,例如图像和脚本。 DOM准备就绪,直到您可以通过API访问DOM为止。 作为一个方面说明,在当今这个时代,你应该使用或较旧的IE。