Open In App

Data Access Object(DAO) Design Pattern

Data Access Object Pattern or DAO pattern is a way of organizing code to handle the communication between your program and a database. It helps keep your code clean and separates the logic for interacting with data from the rest of your application.



1. What is the Data Access Object(DOA) Design Pattern?

The DAO Design Pattern is a way of organizing code to handle the communication between your program and a database.



The DAO (Data Access Object) design pattern is like an architect’s plan for handling data in software. It’s a blueprint that developers use to create a structured and orderly system for getting information from a data source, like a database. Instead of dealing directly with the nitty-gritty details of how data is stored and retrieved, the DAO pattern acts as a guide, abstracting away the complexities and offering a clear way to interact with the data.

2. Functionalities of the Data Access Object(DAO) Design Pattern

Let’s see how DOA pattern allows for effective and consistent interaction with a database while abstracting away the underlying complexities

3. Why do we need the Data Access Object(DOA) Design Pattern?

Let’s understand why we need DOA pattern through an example of an e-commerce application:

Let’s say you are developing an e-commerce application. Throughout your application, there’s a need to interact with a database to handle user information.

Without the DAO pattern, you might find yourself scattering database-related code, Lack of consistency, scalabilty concerns across different parts of your application, where as, with the DAO pattern, we can have a centralized set of methods for handling database operations related to user entities. This approach offers several benefits:

4. What are the Key Components of the Data Access Object Design Pattern?

The DAO pattern helps to achieve separation of concerns, making the code more organized, maintainable, and adaptable to changes in data storage or access logic with the help of below main components:

1. BusinessObject

The BusinessObject represents the data client. It is the object that requires access to the data source to obtain and store data. Business Objects model the core entities in your application and are often used to encapsulate business logic. They may interact with Transfer Objects for data transfer purposes.

2. DataAccessObject

The DataAccessObject is the primary object of this pattern. The DataAccessObject abstracts the underlying data access implementation for the BusinessObject to enable transparent access to the data source. It provides a standardized interface for performing CRUD operations on entities.

In simpler terms ,DAOs encapsulate the database-specific code and allow the rest of the application to interact with data entities without being concerned about how the data is stored or retrieved.

3. DataSource

This represents a data source implementation. The Data Source manages the connection to the underlying database and can be used by the DAOs to obtain connections and execute queries. It abstracts away details like connection pooling, database URL, and credentials.

4. TransferObject

This represents a Transfer Object used as a data carrier. It’s used to transfer data between a client and a server or between different layers of an application. The DataAccessObject may also receive the data from the client in a Transfer Object to update the data in the data source. Transfer Objects help reduce the number of method calls between the client and server by bundling multiple data fields into a single object.

How the components Interact with each other:

5. Implementation of Data Access Object(DAO) Design Pattern in Java

5.1. Problem Statement:

A company is facing challenges in managing the information of its developers. The company needs a systematic approach to store, retrieve, update, and delete developer records efficiently. The current system lacks a structured architecture for handling data access operations, leading to scattered and error-prone code.

5.2. How DOA design pattern will help to solve this problem:

DOA pattern abstracts away the in-memory list of developers and provides a standardized interface for performing operations such as retrieval, update, and deletion. The DAO pattern centralizes all the database-related code in one place.The DAO pattern promotes the separation of concerns by isolating the data access logic from the rest of the application.

5.3. Components of the below code:

  1. Developer Class:
    • Represents a developer with attributes such as name and DeveloperId.
    • Methods include getters and setters for accessing and modifying developer information.
  2. DeveloperDao Interface:
    • The DeveloperDao interface defines a standardized set of methods for common data access operations (e.g., getAllDevelopers, getDeveloper, updateDeveloper, deleteDeveloper).
  3. DeveloperDaoImpl Class:
    • Implements the DeveloperDao interface.
    • Manages a list of developers as an in-memory data store.
    • Provides methods to perform CRUD operations on developer data.
    • Demonstrates the Data Access Object (DAO) pattern.
  4. GFG (Main Class):
    • Contains the main method, serving as the entry point of the program.
    • Instantiates an object of DeveloperDaoImpl, which acts as a concrete implementation of the DeveloperDao interface.
    • Demonstrates the usage of the DAO pattern by retrieving, updating, and printing developer information.

5.4. How components are interacting?

5.5. Below is the java code for the above problem statement:




// Java program to illustrate Data Access Object Pattern
 
// Importing required classes
import java.util.ArrayList;
import java.util.List;
 
// Class 1
// Helper class
class Developer {
 
    private String name;
    private int DeveloperId;
 
    // Constructor of Developer class
    Developer(String name, int DeveloperId)
    {
 
        // This keyword refers to current instance itself
        this.name = name;
        this.DeveloperId = DeveloperId;
    }
 
    // Method 1
    public String getName() { return name; }
 
    // Method 2
    public void setName(String name) { this.name = name; }
 
    // Method 3
    public int getDeveloperId() { return DeveloperId; }
 
    // Method 4
    public void setDeveloperId(int DeveloperId)
    {
        this.DeveloperId = DeveloperId;
    }
}
 
// Interface
interface DeveloperDao {
    public List<Developer> getAllDevelopers();
    public Developer getDeveloper(int DeveloperId);
    public void updateDeveloper(Developer Developer);
    public void deleteDeveloper(Developer Developer);
}
 
// Class 2
// Implementing above defined interface
class DeveloperDaoImpl implements DeveloperDao {
 
    List<Developer> Developers;
 
