The Data Access Object (DAO) Pattern

It's possible to be less ambitious in accessing an RDBMS, and not attempt to map objects directly onto data - or at least, not design business objects that require such a mapping. When we distinguish between business logic and persistence logic, we can decouple business logic from persistent storage by defining a persistence interface that business logic components can use. The Data Access Object pattern (shown in detail in ) uses an abstraction layer of ordinary Java interfaces between business logic and persistence logic components. The implementations of these interfaces handle persistence logic. The DAO pattern is described in Core J2EE Patterns, although it's really just a special case of the Strategy GoF pattern, which we discussed in . In Sun Java Center's examples, the DAO pattern is usually associated with entity beans with Bean-Managed Persistence (BMP). However, it can be used anywhere in a J2EE app. Entity beans provide a similar abstraction between business logic and persistence storage, but they lock us into one way of accessing data and one particular O/R mapping solution: the DAO pattern leaves us a choice. For example, we can use JDBC, JDO or entity beans to implement DAO interfaces. The DAO pattern also has the important advantage of working inside or outside an EJB container: often we can use the same DAO implementations in either location, which increases the flexibility of our architecture. The DAO pattern differs from entity beans or O/R mapping approach in that:

With the DAO pattern the business logic determines the data access interfaces. With O/R mapping there is a risk that the data layer will dictate the working of the business logic layer. This is one of the reasons I'm skeptical about object-driven modeling. I have often seen situations where the modeling of one entity bean per RDBMS table dictates the nature of session bean code and results in excessive complexity. This is the tail wagging the dog: the point of an app is to express business rules, not work with a predetermined and possibly artificial data structure. The following two diagrams illustrate how the DAO pattern can be used to conceal very different data access strategies from a business object Both illustrate the use of a DAO implementing a MyDAO interface. The left hand diagram (Scenario 1) illustrates use of an implementation of this interface that uses JDBC. The right hand diagram (Scenario 2) illustrates use of an implementation that uses a layer of entity beans to abstract access to the RDBMS. Although the resulting architectures look very different, because the business object accesses the DAO through a fixed interface there is no need for changes in business logic to accommodate these two data access strategies.

Java Click To expand

DAOs, like business objects, are part of an app's middle tier. In , we'll look at how to implement the DAO pattern to cleanly decouple business logic from persistence logic. We'll also use this pattern in our sample app.


It's important to recognize that there are times when it isn't practicable or beneficial to try to decouple business logic from persistence logic, whatever abstraction we use and however desirable such separation is. For example, sometimes we are unable to separate the two without fatally compromising performances; sometimes it's inappropriate to force every implementation to use a certain O/R mapping or even certain value objects.

In such cases, we should apply good OO design principles - there's nothing special about data access. We should try to minimize the amount of code that requires a mix of business and persistence logic and decouple it from other business objects by isolating it behind Java interfaces. We can then reimplement these interfaces as necessary. By writing unit tests to the interfaces, rather than concrete classes, we will be able to start with comprehensive unit tests if we ever need to port the app to another persistent store.