Java - Data Access Object (DAO) Pattern

Java Conceptuel Diagram

About

Many applications need to use persistent data.

The Data Access Object (DAO) Pattern is aimed to minimize the direct dependency between:

  • application code
  • and data access code.

Such code dependencies in components make 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.

Furthermore, persistent storage APIs vary depending:

  • on the product vendor (Oracle, Sybase, …).
  • on the type of storage: RDBMS, object-oriented database management system (OODBMS), XML documents, flat files, web service, a LDAP repository, and so forth.

A Data Access Object (DAO) is used to abstract and encapsulate all access to the data source. The DAO manages the connection with the data source to obtain and store data.

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. Essentially, the DAO acts as an adapter between the component and the data source.

The only required change is the getDAOFactory() method call to the DAO factory to obtain a different factory in the client.

Abstract Factory Pattern Component Code

Daoabstractfactorypattern

Client

...
// create the required DAO Factory
DAOFactory OracleDbFactory =   
  DAOFactory.getDAOFactory(DAOFactory.DAOORACLEDB);

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

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

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

// modify the values in the Transfer 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("New York");
Collection customersList = 
  custDAO.selectCustomersTO(criteria);
// returns customersList - collection of Customer
// Transfer Objects. iterate through this collection to
// get values.

...

Factory

Definition

// Abstract class DAO Factory
public abstract class DAOFactory {

  // List of DAO types supported by the factory
  public static final int ORACLE = 1;
  public static final int XML= 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 ORACLE: 
          return new OracleDbDAOFactory();
      case XML: 
          return new XmlDAOFactory();      
      case SYBASE    : 
          return new SybaseDAOFactory();
      ...
      default           : 
          return null;
    }
  }
}

Implementation

Factory Method Pattern:

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

public class OracleDbDAOFactory extends DAOFactory {
  public static final String DRIVER=
    "oracle.jdbc.OracleDriver";
  public static final String DBURL=
    "jdbc:oracle:thin:@[host]:[port]:[sid]";

  // 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() {
    // OracleDbCustomerDAO implements CustomerDAO
    return new OracleDbCustomerDAO();
  }
  public OrderDAO getOrderDAO() {
    // OracleDbOrderDAO implements OrderDAO
    return new OracleDbOrderDAO();
  }
  public AccountDAO getAccountDAO() {
    // OracleDbAccountDAO implements AccountDAO
    return new OracleDbAccountDAO();
  }
  ...
}

DAO

Interface

// 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 selectCustomersTO(...);
  ...
} 

Implementation

// OracleDbCustomerDAO 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 OracleDbCustomerDAO implements 
    CustomerDAO {
  
  public OracleDbCustomerDAO () {
    // initialization 
  }

  // The following methods can use
  // OracleDbCustomerDAOFactory.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 Transfer Object if found,
    // return null on error or if not found
  }

  public boolean updateCustomer(...) {
    // implement update record here using data
    // from the customerData Transfer 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 selectCustomersTO(...) {
    // implement search customers here using the
    // supplied criteria.
    // Alternatively, implement to return a Collection 
    // of Transfer Objects.
  }
  ...
}

Transfer or Data Model Object

wiki/Data transfer object

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

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

Documentation / Reference





Discover More
Java Conceptuel Diagram
J2EE - JPA and Stateless Session Bean (EJB) as Data Access Object (DAO)

Stateless EJB session beans as Data Access Object (DAO) implementation with JPA. You must use the EntityManagerFactory to get an EntityManager The resulting EntityManager instance is a PersistenceContext/Cache...



Share this page:
Follow us:
Task Runner