Data Access ObjectContextAccess to data varies depending on the source of the data. Access to persistent storage, such as to a database, varies greatly depending on the type of storage (RDBMS, OODBMS, flat files, and so forth) and the vendor implementation. ProblemMany real-world J2EETM applications need to use persistent data at some point. For many applications, the persistent storage is implemented with different mechanisms, and there are marked differences in the APIs used to access these different persistent storage mechanisms. Other applications may need to access data that resides on a different system. For example, the data may reside on a mainframe, an LDAP repository, a B2B service, a credit card bureau, and so forth. Typically, applications use persistent shared distributed components such as entity beans to represent persistent data. An application is considered to employ bean-managed persistence for its entity beans when these entity beans explicitly access the persistent storage-that is, the entity bean includes code to directly access the persistent storage. An application with simpler requirements may forego using entity beans and instead, use session beans or servlets to directly access the persistent storage to retrieve and modify the data. Applications can use the JDBCTM API to access data residing in an RDBMS. The JDBC API enables standard access and manipulation of data in a persistent storage, such as a relational database. JDBC enables J2EE applications to use SQL statements, which are the standard means for accessing RDBMS tables. However, even within an RDBMS environment, the actual syntax and format of the SQL statements may vary depending on the particular database product. There is even greater variation with different types of persistent storage. Access mechanisms, supported APIs, and features vary drastically when comparing a relational type of persistent storage such as RDBMS to other types of persistent stores, such as Object Oriented Databases (OODBMS), file system-based ISAM databases, or simply flat files. Applications that need to access data from a legacy or disparate system (for example, a mainframe, CORBA service or B2B service) are often required to use APIs that may be proprietary. Such disparate data sources offer challenges to the application and can potentially create a tight integration between application code and integration code. When business components-entity beans, session beans and even presentation components like servlets and JSPTM)-need to access a data source, they can use the appropriate API to achieve connectivity and manipulate the data source. But, including the connectivity and data access code within these components introduces a tight coupling between the components and the data source implementation. Such code dependencies in the components makes it difficult and tedious to migrate the application from one type of data source to another. When the data source changes, the components need to be changed to handle the new type of data source. Forces
SolutionUse a Data Access Object to abstract and encapsulate all access to the data source. The Data Access Object manages the connection with the data source to obtain and store data. The Data Access Object (DAO) is the primary object of this pattern. The DAO implements the access mechanism required to work with the data source. The data source could be a persistent store like an RDBMS, an external service like a B2B exchange, a repository like an LDAP database or a business service accessed via CORBA IIOP or low-level sockets. The business component that relies on the DAO object uses the simpler interface exposed by the DAO for its clients. The DAO completely hides the data source implementation details from its clients. Because the interface exposed by the DAO to clients does not change when the underlying data source implementation changes, this pattern allows the DAO to adapt to different storage schemes without affecting its clients or business components. Essentially, the DAO acts as an adapter between the component and the data source. StructureThe following class diagram represents the relationships for the Data Access Object pattern. click to enlarge
Participants & ResponsibilitiesThe following sequence diagram shows the interaction between the various participants in this pattern.
BusinessObject DataAccessObject (DAO) DataSource StrategiesAutomatic DAO Code Generation ToolsSince each BusinessObject corresponds to a specific DAO object, it is possible to establish relationships between the BusinessObject, DAO, and the underlying implementation (such as the tables in an RDBMS). Once the relationships are established it is possible to write a simple application-specific code generation utility that generates the code for all DAOs required by the application. The meta-data to generate the DAO can come from a developer-defined descriptor file. Or, the code generator can automatically introspect the database and provide the necessary DAOs to access the database. If the requirements for DAOs are sufficiently complex, consider using third party tools that provide Object-to-Relational mapping for RDBMS databases. These tools typically include GUI tools to map the BusinessObjects to the persistent storage objects and thereby define the intermediary data access objects. The tools automatically generate the code once the mapping is complete and may provide other value-added features such as results caching, query caching, integration with application servers, integration with other third party products (distributed caching), and so forth. Factory for Data Access ObjectThe DAO pattern can be made highly flexible by adopting the Abstract Factory and the Factory Method patterns. (See related patterns.) This strategy provides a DAO factory object that can construct various types of DAO factories, each factory supporting a different type of persistent storage implementation. Once you obtain the DAO factory for a specific implementation, you use it to produce DAOs supported and implemented in that implementation (CustomerDAO, AccountDAO, and so forth). The following class diagram for this strategy shows the DAO factory as a base class from which different DAO factories inherit and implement specific storage access mechanisms to different implementations (for example, RdbDAOFactory to access an RDBMS such as Oracle, XmlDAOFactory to access an XML repository, and so on). Then, use a specific DAO factory such as RdbDAOFactory to obtain specific DAOs that support the business objects (for example, DAO1, DAO2, and so forth). This is similar to obtaining a CustomerDAO for a CustomerBusinessObject, an AccountDAO for an AccountBusinessObject, and so on. Each DAO is responsible for connecting to the data source, and obtaining and manipulating data for the business object it supports.
The following sequence diagram shows the interactions for this strategy: click to enlarge
Consequences
Related Patterns
(c) 2000-2001 Sun Microsystems, Inc. All Rights Reserved. Version 1.0 Beta | |||
|
| ||||||||||||