Spring DAO与Spring ORM与Spring JDBC的比较

我正在浏览Spring支持的数据访问技术,我注意到它提到了多种select,我不确定它们之间的区别:

  • 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提供了用于通过简单的旧方法来减less访问数据库的样板代码的模板 – 您可以编写自己的SQL查询。

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

Spring-DAO按照Spring的网站:

Spring中的数据访问对象(Data Access Object,DAO)支持旨在使得JDBC,Hibernate或JDO等数据访问技术以一致的方式工作

我对ORM vs JDBC有点清楚,因为它们是以不同的方式访问数据库。 但是Spring-DAO只是简单的混淆!

任何人都可以澄清这三者之间究竟有什么不同? 哪种情况下应该首选?

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

这里是每个提到的技术的介绍。

Spring的DAO

Spring-DAO并不是严格意义上的Spring模块,而是应该规定你写DAO的惯例,并且写得很好。 因此,它既不提供接口,也不提供实现,也不提供访问数据的模板。 在编写DAO时,应该用@Repository注释它们,以便将与底层技术(JDBC,Hibernate,JPA等)相关的exception转换为适当的DataAccessException子类。

举一个例子,假设你现在使用Hibernate,并且你的服务层捕获了HibernateException ,以便对它作出反应。 如果更改为JPA,则不应更改DAO接口,并且服务层仍将使用捕获HibernateException块进行编译,但是您将永远不会input这些块,因为您的DAO现在正在引发JPA PersistenceException 。 通过在DAO上使用@Repository ,链接到底层技术的exception被转换为Spring DataAccessException ; 你的服务层捕获了这些exception,如果你决定改变持久化技术,spring的DataAccessExceptions仍然会被抛出,因为spring已经翻译了本地exception。

但请注意,由于以下原因,此限制使用:

  1. 您通常不应该捕获持久性exception,因为提供程序可能已经回滚事务(取决于确切的exception子types),因此不应该使用替代path继续执行。
  2. 在你的提供者中,exception的层次结构通常比Spring提供的更丰富,而且不存在从一个提供者到另一个提供者的确定映射。 依靠这是危险的。 然而,这是一个好主意,用@Repository注释你的DAO,因为这些bean将被扫描过程自动添加。 此外,Spring可能会在注释中添加其他有用的function。

Spring的JDBC

Spring-JDBC提供了JdbcTemplate类,它删除了pipe道代码,并帮助您专注于SQL查询和参数。 你只需要用一个DataSource来configuration它,然后你可以这样写代码:

 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方法。 它还提供了从SQLexception到Spring DataAccessExceptions的exception转换器。

如果你打算使用普通的jdbc,那么你需要使用这个模块。

Spring的ORM

Spring-ORM是涵盖许多持久性技术的伞形模块,即JPA,JDO,Hibernate和iBatis。 对于这些技术中的每一种,Spring都提供了集成类,以便每种技术都可以遵循Spring的configuration原则,并顺利地与Spring事务pipe理集成。

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

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

Spring的数据

Spring-Data是一个总括项目,它提供了一个通用API来定义如何以更通用的方式访问数据(DAO +注释),同时覆盖SQL和NOSQL数据源。

最初的想法是提供一种技术,以便开发人员以技术不可知的方式编写DAO接口(查找方法)和实体类,并且仅基于configuration(DAO&实体+弹簧configuration的注释, xml-或java-based),决定实现技术,无论是JPA(SQL)还是redis,hadoop等(NOSQL)。

如果你按照spring定义的命名约定来查找finder方法名,那么你甚至不需要为最简单的情况提供与finder方法相对应的查询string。 对于其他情况,您必须在查找器方法的注释中提供查询string。

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

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

下一步是什么

