上一篇:应用Java技术开发WAP应用程序 >>
Java数据访问对象(DAO)编程模入门
在最近的18个月,我和一个优秀的软件开发团队一起工作,开发定制基于WEB的供应链管理应用程序.我们的应用程序访问广泛的持久层数据,包括出货状态,供应链制度,库存,货物发运,项目管理数据,和用户属性等.我们使用JDBC API连接我们公司的各种数据库平台,并且在整个应用程序中应用了DAO设计模式.
通过在整个应用程序中应用数据访问对象(DAO)设计模式使我们能够把底层的数据访问逻辑和上层的商务逻辑分开.我们为每个数据源创建了提供CRUD(创建,读取,更新,删除)操作的DAO类.
在本文中,我将向你介绍DAO的实现策略以及创建更好的DAO类的技术.我会明确的介绍日志记录,异常处理,和事务划分三项技术.你将学在你的DAO类中怎样把这三种技术结合在一起.这篇文章假设你熟悉JDBC API,SQL和关系性数据库编程.
我们先来回顾一下DAO设计模式和数据访问对象.
DAO基础
DAO模式是标准的J2EE设计模式之一.开发人员使用这个模式把底层的数据访问操作和上层的商务逻辑分开.一个典型的DAO实现有下列几个组件:
1. 一个DAO工厂类;
2. 一个DAO接口;
3. 一个实现DAO接口的具体类;
4. 数据传递对象(有些时候叫做值对象).
具体的DAO类包含了从特定的数据源访问数据的逻辑。在下面的这段中你将学到设计和实现数据访问对象的技术。
事务划分:
关于DAO要记住的一件重要事情是它们是事务性对象。每个被DAO执行的操作(象创建,更新、或删除数据)都是和事务相关联的。同样的,事务划分(transaction demarcation)的概念是特别重要的。
事务划分是在事务界定定义中的方式。J2EE规范为事务划分描述了两种模式:编程性事务(programmatic)和声明性事务(declarative)。下表是对这两种模式的拆分:
| 声明性事务划分 | 编程性事务划分 |
| 程序员使用EJB的布署描述符声明事务属性 | 程序员担负编写事务逻辑代码的责任。 |
| 运行时环境(EJB容器)使用这些属性来自动的管理事务。 | 应用程序通过一个API接口来控制事务。 |
我将把注意力集中的编程性事务划分上。
象前面的介绍一样,DAOs是一些事务对象。一个典型的DAO要执行象创建、更新、和删除这的事务性操作。在设计一个DAO时,首先要问自己如下问题:
1、 事务将怎样开始?
2、 事务将怎样结束?
3、 那个对象将承担起动一个事务的责任?
4、 那个对象将承担结束一个事务的责任?
5、 DAO应该承担起动和结束事务的责任?
6、 应用程序需要交叉访问多个DAO吗?
7、 一个事务包含一个DAO还是多个DAO?
8、 一个DAO包含其它的DAO中的方法吗?
回答这些问题将有助于你为DAO对象选择最好的事务划分策略。对ADO中的事务划分有两个主要的策略。一种方法是使用DAO承担事务划分的责任;另一种是延期性事务,它把事务划分到调用DAO对象的方法中。如果你选择前者,你将要在DAO类中嵌入事务代码。如果你选择后者,事务代码将被写在DAO类的外部。我们将使用简单的代码实例来更好的理解这两种方法是怎样工作的。
实例1展示了一个带有两种数据操作的DAO:创建(create)和更新(update):
| public void createWarehouseProfile(WHProfile profile); public void updateWarehouseStatus(WHIdentifier id, StatusInfo status); |
实例2展示了一个简单的事务,事务划分代码是在DAO类的外部。注意:在这个例子中的调用者把多个DOA操作组合到这个事务中。
| tx.begin(); // start the transaction dao.createWarehouseProfile(profile); dao.updateWarehouseStatus(id1, status1); dao.updateWarehouseStatus(id2, status2); tx.commit(); // end the transaction |
这种事务事务划分策略对在一个单一事务中访问多个DAO的应用程序来说尤为重要。
你即可使用JDBC API也可以使用Java 事务API(JTA)来实现事务的划分。JDBC事务划分比JTA事务划分简单,但是JTA提供了更好的灵活性。在下面的这段中,我们会进一步的看事务划分机制。
使用JDBC的事务划分
JDBC事务是使用Connection对象来控制的。JDBC的连接接口(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.*; import javax.sql.*; // ... DataSource ds = obtainDataSource(); Connection conn = ds.getConnection(); conn.setAutoCommit(false); // ... pstmt = conn.prepareStatement(";UPDATE MOVIES ...";); pstmt.setString(1, ";The Great Escape";); pstmt.executeUpdate(); // ... conn.commit(); // ... |
使用JDBC事务划分,你能够把多个SQL语句组合到一个单一事务中。JDBC事务的缺点之一就是事务范围被限定在一个单一的数据库连接中。一个JDBC事务不能够跨越多个数据库。接下来,我们会看到怎样使用JTA来做事务划分的。因为JTA不象JDBC那样被广泛的了解,所以我首先概要的介绍一下JTA。
JTA概要介绍
Java事务API(JTA;Java Transaction API)和它的同胞Java事务服务(JTS;Java Transaction Service),为J2EE平台提供了分布式事务服务。一个分布式事务(distributed transaction)包括一个事务管理器(transaction manager)和一个或多个资源管理器(resource manager)。一个资源管理器(resource manager)是任意类型的持久化数据存储。事务管理器(transaction manager)承担着所有事务参与单元者的相互通讯的责任。下车站显示了事务管理器和资源管理的间的关系。
JTA事务比JDBC事务更强大。一个JTA事务可以有多个参与者,而一个JDBC事务则被限定在一个单一的数据库连接。下列任一个Java平台的组件都可以参与到一个JTA事务中:
.JDBC连接
.JDO PersistenceManager 对象
.JMS 队列
.JMS 主题
.企业JavaBeans(EJB)
.一个用J2EE Connector Architecture 规范编译的资源分配器。
使用JTA的事务划分
要用JTA来划分一个事务,应用程序调用javax.transaction.UserTransaction接口中的方法。示例4显示了一个典型的JNDI搜索的UseTransaction对象。
| import javax.transaction.*; import javax.naming.*; // ... InitialContext ctx = new InitialContext(); Object txObj = ctx.lookup(";java:comp/UserTransaction";); UserTransaction utx = (UserTransaction) txObj; |
应用程序有了UserTransaction对象的引用之后,就可以象示例5那样来起动事务。
| utx.begin(); // ... DataSource ds = obtainXADataSource(); Connection conn = ds.getConnection(); pstmt = conn.prepareStatement(";UPDATE MOVIES ...";); pstmt.setString(1, ";Spinal Tap";); pstmt.executeUpdate(); // ... utx.commit(); // ... |
当应用程序调用commit()时,事务管理器使用两段提交协议来结束事务。JTA事务控制的方法:
.javax.transaction.UserTransaction接口提供了下列事务控制方法:
| .public void begin() .public void commit() .public void rollback() .public void getStatus() .public void setRollbackOnly() .public void setTransactionTimeout(int) |
应用程序调用begin()来起动事务,即可调用commit()也可以调用rollback()来结束事务。
下一篇:剖析AJAX成为“时尚”的十大主要理由 >>
相关文章:
- · 用Java开发3D游戏之创建浮动的球体
- · 深入浅出Java设计模式之状态模式
- · 将Java程序变成Windows系统服务
- · Java语言入门级的十二大特色详细介绍
- · 在Java中使用JGraph实现图形绘制
- · 成长的烦恼:初涉设计模式
- · 成长的烦恼:进一步理解设计模式
- · Java程序类加载完全揭密
- · Java的垃圾回收机制详解和调优
- · 浅析Java语言中两种异常的差别
- · 谈谈J2SE中的序列化之一个感性的认识
- · 利用Java 3D技术播放动画之QTJ技术
- · “2005Java中国开发者大会”即将召开
- · 现代Java Web开发架构分析
- · 用Java开源项目JOONE实现人工智能编程
- · ASP.NET 2.0移动开发入门之使用模拟器
- · 在ASP.NET中自动给URL加上超链接
- · ASP.NET Atlas对JavaScript的扩展
- · ASP.NET Atlas简单控件介绍之两个基类
- · ASP.NET Atlas简单控件介绍之四大控件
- · ASP.NET页面中标题单点解决方案
- · ASP.NET2.0导航功能之配置会员和角色
- · 在ASP.NET程序中实现语音合成
- · ASP.NET入门随想之吸星大法
- · 抢先试用ASP.NET 2.0中的新型安全控件
- · ASP.NET入门随想六之大航海家
- · ASP.NET2.0应用中定制安全凭证之理论篇
- · ASP.NET2.0应用中定制安全凭证之实践篇
- · ASP.NET入门随想之抽象的力量
- · 一道Google中国挑战赛竞赛题的解法
- · ASP.NET入门随想之开卷有益
- · ASP.NET入门随想之瘦子与胖子的故事
- · .NET 2.0远程传输数据集的优化方法
- · 英特尔:对驱动程序软件漏洞没必要担忧
- · 苹果发布Mac OS升级版 修复60个软件瑕疵
- · 边走边看 手机应用软件开发平台介绍
- · Windows Mobile 5.0最新体验
- · 解读VC++编程中的文件操作API和CFile类
