Spring DAO vs Spring ORM vs Spring JDBC
Pat 的疑惑
最近关注于 Spring 提供的数据访问技术,对于 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 提供了通过 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。
但注意由于以下原因这种用法是受限的:
- 你不应该在持久层捕捉异常,因为底层技术可能已经将事务进行了回滚(取决于具体的 exception 类型),因此你不应该再(在持久层)继续执行你的备用方案。
- 底层技术提供的异常级别往往比 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 主旨所在:作为一名开发人员,在你写代码的时候更多专注于业务逻辑,如果你把业务处理好了,改变底层技术只是一些实现或者配置细节的工作。
- 使用 POJO 类为实体定义一个数据模型,并使用 get 和 set 方法来表示实体的属性以及和其他实体的关系。你当然需要根据底层技术的需要为实体类及其方法加注解,但是现在,作为入门 POJO 足够了。现在你只需要专注于业务需求。
- 为你的 DAO 定义接口。一个 DAO 刚好包含一个实体,但你也无需为每个实体都对应一个 DAO,因为通过关联关系你可以加载到额外的实体。遵循严格的命名约定定义查找器方法。
- 藉此,其他人就可以模仿你的 DAO 开始业务层的工作了。
- 你可以学习不同的持久层技术(sql,no-sql)来寻找最适合你需要的那个,并最终选择一个。藉此,为你的实体注解并实现 DAO(或者如果你选择使用 Spring-Data 你可以让 Spring 来实现 DAO)。
- 如果你的业务需求进化,而你的数据访问技术对此的支持并不充分(比方说,一开始你使用了 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。
本文转自http://blog.csdn.net/defonds/article/details/47445915 感谢作者
Spring DAO vs Spring ORM vs Spring JDBC的更多相关文章
- Spring框架第六篇之Spring与DAO
一.Spring与JDBC模板 1.搭建环境 首先导入需要的jar包: 以上jar中多导入了DBCP和C3P0的jar包,因为这里需要演示怎么配置多种数据源,所以导入了这两个包,在实际开发中无需导入这 ...
- spring深入学习(五)-----spring dao、事务管理
访问数据库基本是所有java web项目必备的,不论是oracle.mysql,或者是nosql,肯定需要和数据库打交道.一开始学java的时候,肯定是以jdbc为基础,如下: private sta ...
- Spring框架学习(3)spring中使用jdbc
内容源自:spring中使用jdbc spring dao层中对jdbc进行了封装,使用模板模式的设计模式,通过ioc被动注入的方式将jdbcTemplate这个模板类注入到数据对象中,进行数据库操作 ...
- 学习Spring5必知必会(6)~Spring DAO
一.Spring 对持久层技术的支持 Spring DAO 1.模板类: 2.基类: 二.spring JDBC [JDBCTemplate 模板类] 1.案例:使用jdbc 完成crud操作 (1) ...
- Spring DAO模块
Spring的DAO模块提供了对JDBC.Hibernate.Mybatis等DAO层支持,本节介绍DAO模块对JDBC的支持.DAO模块依赖ommons-dbcp.jar.commons-pool. ...
- Spring入门学习笔记(4)——JDBC的使用
目录 Spring JDBC框架概览 JdbcTemplate类 配置数据源 数据访问对象(Data Access Object,DAO) 执行SQL命令 Spring JDBC框架概览 使用传统的J ...
- Spring DAO
Spring DAO 连接池 使用JDBC访问数据库是,频繁的打开连接和关闭连接,造成性能影响,所以有了连接池.数据库连接池负责分配.管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接, ...
- spring DAO 有什么用?
Spring DAO 使得 JDBC,Hibernate 或 JDO 这样的数据访问技术更容易以一 种统一的方式工作.这使得用户容易在持久性技术之间切换.它还允许您在编写 代码时,无需考虑捕获每种技术 ...
- 关于Hibernate在反向工程时无法选择Spring DAO Type的解决方法【更新版】
目录(?)[+] IT程序员开发必备-各类资源下载清单,史上最全IT资源,个人收藏总结! 之前有一篇文章中(Hibernate反向工程步骤及DAO Type无法选择Spring DAO解决方法)提到, ...
随机推荐
- POJ 2186 Popular Cows(强联通分量)
题目链接:http://poj.org/problem?id=2186 题目大意: 每一头牛的愿望就是变成一头最受欢迎的牛.现在有N头牛,给你M对整数(A,B),表示牛A认为牛B受欢迎. 这 种 ...
- 以太坊go-ethereum常见问题汇总
(1)什么是 Ethereum? 以太坊是一个分散的智能合同平台,由Ether的加密货币提供支持. (2) 听说过以太坊,但什么是Geth,Mist,Ethminer,Mix? Geth: 以太坊节点 ...
- Sqlserver双机热备文档(无域)
1. 配制环境 OS:Win7 DB:SQL Server R2 2. 基本配制 1. 开启sqlServer服务如下图-1 图-1 2. 开启sqlServer的tcp/i ...
- 【BZOJ】2395: [Balkan 2011]Timeismoney
题解 最小乘积生成树! 我们把,x的总和和y的总和作为x坐标和y左边,画在坐标系上 我们选择两个初始点,一个是最靠近y轴的A,也就是x总和最小,一个是最靠近x轴的B,也就是y总和最小 连接两条直线,在 ...
- php匹配邮箱正则
php匹配邮箱正则 '/[a-z0-9&\-_.]+@[\w\-_]+([\w\-.]+)?\.[\w\-]+/is'
- php7的新特性
新增操作符1.??$username = $_GET['user'] ?? '';$username = isset($_GET['user']) ? $_GET['user'] : 'nobody' ...
- R语言编程艺术(2)R中的数据结构
本文对应<R语言编程艺术>第2章:向量:第3章:矩阵和数组:第4章:列表:第5章:数据框:第6章:因子和表 ======================================== ...
- qt study2
- ThreadLocal和ThreadLocalMap源码分析
目录 ThreadLocal和ThreadLocalMap源码分析 背景分析 定义 例子 源码分析 ThreadLocalMap源码分析 ThreadLocal源码分析 执行流程总结 源码分析总结 T ...
- JSP九大内置对象简介
1.out对象,是JspWriter类的实例,是向客户端输出内容常用的对象 方法: void println() 向客户端打印字符串 void clear() 清除缓冲区的内容,如果在flush之后调 ...