知道这一切,你现在要决定select什么。 这里的好消息是,你不需要为技术做出明确的最终select。 这实际上就是Spring所在的地方:作为一个开发者,当你编写代码时你专注于业务,如果你做得很好,改变底层技术就是一个实现或configuration细节。

  1. 为实体定义一个POJO类的数据模型,并通过get / set方法来表示实体属性以及与其他实体的关系。 您肯定需要根据技术注解实体类和字段,但是现在,POJO已经足够了。 只是专心于现在的业务需求。
  2. 为您的DAO定义接口。 1个DAO只包含1个实体,但你肯定不需要每个DAO,因为你应该能够通过导航关系加载额外的实体。 按照严格的命名规则定义查找器方法。
  3. 基于此,其他人可以开始在服务层上工作,为您的DAO模拟。
  4. 您将学习不同的持久性技术(sql,no-sql)以find最适合您需求的方法,并select其中之一。 基于此,你注释实体并实现DAO(或者如果你select使用spring-data,让spring为你实现)。
  5. 如果业务需求发生变化,并且您的数据访问技术不足以支持它(例如,您开始使用JDBC和一些实体,但现在需要更丰富的数据模型,并且JPA是更好的select),则必须更改实现的DAO,在你的实体上添加一些注解,并改变弹簧configuration(添加一个EntityManagerFactory定义)。 其余的业务代码不应该看到您的更改的其他影响。

注意事务pipe理

Spring为事务pipe理提供了一个API。 如果您打算使用spring来访问数据,那么您也应该使用spring来进行事务pipe理,因为它们很好地集成在一起。 对于Spring支持的每种数据访问技术,本地事务都有一个匹配的事务pipe理器,如果您需要分布式事务,则可以selectJTA。 他们都实现相同的API,所以(再次)技术select只是一个configuration问题,可以改变,而不会对业务代码产生进一步的影响。

注意:Spring文档

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

  • 单个html页面: http : //docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/
  • PDF: http : //docs.spring.io/spring/docs/current/spring-framework-reference/pdf/spring-framework-reference.pdf

Spring数据不是Spring框架的一部分。 有一个通用的模块,你应该先阅读以适应原则。 文档可以在这里find:

  • 单一的html页面: http : //docs.spring.io/spring-data/data-commons/docs/1.9.2.RELEASE/reference/html/
  • PDF: http : //docs.spring.io/spring-data/data-commons/docs/1.9.2.RELEASE/reference/pdf/spring-data-commons-reference.pdf

Spring DAO (数据访问对象):用于使用DAO模式的数据库操作。 这是使用它的单独支持类来访问JDBC和Hibernate,iBatis,JPA,JDO的概念化概念。 它通过定义@Repository注释来提供通用的exception层次结构。 注解为Spring容器定义了从SQLException到Spring的数据访问策略(不可知的DataAccessException层次结构)的SQLexception转换

即特定于平台的exception被捕获,然后重新抛出为Spring的未经检查的数据访问exception之一。

在这里输入图像说明

Spring JDBC :对于纯JDBC,只依赖于DataSource和Template类,如JdbcTemplateNamedParameterJdbcTemplate (包装JdbcTemplate )和SimpleJdbcTemplate以减less交叉问题,还有JdbcDaoSupport类具有上述优点。

Spring ORM:对于ORM工具的支持,比如Hibernate,JPA,iBatis …可以很容易的将Hibernate的SessionFactory ,JPA的EntityManagerFactory ,iBatis的SQLMapClient Spring注入DataSource以及相应的DaoSupport类。

您可以像SomeObjectDao一样创build接口,然后创build此接口的不同实现,如JdbcSomeObjectDaoHibernateSomeObjectDao 。 然后在你的SomeObjectService类中,你将在SomeObjectDao接口上进行操作,并在其中注入一个具体的实现。 所以每个SomeObjectDao实现都会隐藏细节,无论是使用JDBC还是ORM等等。

通常,JDBC和ORM的不同实现会引发不同types的exception。 Spring的DAO支持可以将这些不同的,特定于技术的exception映射到常见的Spring DAOexception。 所以你从实际的实现中分离出来了。 另外Spring的DAO支持提供了一组抽象的*DataSupport类,它们在DAO开发中更有帮助。 所以除了实现你的SomeObjectDao接口之外,你可以扩展一个Spring的*DataSupport类。