A Data Access Object (DAO) is a design pattern used in software development to provide an abstraction layer between the application and the database. It encapsulates data access logic and provides a structured way to interact with databases without exposing the underlying database implementation to the rest of the application.

  • Primary Purpose: Separates business logic from data persistence logic.
  • Key Benefit: Improves maintainability, testability, and scalability of applications.

Why Use the DAO Pattern?

  • Encapsulation: Hides database logic from the application.
  • Reusability: Centralized database operations can be reused across different components.
  • Flexibility: Easily switch between different databases or storage mechanisms.
  • Maintainability: Changes to data access logic do not affect the business logic.

Structure

A DAO typically consists of the following:

  1. DAO Interface – Defines the database operations (CRUD methods).
  2. DAO Implementation – Implements the interface using a specific database technology (e.g., JDBC, Hibernate, JPA).
  3. Model/Entity Class – Represents the database table as an object.
  4. Database Connection Manager – Manages connections to the database.

Examples in Java

DAO Interface

public interface UserDAO {
    void save(User user);
    User getById(int id);
    List<User> getAll();
    void update(User user);
    void delete(int id);
}

A. DAO Implementation with JDBC

public class UserDAOImpl implements UserDAO {
    private Connection connection;
 
    public UserDAOImpl(Connection connection) {
        this.connection = connection;
    }
 
    @Override
    public void save(User user) throws SQLException {
        String sql = "INSERT INTO users (name, email) VALUES (?, ?)";
        try (PreparedStatement stmt = connection.prepareStatement(sql)) {
            stmt.setString(1, user.getName());
            stmt.setString(2, user.getEmail());
            stmt.executeUpdate();
        }
    }
 
    @Override
    public User getById(int id) throws SQLException {
        String sql = "SELECT * FROM users WHERE id = ?";
        try (PreparedStatement stmt = connection.prepareStatement(sql)) {
            stmt.setInt(1, id);
            ResultSet rs = stmt.executeQuery();
            if (rs.next()) {
                return new User(rs.getInt("id"), rs.getString("name"), rs.getString("email"));
            }
        }
        return null;
    }
 
    // Other CRUD methods omitted for brevity
}

B. DAO Implementation with ORMs (Hibernate)

Using an ORM like Hibernate simplifies DAO implementation.

public class UserDAOImpl implements UserDAO {
    private SessionFactory sessionFactory;
 
    public UserDAOImpl(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }
 
    @Override
    public void save(User user) {
        Session session = sessionFactory.openSession();
        Transaction tx = session.beginTransaction();
        session.save(user);
        tx.commit();
        session.close();
    }
}

Alternatives to DAO

  • Repository Pattern: Often used in Domain-Driven Design (DDD).
  • Microservices & APIs: Some applications use direct API calls instead of DAOs.
  • Active Record Pattern: Used in frameworks like Rails and Laravel.