`
benbenming
  • 浏览: 112146 次
  • 性别: Icon_minigender_1
  • 来自: 石家庄
社区版块
存档分类
最新评论

《J2EE核心模式》(DAO模式)

阅读更多
很多的J2EE应用程序需要使用持久性数据(数据库、文件等)。不同的程序,持久性存储是各不相同的,并且用来访问这些不同的持久性存储机制的API也有很大的不同。如果应用程序要在不同的持久性存储间迁移,这些访问特定持久存储层的代码将面临重写。

  如何解决这个问题?且看"DAO模式"                                          

  数据访问对象(Data Acess Object) 模式                      

一.环境
根据数据源不同,数据访问也不同。根据存储的类型(关系数据库、面向对象数据库、文件等等)和供应商实现不同,持久性存储(比如数据库)的访问差别也很大。

二.问题
许多真是的J2EE应用程序需要在一定程度上使用持久性数据。对于许多应用程序,持久性存储是使用不同的机制实现的,并且用来访问这些不同的持久性存储机制的API也有很大的不同。
比如,应用程序使用实体bean(这里应该是指BMP的bean,CMP的bean已大大降低了与RDBMS的耦合)的分布式组件来表示持久性数据,或者使用JDBC API来访问驻留在某关系数据库管理系统(RDBMS)中的数据,这些组件中包含连接性性和数据访问代码会引入这些组件与数据源实现之间的紧密耦合。组件中这类代码依赖性使应用程序从某种数据源迁移到其他种类的数据源将变得非常麻烦和困难。当数据源变化时,组件也需要改变,以便于能够处理新类型的数据源。

(举个例子来说,我们UPTEL系统是使用JDBC API对 ORACLE数据库进行连接和数据访问的,这些JDBC API与SQL语句散布在系统中,当我们需要将UPTEL迁移到其他RDBMS时,比如曾经迁移到INFORMIX,就面临重写数据库连接和访问数据的模块。)

三.作用力
1.诸如bean管理的实体bean、会话bean、servlet等组件往往需要从持久性存储数据源中检索数据,以及进行数据存储等操作。
2.根据产品供应商的不同,持久性存储API差别也很大,这些API和其能力同样根据存储的类型不同也有差别,这样存在以下缺点,即访问这些独立系统的API很不统一。
3.组件需要透明于实际的持久性存储或者数据源实现,以便于提供到不同供应商产品、不同存储类型和不同数据源类型的更容易的移植性。

四.解决方案
使用数据访问对象(DAO)模式来抽象和封装所有对数据源的访问。DAO管理着与数据源的连接以便检索和存储数据。
DAO实现了用来操作数据源的访问机制。数据源可以时RDBMS,LDAP,File等。依赖于DAO的业务组件为其客户端使用DAO提供更简单的接口。DAO完全向客户端隐藏了数据源实现细节。由于当低层数据源实现变化时,DAO向客户端提供的接口不会变化,所有该模式允许DAO调整到不同的存储模式,而不会影响其客户端或者业务组件。重要的是,DAO充当组件和数据源之间的适配器。

(按照这个理论,如果我们UPTEL系统使用了DAO模式,就可以无缝的从ORACLE迁移到任何一个RDBMS了。梦想总是很完美的,且看看DAO模式如何实现)

1.结构,图1是表示DAO模式中各种关系的类图。

此主题相关图片如下:
                      



2.参与者和职责
                                                              
1)BusinessObject(业务对象)
代表数据客户端。正是该对象需要访问数据源以获取和存储数据。
2)DataAccessObject(数据访问对象)
是该模式的主要对象。DataAccessObject抽取该BusinessObject的低层数据访问实现,以保证对数据源的透明访问。BusinessObject也可以把数据加载和存储操作委托给DataAccessObject。
3)DataSource(数据源)
代表数据源实现。数据源可以是各RDBMSR数据库,OODBMS,XML文件等等。
4)valueObject(值对象)
代表用做数据携带着的值对象。DataAccessObject可以使用值对象来把数据返回给客户端。
DataAccessObject也许会接受来自于客户端的数据,其中这些用于更新数据源的数据存放于值对象中来传递。

3.策略
1).自动DAO代码产生策略
因为每个BusinessObject对应于一个特殊的DAO,因此有可能建立BusinessObject,DAO和低层实现(比如RDBMS中的表)之间的关系(映射)。一点这些关系(映射)已经建立,我们就可以编写与应用程序有馆的代码生成的简单工具了(什么?自己写GP程序?用ORM的附带工具自动生成不就完了,最多自己写几个Adapter,牛人就是不同,啥都要自己写...),其中的工具可以产生该应用程序需要的所有DAO代码。
如果DAO需求很复杂,我们可以采用第三方工具,其中这些工具提供对象到RDBMS数据库的关系映射(这里指的是前面提到的ORM工具,全称是Object Relation Mapping,目前成熟的ORM工具有很多:Hibernate,OJB,Torque,TopLink等等)。
这些工具通常包含GUI工具来把业务对象映射到持久性存储对象,并且因而定义中间DAO。一旦这些映射完成,这些工具会自动地生成代码,并且也许会提供其他增值功能,比如结果缓冲、查询缓冲、与应用程序集成,以及与其他第三方产品(比如分布式缓冲)地继承,等等。
(增值服务:Torque提供了结果缓冲,Hibernate提供了对Oracle数据库SQL指令的优化,OJB提供JDO API、OMDB API)

2).数据访问对象的工厂策略
通过调整抽象工厂和工厂方法模式,DAO模式可以达到很高的灵活度。
当低层存储不会随着实现变化而变化时,该策略可以使用工厂方法模式来实现该策略。以产生应用程序需要的大量DAO。图2是这种情况下的类图。

此主题相关图片如下:
                          


当低层存储随着实现变化而变化时,该策略可以使用抽象工厂方法模式而实现。
图3是这种情况下的类图。

此主题相关图片如下:



5.结果
1).启用透明性
业务对象可以是使用数据源,而无须了解该数据源实现的具体细节。访问是透明的,原因是实现被隐藏在DAO的内部。
2).启用更容易的迁移
DAO层使应用程序更加容易地迁移到一个不同的数据库实现。业务对象不了解低层数据实现。因而,该迁移只涉及对DAO层的变化。更进一步说,如果使用工厂策略,则有可能为每一个低层存储实现提供一个具体工厂实现。在这种情况下,迁移到不同的迁移实现意味着给应用程序提供一个新的工厂实现。
3).减少业务对象中代码复杂度
由于DAO管理所有的数据访问复杂性,它可以简化业务对象和其他使用DAO的客户端中的代码。所有与实现有关的代码(比如sql语句)都被包含在DAO中,而不是包含在业务对象中。这样做提高了代码的可读性,已经代码生产效率。
4).把所有的数据访问集中到一个独立的层。
因为所有的数据访问操作现在被委托给DAO,所有单独的数据访问层可以被看作把数据访问实现与应用程序中的其他代码相隔离的。这种集中化使应用程序更容易地维护和管理。
5).不适用于容器管理的持久性
由于EJB容器用容器管理的持久性(CMP)来管理实体bean,该容器会自动地服务所有的持久性存储访问。使用容器管理的实体bean的应用程序不需要DAO层,因为该应用程序服务器透明地提供该功能。然而,当需要组合使用CMP和BMP时,DAO仍旧有用处。
6).添加其他层
DAO会在数据客户端和数据源之间创建其他的对象层,其中该数据源需要被设计和实现以便于权衡该模式的好处。但是选择本方法也会带来额外的开销。
7).需要类层次设计
在使用工厂策略时,我们需要设计和实现具体工厂的层次,以及这些工厂产生的具体产品层次。如果能够确保这种灵活性,则有必要考虑这种额外的工作。这样做会增加设计的复杂性。然而,在实现该工厂策略时,你可以首先考虑工厂方法模式,然后再根据需要过渡到抽象工厂。

六.范例代码
1.实现数据访问对象模式
范例9-4时表示Customer信息的持久性对象的DAO范例代码。当findCustomer()被调用时,CloudscapeCustomerDAO创建一个Customer值对象。
范例9-6是使用DAO的范例代码。

2.实现数据访问对象的工厂策略
1)使用工厂方法模式
2)使用抽象工厂模式
范例代码9-2是CloudscapeDAOFactory的范例代码。
范例代码9-3中的CustomerDAO接口为Customer持久性对象定义了DAO方法,这些接口是被所有具体DAO实现来实现的,比如CloudscapeCustomerDAO、OracleCustomerDAO、已经SybaseCustomerDAO。Account和OrederDAO接口也与此类似。


Example 9.1 Abstract DAOFactory Class

// Abstract class DAO Factory
public abstract class DAOFactory {

// List of DAO types supported by the factory
public static final int CLOUDSCAPE = 1;
public static final int ORACLE = 2;
public static final int SYBASE = 3;
...

// There will be a method for each DAO that can be
// created. The concrete factories will have to
// implement these methods.
public abstract CustomerDAO getCustomerDAO();
public abstract AccountDAO getAccountDAO();
public abstract OrderDAO getOrderDAO();
...

public static DAOFactory getDAOFactory(
int whichFactory) {

switch (whichFactory) {
case CLOUDSCAPE:
return new CloudscapeDAOFactory();
case ORACLE :
return new OracleDAOFactory();
case SYBASE :
return new SybaseDAOFactory();
...
default :
return null;
}
}
}


Example 9.2 Concrete DAOFactory Implementation for Cloudscape

// Cloudscape concrete DAO Factory implementation
import java.sql.*;

public class CloudscapeDAOFactory extends DAOFactory {
public static final String DRIVER=
"COM.cloudscape.core.RmiJdbcDriver";
public static final String DBURL=
"jdbc:cloudscape:rmi://localhost:1099/CoreJ2EEDB";

// method to create Cloudscape connections
public static Connection createConnection() {
// Use DRIVER and DBURL to create a connection
// Recommend connection pool implementation/usage
}
public CustomerDAO getCustomerDAO() {
// CloudscapeCustomerDAO implements CustomerDAO
return new CloudscapeCustomerDAO();
}
public AccountDAO getAccountDAO() {
// CloudscapeAccountDAO implements AccountDAO
return new CloudscapeAccountDAO();
}
public OrderDAO getOrderDAO() {
// CloudscapeOrderDAO implements OrderDAO
return new CloudscapeOrderDAO();
}
...
}


Example 9.3 Base DAO Interface for Customer

// Interface that all CustomerDAOs must support
public interface CustomerDAO {
public int insertCustomer(...);
public boolean deleteCustomer(...);
public Customer findCustomer(...);
public boolean updateCustomer(...);
public RowSet selectCustomersRS(...);
public Collection selectCustomersVO(...);
...
}


Example 9.4 Cloudscape DAO Implementation for Customer

// CloudscapeCustomerDAO implementation of the
// CustomerDAO interface. This class can contain all
// Cloudscape specific code and SQL statements.
// The client is thus shielded from knowing
// these implementation details.

import java.sql.*;

public class CloudscapeCustomerDAO implements
CustomerDAO {

public CloudscapeCustomerDAO() {
// initialization
}

// The following methods can use
// CloudscapeDAOFactory.createConnection()
// to get a connection as required

public int insertCustomer(...) {
// Implement insert customer here.
// Return newly created customer number
// or a -1 on error
}

public boolean deleteCustomer(...) {
// Implement delete customer here
// Return true on success, false on failure
}

public Customer findCustomer(...) {
// Implement find a customer here using supplied
// argument values as search criteria
// Return a value object if found,
// return null on error or if not found
}

public boolean updateCustomer(...) {
// implement update record here using data
// from the customerData value object
// Return true on success, false on failure or
// error
}

public RowSet selectCustomersRS(...) {
// implement search customers here using the
// supplied criteria.
// Return a RowSet.
}

public Collection selectCustomersVO(...) {
// implement search customers here using the
// supplied criteria.
// Alternatively, implement to return a Collection
// of value objects.
}
...
}


Example 9.5 Customer value Object

public class Customer implements java.io.Serializable {
// member variables
int CustomerNumber;
String name;
String streetAddress;
String city;
...

// getter and setter methods...
...
}


Example 9.6 Using a DAO and DAO Factory ?Client Code

...
// create the required DAO Factory
DAOFactory cloudscapeFactory =
DAOFactory.getDAOFactory(DAOFactory.DAOCLOUDSCAPE);

// Create a DAO
CustomerDAO custDAO =
cloudscapeFactory.getCustomerDAO();

// create a new customer
int newCustNo = custDAO.insertCustomer(...);

// Find a customer object. Get the value object.
Customer cust = custDAO.findCustomer(...);

// modify the values in the value object.
cust.setAddress(...);
cust.setEmail(...);
// update the customer object using the DAO
custDAO.updateCustomer(cust);

// delete a customer object
custDAO.deleteCustomer(...);
// select all customers in the same city
Customer criteria=new Customer();
criteria.setCity("广州");
Collection customersList =
custDAO.selectCustomersVO(criteria);
// returns customersList - collection of Customer
// value objects. iterate through this collection to
// get values.

...


七.相关模式
1.值对象
2.工厂方法
3.代理[/img]
分享到:
评论

相关推荐

    J2EE核心模式第二版

    《J2EE核心模式第二版》是一本深入探讨Java企业级应用开发的经典著作。这本书针对JavaEE(Java Platform, Enterprise Edition)平台,详尽解析了一系列的设计模式,旨在帮助开发者理解和应用这些模式,以构建高效、...

    J2EE核心模式电子版

    《J2EE核心模式》是一本深受欢迎的书籍,它为Java企业级应用开发提供了坚实的理论基础和技术指导。这本书详细探讨了在J2EE(Java 2 Platform, Enterprise Edition)平台上构建可扩展、灵活且可维护的软件系统的关键...

    J2EE核心模式pdf

    **J2EE核心模式**是Java企业版(Java 2 Platform, Enterprise Edition)开发中的重要指导原则和最佳实践。这本书深入探讨了如何有效地利用J2EE技术构建可扩展、健壮且可维护的企业级应用程序。以下是对J2EE核心模式...

    J2EE核心模式之DAO

    总之,DAO模式是J2EE核心模式中用于抽象和封装数据访问逻辑,提供不同数据源的统一访问方式的一种有效机制。它通过隔离业务组件和数据源之间的直接依赖关系,简化了代码的维护,增强了应用程序的可移植性和灵活性。...

    J2EE核心模式之DAO(简体中文)

    在"J2EE核心模式之DAO(简体中文)"这个资料中,我们将会深入探讨DAO模式在J2EE环境下的具体应用和实现。 1. **DAO模式的概念** DAO模式是软件设计中的一种结构型模式,它提供了一种方法来封装对数据库、文件系统或...

    J2EE核心模式

    《J2EE核心模式》是一本专为提升Java企业级应用开发技能而编写的书籍,其主要内容涵盖了在J2EE平台上构建可扩展、可维护且高效的企业级应用程序的关键设计模式。J2EE(Java 2 Platform, Enterprise Edition)是...

    核心J2EE模式-DAO(中文版)

    综上所述,DAO模式是J2EE应用中解决数据访问问题的关键设计模式,它通过提供一个统一的接口,隔离了业务逻辑和数据存储,提高了代码的可维护性和可测试性。在实际开发中,结合其他设计模式,如工厂模式和抽象工厂...

    J2EE核心模式003.pdf

    本书《J2EE核心模式003》很可能是深入探讨了在J2EE开发过程中常用的设计模式,以及如何有效地将这些模式应用于实际项目中。 ### J2EE核心设计模式概览 #### 1. MVC(Model-View-Controller) MVC是一种经典的架构...

    J2EE核心模式.pdf

    由于提供的文件内容实际上并未包含J2EE核心模式的具体知识点,而是重复的链接和版权提醒,这不符合生成详细知识点的要求。但是根据标题“J2EE核心模式.pdf”,我可以假设您需要的是关于J2EE核心模式的知识点。J2EE...

    Sun-J2EE核心模式

    《Sun-J2EE核心模式》是一本专注于Java企业级应用开发的权威著作,由Sun公司出品,旨在解析J2EE平台中的核心设计模式,帮助开发者深入理解并有效地应用这些模式来构建高性能、可扩展的系统架构。这本书是学习和提升...

    J2EE核心模式(Core J2EE Patterns)

    《J2EE核心模式(Core J2EE Patterns)》是一本深度探讨J2EE平台设计模式的权威著作,由SUN公司的资深工程师倾力撰写。这本书是Java企业级开发者的必备参考书籍,它揭示了在复杂的企业级应用开发中,如何有效地利用...

    J2EE核心模式_java

    《J2EE核心模式》是Java企业级应用开发的经典之作,深入探讨了在J2EE平台上构建可扩展、健壮且可维护的分布式系统的设计模式。这本书主要关注于如何利用Java Enterprise Edition(J2EE)框架来解决实际的业务问题,...

    j2ee核心模式 j2ee平台里模式的应用

    《J2EE核心模式:J2EE平台里模式的应用》一书深入探讨了在Java企业级应用开发中广泛采用的设计模式和技术架构。J2EE(Java 2 Platform, Enterprise Edition)是Oracle公司推出的用于构建分布式、多层企业级应用程序...

    J2EE核心模式.7z

    《J2EE核心模式》是一本深入探讨Java企业级应用开发的经典著作,它详细阐述了在J2EE(Java 2 Platform, Enterprise Edition)平台上构建可扩展、灵活且高效的分布式系统的最佳实践。这本书的核心目标是提供一套经过...

    J2EE 核心模式

    《J2EE核心模式》是一本深入探讨Java企业级应用开发的经典著作,主要针对使用Java 2企业版(J2EE)平台进行大型分布式系统设计的开发者。这本书旨在通过一系列经过实践验证的设计模式,帮助读者理解和掌握J2EE平台的...

    j2ee 核心模式

    **J2EE核心模式详解** J2EE(Java 2 Platform, Enterprise Edition)是Java平台的一个版本,专门针对企业级应用开发。它提供了一个多层架构的框架,用于构建可扩展、高性能、高可用性的分布式应用程序。J2EE的核心...

Global site tag (gtag.js) - Google Analytics