Core Java

Java DAO Pattern

Introduction:

The DAO or the Data Access Object pattern is a very popular structural design pattern that separates the persistence logic in a separate layer. The idea is to abstract or hide the database logic from the business layer. It helps in hiding unnecessary CRUD operation and storage details from our service layer so that it can evolve independently. This is also known as ‘Separation of concerns’ principle.

In this tutorial, we’ll learn to implement Java DAO pattern with the help of an example.

Context Buildup:

In the DAO design pattern, we usually have the following components:

  • The model or the transfer object which holds our data and is transferred from a layer to another
  • Interfaces, to encourage a flexible design
  • Interface Implementation, holding the persistence logic implementation

To follow along with this tutorial, let’s say we have an application which operates on Employee details. On using the DAO pattern, our application structure would be similar to:

Java DAO Pattern

Here, EmployeeDao is an interface providing an abstraction over the persistence logic present in EmployeeDaoImpl class. Our business layer will only interact with the persistence layer using the EmployeeDao interface. In this way, the two layers remain de-coupled and the business layer doesn’t need to know the complex details involved in persistence.

Model Object:

Let’s start by defining our Employee class:

public class Employee {
    
    private int id;
    private String name;
    
    //constructor, equals() & toString() impl, getters and setters
}

It’s a simple POJO representing an Employee in our application.

DAO Pattern Interface:

We’ll now define our EmployeeDao interface, which will abstract  the details of our class holding concrete implementation of the persistence logic:

public interface EmployeeDao {

    public List<Employee> getAllEmployees();
    public Optional<Employee> getEmployeeById(int id);
    public void save(Employee emp);
    public void delete(Employee emp);
    public void updateEmpName(Employee emp, String name);

}

Here, we have defined the CRUD operations that’ll be exposed to our business layer.

DAO Pattern Concrete Implementation:

Having defined our EmployeeDao interface, let’s implement it:

public class EmployeeDaoImpl implements EmployeeDao {

    private List<Employee> employees;

    public EmployeeDaoImpl() {
        employees.add(new Employee(1, "Harry"));
        employees.add(new Employee(2, "Kathy"));
        employees.add(new Employee(3, "Simens")); 
    }
 
    @Override   
    public List<Employee> getAllEmployees() {
        return employees;
    }  

    @Override
    public Optional<Employee> getEmployeeById(int id) {
        Employee emp = null;
        for(Employee e : employees) {
            if(e.getId() == id) {
                emp = e;
                break;
            }  
        }
        return Optional.ofNullable(emp);
    }

    @Override
    public void save(Employee emp) {
        employees.add(emp);
    }

    @Override
    public void delete(Employee emp) {
        employees.remove(emp);
    }

    @Override
    public void updateEmpName(Employee emp, String name) {
        for(Employee e : employees) {
            if(e.equals(emp)) {
                //if employee exists
                e.setName(name);
                break;
            }
        } 
    }
}

In the above implementation, just for the sake of simplicity, we have used an ArrayList as a data store instead of interacting with some DB. Here, we make sure that we have overridden the equals() method in our Employee class correctly.

In real-world, in any DAO class, we’ll usually be interacting with some database.

Using DAO Layer:

Now, let’s try to perform some operations on our data store using the created persistence layer:

public class EmployeeApp {
 
    private static EmployeeDao employeeDao;
 
    public static void main(String[] args) {
        employeeDao = new EmployeeDaoImpl();
         
        List<Employee> employees = employeeDao.getAllEmployees();
        System.out.println(employees);
        
        Employee jessica = new Employee(4, "Jessica");
        employeeDao.save(jessica);
        
        Optional<Employee> jessicaOpt = employeeDao.getEmployeeById(4);
        jessicaOpt.ifPresent(System.out::println);
    
        employeeDao.update(jessica, "Jessica S.");
        System.out.println(employees);
           
    }
}

Our EmployeeDaoImpl class supports search, insert, update and delete operations. The business layer remains unaware of the actual persistence logic.

Advantages of DAO Pattern:

There are several advantages of using DAO Pattern:

  • It promotes loose coupling between our application and persistence layers. If we wish to migrate from one database to another, we’ll only have to update the logic in our DAO class i.e. our service layer remains unaware and have no impacts
  • Due to the clear separation of concerns, it makes testing and debugging our code a lot easier
  • It encourages and supports object-oriented programming by using the power of abstraction

Conclusion:

In this tutorial, we learned to implement DAO Pattern in Java. It helps us to have a clear boundary between our persistence and business layers, promoting loose-coupling.

2 comments

Leave a Comment

Your email address will not be published. Required fields are marked *