Skip to content

Data Access Object Design Pattern

3 components of a DAO Class - Object with all of the details ClassDAO - The interface / blueprint for the implementations to follow ClassDAOImpl - An implementation of ClassDAO #eg CourierDAOCSVImpl

All a DAO serves to do is to separate data access from the logic.

https://hibernate.org

Overview

DAO stands for Data Access Object. It is a design pattern used to separate the data separate data persistence logic in its own layer, away from the core logic of the application or service.

The application or service can be completely abstracted from the low-level operations of the database access. Data can even be lifted and shifted to a different format and the DAO should automatically use the correct implementation based on its configuration.

This is known as the principle of the Separation of Logic.

DAO Design Pattern

With DAO, there are three core components to a design, these are:

  • The model which is transferred from one layer to another.
  • The interfaces which provide a flexible design
  • The interface implementation, which is typically format specific, and a concrete implementation of the persistence logic.

Persistence logic handles reading and writing from persistent storage, such as a database or file.

Implementing DAO

Using the Courier class as an example, the DAO pattern can be implemented as such:

  • The Courier model which is transferred from one layer to another. (Treat the class like a blueprint for the results that you expect from the database. Its basically a blank business card that needs filling (or a POJO, Plain Old Java Object)
  • The CourierDAO interfaces provides a flexible design and API to implement.
  • The CourierDAOImpl concrete class that is an implementation of the CourierDAO interface.
classDiagram
    direction LR

    class Main{
        Calls the interface
    }

    class Courier{
        - Contains data from DAO
    }

    class CourierDAO {
        <<interface>>
        - Contains method blueprints
        for implementations

    }

    class CourierDAOImpl {
        - Format-specific implementation
        - Contains logic of methods defined
        in CourierDAO
    }

    Main --> CourierDAO : calls
    CourierDAOImpl --> CourierDAO : Implements
    CourierDAO --> Courier : Transfers

DAO Pattern Implementation

Class Example

Courier.java
package io.entityfour.sweet_treats.courier;

import java.time.LocalTime;

public class Courier {
    // Fields
    private String name;
    private LocalTime startTime;
    private LocalTime endTime;
    private boolean refrigerationRequired;
    private int maxDeliveryDistance;
    private String vehicleType;
    private float perMileCost;
    private boolean preferredStatus;


    // X-ers
    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public LocalTime getStartTime() {
        return this.startTime;
    }

    public void setStartTime(LocalTime startTime) {
        this.startTime = startTime;
    }

    public LocalTime getEndTime() {
        return this.endTime;
    }

    public void setEndTime(LocalTime endTime) {
        this.endTime = endTime;
    }

    public boolean isRefrigerationRequired() {
        return this.refrigerationRequired;
    }

    public boolean getRefrigerationRequired() {
        return this.refrigerationRequired;
    }

    public void setRefrigerationRequired(boolean refrigerationRequired) {
        this.refrigerationRequired = refrigerationRequired;
    }

    public int getMaxDeliveryDistance() {
        return this.maxDeliveryDistance;
    }

    public void setMaxDeliveryDistance(int maxDeliveryDistance) {
        this.maxDeliveryDistance = maxDeliveryDistance;
    }

    public String getVehicleType() {
        return this.vehicleType;
    }

    public void setVehicleType(String vehicleType) {
        this.vehicleType = vehicleType;
    }

    public float getPerMileCost() {
        return this.perMileCost;
    }

    public void setPerMileCost(float perMileCost) {
        this.perMileCost = perMileCost;
    }

    public boolean isPreferredStatus() {
        return this.preferredStatus;
    }

    public boolean getPreferredStatus() {
        return this.preferredStatus;
    }

    public void setPreferredStatus(boolean preferredStatus) {
        this.preferredStatus = preferredStatus;
    }


    // Constructors 
    public Courier() {

    }

    public Courier(String name, LocalTime startTime, LocalTime endTime, boolean refrigerationRequired, int maxDeliveryDistance, String vehicleType, float perMileCost, boolean preferredStatus) {
        this.name = name;
        this.startTime = startTime;
        this.endTime = endTime;
        this.refrigerationRequired = refrigerationRequired;
        this.maxDeliveryDistance = maxDeliveryDistance;
        this.vehicleType = vehicleType;
        this.perMileCost = perMileCost;
        this.preferredStatus = preferredStatus;
    }

}

Interface Example

```java title="CourierDAO.java package io.entityfour.sweet_treats.courier;

import java.util.List;

public interface CourierDAO {

List<Courier> getAllCouriers(); // Create a list of type Courier
Courier getCourierByName(String name); // Using type Courier, get courier by name
Courier getCourierByPreferredStatus(boolean preferredStatus);

}

### Implementation / Concrete Class Example

```java title="CourierDAOImpl.java
package io.entityfour.sweet_treats.courier;

import java.time.LocalTime;
import java.util.ArrayList;
import java.util.List;

public class CourierDAOCSVImpl implements CourierDAO {

    public List<Courier> courier;

    public void getCSVContents() {

    }

    public CourierDAOCSVImpl() {
            courier = new ArrayList<>();
            courier.add(new Courier("Bobby",LocalTime.parse("09:00:00"),LocalTime.parse("13:00:00"),true,5,"bike",1.75,false));
            courier.add(new Courier("Martin",LocalTime.parse("09:00:00"),LocalTime.parse("17:00:00"),false,3,"unknown",1.50,false));
            courier.add(new Courier("Geoff",LocalTime.parse("10:00:00"),LocalTime.parse("16:00:00"),true,4,"bike",2.00,false));
        }

    @Override
    public List<Courier> getAllCouriers() {
        return courier;
    }

    @Override
    public Courier getCourierByName(String name){
        return null;
    }


    @Override
    public Courier getCourierByPreferredStatus(boolean preferredStatus) {
        return null;
    }



}

Usage

Finish this off Lookup collections vs hashmap

https://www.baeldung.com/java-8-double-colon-operator https://stackoverflow.com/questions/20001427/double-colon-operator-in-java-8