    // Method 1
    public DeveloperDaoImpl()
    {
        Developers = new ArrayList<Developer>();
        Developer Developer1 = new Developer("Kushagra", 0);
        Developer Developer2 = new Developer("Vikram", 1);
        Developers.add(Developer1);
        Developers.add(Developer2);
    }
 
    // Method 2
    @Override
    public void deleteDeveloper(Developer Developer)
    {
        Developers.remove(Developer.getDeveloperId());
        System.out.println("DeveloperId "
                           + Developer.getDeveloperId()
                           + ", deleted from database");
    }
 
    // Method 3
    @Override public List<Developer> getAllDevelopers()
    {
        return Developers;
    }
 
    // Method 4
    @Override public Developer getDeveloper(int DeveloperId)
    {
        return Developers.get(DeveloperId);
    }
 
    // Method 5
    @Override
    public void updateDeveloper(Developer Developer)
    {
        Developers.get(Developer.getDeveloperId())
            .setName(Developer.getName());
        System.out.println("DeveloperId "
                           + Developer.getDeveloperId()
                           + ", updated in the database");
    }
}
 
// Class 3
// DaoPatternDemo
class GFG {
 
    // Main driver method
    public static void main(String[] args)
    {
 
        DeveloperDao DeveloperDao = new DeveloperDaoImpl();
 
        for (Developer Developer :
             DeveloperDao.getAllDevelopers()) {
            System.out.println("DeveloperId : "
                               + Developer.getDeveloperId()
                               + ", Name : "
                               + Developer.getName());
        }
 
        Developer Developer
            = DeveloperDao.getAllDevelopers().get(0);
 
        Developer.setName("Lokesh");
        DeveloperDao.updateDeveloper(Developer);
 
        DeveloperDao.getDeveloper(0);
        System.out.println(
            "DeveloperId : " + Developer.getDeveloperId()
            + ", Name : " + Developer.getName());
    }
}

Output
DeveloperId : 0, Name : Kushagra
DeveloperId : 1, Name : Vikram
DeveloperId 0, updated in the database
DeveloperId : 0, Name : Lokesh











6. Use Cases of Data Access Object Design Pattern

use cases highlight how the DAO pattern addresses various concerns in software development, including abstraction of data storage, isolation of business logic, support for multiple data sources, enhanced testability, and transaction management.

7. Data Access Object(DAO) Design Pattern with Java Persistence API(JPA)

7.1. What is Java Persistence API(JPA)?

JPA, or Java Persistence API, is a Java specification for managing relational data in Java applications. It provides a standardized way to interact with relational databases using Java objects.

7.2. Why we need JPA with DAO in Java?

Using JPA with the DAO pattern is like having a smart and organized system for dealing with data in Java applications. JPA, the smart part, helps us talk to databases without getting into the nitty-gritty details, while the DAO pattern, the organized part, gives us a clear plan on how to handle data operations.

7.3 Implementation of JPA with DAO in Java?

Let’s create a simple example of using JPA with the DAO pattern in a Spring Boot application. In this example, we’ll have an entity called Product, and we’ll perform basic CRUD operations on it.

1. Entity Class

This class represents a product with an ID, name, and price. The @Entity annotation indicates that this class is a JPA entity, and the @Table annotation specifies the database table name.




import javax.persistence.*;
 
@Entity
@Table(name = "products")
public class Product {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
 
    private String name;
    private double price;
 
    // Getters and setters
}

2. DAO Interface

The ProductDAO interface extends JpaRepository, a Spring Data JPA interface that provides standard CRUD operations. Custom queries or methods can be added as needed.




import org.springframework.data.jpa.repository.JpaRepository;
 
public interface ProductDAO extends JpaRepository<Product, Long> {
    // Additional custom queries or methods can be declared here
}

3. DAO Implementation

No explicit implementation is needed for the DAO interface since Spring Data JPA provides default implementations. However, if you have custom queries or methods, you can create an implementation class.

4. Service Class

The ProductService class contains business logic and interacts with the ProductDAO to perform operations like retrieving all products, getting a product by ID, saving a new product, and deleting a product.




import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
 
import java.util.List;
 
@Service
public class ProductService {
    @Autowired
    private ProductDAO productDAO;
 
    public List<Product> getAllProducts() {
        return productDAO.findAll();
    }
 
    public Product getProductById(Long id) {
        return productDAO.findById(id).orElse(null);
    }
 
    public Product saveProduct(Product product) {
        return productDAO.save(product);
    }
 
    public void deleteProduct(Long id) {
        productDAO.deleteById(id);
    }
}

5. Controller Class

The ProductController class handles HTTP requests and calls the corresponding methods in the ProductService to perform CRUD operations on products.




import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
 
import java.util.List;
 
@RestController
@RequestMapping("/products")
public class ProductController {
    @Autowired
    private ProductService productService;
 
    @GetMapping
    public List<Product> getAllProducts() {
        return productService.getAllProducts();
    }
 
    @GetMapping("/{id}")
    public Product getProductById(@PathVariable Long id) {
        return productService.getProductById(id);
    }
 
    @PostMapping
    public Product saveProduct(@RequestBody Product product) {
        return productService.saveProduct(product);
    }
 
    @DeleteMapping("/{id}")
    public void deleteProduct(@PathVariable Long id) {
        productService.deleteProduct(id);
    }
}

6. Flow Explanation:

8. Advantages of the Data Access Object Design(DAO) Pattern

9. Disadvantages of the Data Access Object Design(DAO) Pattern

10. Conclusion

In simple terms, the Data Access Object (DAO) design pattern is like a helpful blueprint for how software should handle storing and retrieving data. It keeps things organized by putting all the data-related instructions in one place. This makes it easier to take care of data without making a mess in the rest of the software.


Article Tags :