Java中DAO的实现
图 1. 应用程序和数据源 
- 一个 DAO 工厂类
- 一个 DAO 接口
- 一个实现了 DAO 接口的具体类
- 数据传输对象(有时称为值对象)
事务界定
| 声明式事务界定 | 编程式事务界定 |
| 程序员用 EJB 部署描述符声明事务属性。 | 程序员负责编写事务逻辑。 |
| 运行时环境(EJB 容器)用这些属性自动管理事务。 | 应用程序通过一个 API 控制事务。 |
- 事务要如何开始?
- 事务应如何结束?
- 哪一个对象将负责开始一个事务?
- 哪一个对象将负责结束一个事务?
- DAO 是否要负责事务的开始和结束?
- 应用程序是否需要通过多个 DAO 访问数据?
- 事务涉及到一个 DAO 还是多个 DAO?
- 一个 DAO 是否调用另一个 DAO 的方法?
清单 1. DAO 方法
tx.begin(); // start the transaction
dao.createWarehouseProfile(profile);
dao.updateWarehouseStatus(id1, status1);
dao.updateWarehouseStatus(id2, status2);
tx.commit(); // end the transactionConnection 对象控制的。JDBC Connection 接口( java.sql.Connection )提供了两种事务模式:自动提交和手工提交。 java.sql.Connection 提供了以下控制事务的方法:public void setAutoCommit(boolean)public boolean getAutoCommit()public void commit()public void rollback()
清单 3. 用 JDBC API 进行事务界定
import java.sql.*; |
图 2. 一个事务管理器和资源管理器 
- JDBC 连接
- JDO
PersistenceManager对象 - JMS 队列
- JMS 主题
- 企业 JavaBeans
- 符合 J2EE 连接体系结构(J2EE Connector Architecture)规范的资源适配器
javax.transaction.UserTransaction 接口中的方法。清单 4 显示了对UserTransaction 对象的典型 JNDI 查询:清单 4. 一个对 UserTransaction 对象的 JDNI 查询
import javax.transaction.*; |
UserTransaction 对象后,就可以开始事务了,如清单 5 所示:清单 5. 用 JTA 开始一个事务
utx.begin(); |
commit() 时,事务管理器用一个两阶段的提交协议结束事务。javax.transaction.UserTransaction 接口提供了以下事务控制方法:public void begin()public void commit()public void rollback()public int getStatus()public void setRollbackOnly()public void setTransactionTimeout(int)
begin() 开始事务。应用程序调用 commit() 或者 rollback() 结束事务。javax.sql.XADataSource 、 javax.sql.XAConnection 和 javax.sql.XAResource 接口的 JDBC 驱动程序。一个实现了这些接口的驱动程序将可以参与 JTA 事务。一个 XADataSource 对象就是一个 XAConnection 对象的工厂。XAConnection s 是参与 JTA 事务的 JDBC 连接。XADataSource 。从应用服务器和 JDBC 驱动程序的文档中可以了解到相关的指导。javax.sql.DataSource.getConnection() 以获得到数据库的连接。java.sql.Connection.commit() 或者java.sql.Connection.rollback() 。相反,应用程序应该使用 UserTransaction.begin()、UserTransaction.commit() 和 serTransaction.rollback() 。- 事务界定代码嵌入在 DAO 类中。
- DAO 类使用 JDBC API 进行事务界定。
- 调用者不能界定事务。
- 事务范围局限于单个 JDBC 连接。
- 事务用 JTA 界定。
- 事务界定代码从 DAO 中分离出来。
- 调用者负责界定事务。
- DAO 加入一个全局事务。
System.out.println 和 System.err.println 。 Println 语句速度快且使用方便,但是它们没有提供全功能的日志记录系统所具有的功能。表 2 列出了 Java 平台的日志库:| 日志库 | 开放源代码? | URL |
| java.util.logging | 不是 | [url]http://java.sun.com/j2se/[/url] |
| Jakarta Log4j | 是 | [url]http://jakarta.apache.org/log4j/[/url] |
| Jakarta Commons Logging | 是 | [url]http://jakarta.apache.org/commons/logging.html[/url] |
java.util.logging 或者 Jakarta Log4j 一同使用。Commons Logging 是一个日志抽象层,它隔离了应用程序与底层日志实现。使用 Commons Logging,您可以通过改变配置文件更换底层日志实现。Commons Logging 在 Jakarta Struts 1.1 和 Jakarta HttpClient 2.0 中使用。清单 7. DAO 类中的 Jakarta Commons Logging
import org.apache.commons.logging.*; |
- DAO 的公共接口中的方法是否抛出检查过的异常?
- 如果是的话,抛出何种检查过的异常?
- 在 DAO 实现类中如何处理异常?
- DAO 方法应该抛出有意义的异常。
- DAO 方法不应该抛出
java.lang.Exception。java.lang.Exception太一般化了。它不传递关于底层问题的任何信息。 - DAO 方法不应该抛出
java.sql.SQLException。SQLException 是一个低级别的 JDBC 异常。一个 DAO 应该力争封装 JDBC 而不是将 JDBC 公开给应用程序的其余部分。 - 只有在可以合理地预期调用者可以处理异常时,DAO 接口中的方法才应该抛出检查过的异常。如果调用者不能以有意义的方式处理这个异常,那么考虑抛出一个未检查的(运行时)异常。
- 如果数据访问代码捕获了一个异常,不要忽略它。忽略捕获的异常的 DAO 是很难进行故障诊断的。
- 使用链接的异常将低级别的异常转化为高级别的异常。
- 考虑定义标准 DAO 异常类。Spring Framework 提供了很好的一套预定义的 DAO 异常类。
MovieDAO 是一个展示本文中讨论的所有技术的 DAO:事务界定、日志和异常处理。 MovieDAO 源代码。代码分为三个包:daoexamples.exceptiondaoexamples.moviedaoexamples.moviedemo
daoexamples.movie.MovieDAOFactorydaoexamples.movie.MovieDAOdaoexamples.movie.MovieDAOImpldaoexamples.movie.MovieDAOImplJTAdaoexamples.movie.Moviedaoexamples.movie.MovieImpldaoexamples.movie.MovieNotFoundExceptiondaoexamples.movie.MovieUtil
MovieDAO 接口定义了 DAO 的数据操作。这个接口有五个方法,如下所示:public Movie findMovieById(String id)public java.util.Collection findMoviesByYear(String year)public void deleteMovie(String id)public Movie createMovie(String rating, String year, String, title)public void updateMovie(String id, String rating, String year, String title)
daoexamples.movie 包包含 MovieDAO 接口的两个实现。每一个实现使用一种不同的方式进行事务界定,如表 3 所示:| MovieDAOImpl | MovieDAOImplJTA | |
| 实现 MovieDAO 接口? | 是 | 是 |
| 通过 JNDI 获得 DataSource? | 是 | 是 |
| 从 DataSource 获得 java.sql.Connection 对象? | 是 | 是 |
| DAO 在内部界定事务? | 是 | 否 |
| 使用 JDBC 事务? | 是 | 否 |
| 使用一个 XA DataSource? | 否 | 是 |
| 参与 JTA 事务? | 否 | 是 |
daoexamples.moviedemo.DemoServlet 的 servlet 类。 DemoServlet 使用这两个 Movie DAO 查询和更新表中的电影数据。MovieDAO 和 Java 消息服务(Java Message Service)结合到一个事务中,如清单 8 所示。清单 8. 将 MovieDAO 和 JMS 代码结合到一个事务中
UserTransaction utx = MovieUtil.getUserTransaction(); |
Java中DAO的实现的更多相关文章
- Java中DAO/DTO/PO/VO/BO/QO/POJO
ORM:是Object Relational Mapping(对象关系映射)的缩写. 通俗点讲,就是将对象与关系数据库绑定,用对象来表示关系数据.在O/R/M的世界里,有两个基本的也是重要的东东需要了 ...
- java中dao层和service层的区别是什么?
首先解释面上意思,service是业务层,dao是数据访问层.呵呵,这个问题我曾经也有过,记得以前刚学编程的时候,都是在service里直接调用dao,service里面就new一个dao类对象,调用 ...
- java中dao层的通用层,通过反射机制,操作数据库的增删改,适用的范围是不包含属性类
这里首先必须注意的是:类的类名.字段必须与数据库中的表名和字段名保持一致,否则无法通过反射机制作出通用层 /** * 学生信息类,数据库中的StuInfo表 * */public class StuI ...
- java中dao层和service层的区别是什么
dao层中已经有操作数据库的方法了,为什么还要service层去封装?有什么好处? tanghui12321 | 浏览 131990 次 我有更好的答案 推荐于2017-10-06 18:44:5 ...
- java中Dao模式
什么是DAO 1.Data Access Object(数据存取对象) 2.位于业务逻辑和持久化数据之间 3.实现对持久化数据的访问 DAO模式的作用 1隔离业务逻辑代码和数据访问代码 2.隔离不 ...
- java中的dao模式
java中Dao模式 什么是DAO 1.Data Access Object(数据存取对象) 2.位于业务逻辑和持久化数据之间 3.实现对持久化数据的访问 DAO模式的作用 1隔离业务逻辑代码 ...
- java中Action层、Service层和Dao层的功能区分
Action/Service/DAO简介: Action是管理业务(Service)调度和管理跳转的. Service是管理具体的功能的. Action只负责管理,而Service负责实施. DAO只 ...
- SSH 框架学习之初识Java中的Action、Dao、Service、Model-收藏
SSH 框架学习之初识Java中的Action.Dao.Service.Model-----------------------------学到就要查,自己动手动脑!!! 基础知识目前不够,有感性 ...
- [转]JAVA中Action层, Service层 ,modle层 和 Dao层的功能区分
首先这是现在最基本的分层方式,结合了SSH架构.modle层就是对应的数据库表的实体类.Dao层是使用了Hibernate连接数据库.操作数据库(增删改查).Service层:引用对应的Dao数据库操 ...
随机推荐
- ruby puts, print, p方法比较
1.puts([obj[, obj2[, ....]]] ) 依次将obj和换行符输出到$>.若没有参数的话则只会输出换行符. 若参数是数组,则依次输出数组元素和换行符.若将既非数组又非字符串的 ...
- IOLI crackme分析——从应用中学习使用radare2
Crackme0x00 - writeup 我现在开始看radare2book了,现在刚看1/3,有些无聊,因为之前也看过一些radare2的实例讲解,所以现在先试着做一下里面的crackme练习. ...
- 关于Quartus+Modelsim 门级仿真 Warning (vopt-2216) Cannot find instance 'NA' specified in sdf.的解决办法
本文操作环境:Win 7 32位系统, Quartus II 11.1 ,Modelsim SE 10.1a 在Quartus II中调用Modelsim SE做Gate Level Simulait ...
- [转]使用CallerMemberName简化InotifyPropertyChanged的实现
原文:https://www.cnblogs.com/TianFang/p/3381484.html 在WPF中,当我们要使用MVVM的方式绑定一个普通对象的属性时,界面上往往需要获取到属性变更的通知 ...
- vb6 读写文件
'--------------------------------- 'write file Dim nHandle As Integer, fName As String fName ...
- doc2vec使用笔记
#!/usr/bin/env Python # coding:utf-8 #improt依赖包 # import sys # reload(sys) # sys.setdefaultencoding( ...
- Package设计2:增量更新
SSIS 设计系列: Package设计1:选择数据类型.暂存数据和并发 Package设计2:增量更新 Package 设计3:数据源的提取和使用暂存 一般来说,ETL实现增量更新的方式有两种,第一 ...
- SSD固态硬盘的GC与Trim
操作系统:其实并没有删除数据: 事实上,它只是在硬盘前的索引区里标记这块文件占用的区域为无效的, 所以等该区域被擦除后,下次数据将要再次写入的时候,可以写入这块被标记的区域. 这也就是为啥那 些所谓的 ...
- MySQL5.7(二)数据库的基本操作
登录MySQL数据库 格式:mysql -u 用户名 -h 主机名或IP地址 -P 端口号 -p 密码
- Unity萌新日记—开发小技巧与冷知识(脚本篇)
在学习unity的过程中,总会遇到很多零碎的知识点和小技巧,在此把它们记录下来,方便日后查看. 第一篇是关于脚本的一些你可能不知道的小知识. 还是个正在学习的萌新,如果写的不好,请谅解. Unity版 ...