Spring DAO vs Spring ORM vs Spring JDBC

Pat 的疑惑

近期关注于 Spring 提供的数据訪问技术。对于 Spring 相关的这几个项目有何不同我不是太明白:
个人理解,Spring JDBC 提供了能够降低自己写 SQL 查询来訪问数据库的样板代码的模板。
Spring-ORM 提供了通过 ROM 技术訪问数据库的简化样板,比方 Hibernate,My(i)Batis 等等。
Spring 官网介绍的 Spring-DAO:Spring 提供的数据訪问对象(DAO)技术旨在以一个一致的方式轻松使用不同的数据訪问技术诸如 JDBC,Hibernate 或者 JDO。
关于 ORM vs JDBC 我清楚一点,由于它们都用于以不同的方式訪问数据库。但对于 Spring-DAO 我是晕头转向了。


有没有朋友把这三者之间的差别帮忙澄清一下?每一个应该首选应用于什么场景?
此外,Spring 如今还出了另外一个项目 Spring-DATA,它是 Spring 提供的全部数据訪问技术的一种父项目。还是仅仅是 Spring-DAO 的一个新名字?

Gaetan 的解释

关于以上提到的每一个技术的解释。

Spring-DAO

Spring-DAO 并不是 Spring 的一个模块。它实际上是指示你写 DAO 操作、写好 DAO 操作的一些规范。

因此。对于訪问你的数据它既没有提供接口也没有提供实现更没有提供模板。在写一个 DAO 的时候,你应该使用 @Repository 对其进行注解。这样底层技术(JDBC,Hibernate,JPA,等等)的相关异常才干一致性地翻译为相应的 DataAccessException 子类。


举个样例,假设你正在使用 Hibernate,你的服务层捕获 HibernateException 以进行相关处理。

假设你改为 JPA。你的 DAO 接口不应该也发生改变,服务层仍旧编译捕捉 HibernateException 的代码块,可是你永远不会再进入这些代码块。由于你的 DAO 如今抛出的是 JPA 的 PersistenceException。通过在你的 DAO 上使用 @Repository。底层技术相关的异常统统解释为 Spring 的 DataAccessException;你的服务层能够捕获到这些异常。并且假设你想要更换持久层技术,由于 Spring 翻译了本地异常所以仍然会抛出相同的 Spring DataAccessException
但注意由于下面原因这种使用方法是受限的:

  1. 你不应该在持久层捕捉异常。由于底层技术可能已经将事务进行了回滚(取决于详细的 exception 类型),因此你不应该再(在持久层)继续运行你的备用方案。
  2. 底层技术提供的异常级别往往比 Spring 提供的更加丰富。并且底层技术之间也没有不论什么限定来对此进行匹配。这种依赖是有风险的。可是对你的 DAO 类使用 @Repository 进行注解仍然不失为一个好的做法,由于这些 bean 会自己主动被扫描程序加入。此外,Spring 可能还会给这一注解加入其它实用特性。

Spring-JDBC

Spring-JDBC 提供了 Jdbc 模板类。它移除了连接代码以帮你专注于 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 方法。JdbcDaoSupport 还提供了一个将 SQL 异常转换为 Spring DataAccessExceptions 的异常翻译器。
假设你计划使用纯 jdbc,那么你须要使用 Spring-JDBC 模块。


Spring-ORM

Spring-ORM 是一个囊括了非常多持久层技术(JPA,JDO。Hibernate。iBatis)的总括模块。对于这些技术中的每一个,Spring 都提供了集成类。这样每一种技术都能够在遵循 Spring 的配置原则下进行使用,并平稳地和 Spring 事务管理进行集成。
对于每一种技术,配置主要在于将一个 DataSource bean 注入到某种 SessionFactory 或者 EntityManagerFactory 等 bean 中。纯 JDBC 不须要这种一个集成类(JdbcTemplate 除外),由于 JDBC 仅依赖于一个 DataSource。
假设你计划使用一种 ORM 技术。比方 JPA 或者 Hibernate,那么你就不须要 Spring-JDBC 模块了。你须要的是这个 Spring-ORM 模块。


Spring-Data

Spring-Data 是一个提供了一个通用 API 来定义怎样以一个更通用的方式訪问数据(DAO + 注解)的总括模块。包括 SQL 和 NOSQL 数据源。


初步设想是提供一种技术,开发人员能够以一种技术无关的方式为 DAO 和实体类写接口,仅仅基于配置(在 DAO 和实体类加注解 + spring 配置,或者 xml 配置)。就能够决定实现技术是 JPA(SQL) 还是 redis,hadoop 等等。


假设你遵循了 spring 为方法查找定义的命名规范,大多数简单的场景下你甚至都不须要为查找方法提供查询字符串。

其它少数情况下,你须要在查找方法的注解里提供查询字符串。
在应用上下文被载入后,spring 为 DAO 接口提供代理,它包括有数据訪问技术相关的全部样板代码,并调用配置的查询。
Spring-Data 专注于非 SQL 技术,但仍为 JPA(唯一的 SQL 技术。其它诸如 Hibernate 等没有)提供了一个模块。

该选择哪个

了解了这些,如今你能够决定选用哪一个了。好消息是你不须要为底层技术做一个明白的终于选择。这正是 Spring 主旨所在:作为一名开发人员。在你写代码的时候很多其它专注于业务逻辑。假设你把业务处理好了,改变底层技术仅仅是一些实现或者配置细节的工作。


  1. 使用 POJO 类为实体定义一个数据模型。并使用 get 和 set 方法来表示实体的属性以及和其它实体的关系。你当然须要依据底层技术的须要为实体类及其方法加注解,可是如今,作为入门 POJO 足够了。

    如今你仅仅须要专注于业务需求。

  2. 为你的 DAO 定义接口。一个 DAO 刚好包括一个实体,但你也无需为每一个实体都相应一个 DAO。由于通过关联关系你能够载入到额外的实体。遵循严格的命名约定定义查找器方法。

  3. 藉此。其它人就能够模仿你的 DAO 開始业务层的工作了。
  4. 你能够学习不同的持久层技术(sql,no-sql)来寻找最适合你须要的那个。并终于选择一个。藉此,为你的实体注解并实现 DAO(或者假设你选择使用 Spring-Data 你能够让 Spring 来实现 DAO)。

  5. 假设你的业务需求进化,而你的数据訪问技术对此的支持并不充分(比方说,一開始你使用了 JDBC。仅仅有寥寥几个实体,可是如今须要一个更加丰富的数据模型,而 JPA 是一个比較好的选择),那么你须要修改你的 DAO 实现,在你的实体上加入一些注解并修改 Spring 配置(加入一个 EntityManagerFactory 定义)。但这些也仅仅是持久层的修改,对于业务逻辑层的代码不应该受到到因此修改的影响。

注意:事务管理

Spring 为事务管理提供了一个 API。假设你的数据訪问计划使用 spring,那么你也应该用 spring 来做事务管理。由于它们整合在一起确实非常好。对于每一个 spring 支持的数据訪问技术,都有一个为本地事务匹配的事务管理器,或者假设你须要分布式事务你也能够选择 JTA。它们都实现了相同的 API。因此持久层技术的选择仅仅是一个任意调整的配置的事情。它的更改不会影响到业务代码。


原文链接:http://stackoverflow.com/questions/24990400/spring-dao-vs-spring-orm-vs-spring-jdbc

原文地址:https://www.cnblogs.com/brucemengbm/p/7284871.html