Open In App

Data Access Object(DAO) Design Pattern

Last Updated : 31 Jan, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

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.

dao

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

  • The DAO pattern abstracts and encapsulates the details of how data is saved, retrieved, updated, or deleted in a database. This abstraction shields the rest of the application from the specific database implementation.
  • It centralizes all database-related code within dedicated DAO classes. This means that the rest of the application doesn’t need to scatter database operations throughout its codebase; instead, it interacts with DAO methods.
  • The DAO pattern promotes code reusability by providing a set of generic methods that can be applied to different entities. As a result, you can use similar database access patterns across various parts of your application.

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:

  • Organization: All database-related code is centralized within the UserDao, making the codebase more organized and easier to navigate.
  • Consistency: The standardized interface (DAO interface) ensures a consistent way of interacting with the database, reducing the likelihood of errors due to different approaches.
  • Maintenance Simplicity: Changes to the database structure or technology can be implemented in the UserDaoImpl class, minimizing the impact on the rest of the application.
  • Testing Facilitation: Unit testing becomes more straightforward since there’s a clear set of methods to test within the UserDao.
  • Scalability: As the application grows, new DAO interfaces and implementations can be added, ensuring a scalable and maintainable architecture.

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:

  • The Business Object encapsulates the core business logic and interacts with the Transfer Object for data transfer purposes.
  • The DAO interacts with both the Business Object and the Transfer Object. It uses the Transfer Object for passing data to and from the database and may work with Business Objects to convert between the data transfer format and the application’s internal representation.
  • The Data Source is used by the DAO to obtain database connections needed for executing queries and updates.

Components-of-Data-Access-Object-Pattern-(1)

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?

  • The GFG class interacts with the DeveloperDao interface and its implementation (DeveloperDaoImpl).
  • DeveloperDaoImpl manages the in-memory list of developers and provides methods to perform CRUD operations.
  • The GFG class demonstrates the usage of the DAO pattern by calling methods on the DeveloperDao interface to retrieve, update, and print developer information.

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

Java




// 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.

  • Web application
    • In a web application, data is stored in a relational database. The DAO pattern abstracts the details of database interactions, providing a standardized interface. This abstraction allows the application to work with entities and their relationships without being concerned about the specific database vendor or SQL syntax.
  • E-commerce platform
    • An e-commerce platform has complex business logic for processing orders. The DAO pattern is employed to isolate the data access operations related to order management. By encapsulating database interactions within DAO classes, the business logic remains focused on order processing without being cluttered by low-level data access details.
  • Mobile application
    • A mobile application needs to fetch user data from both a local SQLite database and a remote REST API. The DAO pattern is adapted to have different implementations for local and remote data access. This allows the application to seamlessly switch between data sources based on network availability or other factors.
  • Healthcare application
    • A healthcare application manages patient records stored in a MongoDB database. By employing the DAO pattern, the application separates the data access logic into DAO classes. This facilitates unit testing by allowing developers to use mock DAO implementations during testing, ensuring that the business logic is tested independently of the actual database.
  • Transaction Management:
    • Transferring funds between accounts involves multiple database operations. The DAO pattern is extended to handle transactions, ensuring that these operations are atomic. If any part of the fund transfer fails, the entire transaction is rolled back, maintaining the consistency of the data.

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.

  • JPA allows developers to map Java classes to database tables, define relationships between entities, and perform common database operations (such as CRUD: Create, Read, Update, Delete) using a set of Java annotations and APIs.
  • It abstracts the details of the underlying database and provides a high-level, object-oriented interface for database operations, making it easier for developers to work with databases in their Java applications.

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.

  • Imagine JPA as a helpful translator between Java objects and databases. It understands both languages, making it easier for our Java code to talk to the database.
  • Now, add the DAO pattern to the mix, and it’s like having a well-structured playbook on how to interact with data. The DAO pattern keeps things neat and tidy, making sure our data tasks are handled in an organized way.
  • This combo of JPA and the DAO pattern is widely used in Java development, especially in big applications and popular frameworks like Spring.
  • It makes our code more modular and easy to maintain, like having a reliable system to manage all our data-related activities without chaos.

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.

Java




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.

Java




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.

Java




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.

Java




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:

  • Request from Client: A client (e.g., a web browser or another application) sends an HTTP request to the /products endpoint.
  • Controller Processing: The ProductController processes the request based on the HTTP method (GET, POST, DELETE) and delegates the work to the ProductService.
  • Service Layer: The ProductService contains the business logic and interacts with the ProductDAO for data access operations.
  • Data Access: The ProductDAO (thanks to Spring Data JPA) provides default methods for CRUD operations, and custom queries can be added if needed.
  • Database Interaction: JPA translates the Java objects (e.g., Product entities) into SQL queries to interact with the underlying database.
  • Response to Client: The result is sent back as an HTTP response to the client, containing the requested data or an acknowledgment of the operation.

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

  • Abstraction and Encapsulation:
    • The DAO pattern abstracts the details of data access and encapsulates them within dedicated DAO classes. This abstraction shields the rest of the application from the complexities of database interactions, providing a clean and simplified interface for accessing data.
  • Centralized Data Access Logic:
    • By centralizing data access logic in DAO classes, the code becomes more organized and maintainable. Changes to the data access code are localized, reducing the risk of errors and making it easier to implement modifications or updates.
  • Flexibility and Adaptability:
    • The DAO pattern enhances flexibility by allowing for changes in the underlying data source without affecting the rest of the application. For example, switching from one database system to another can be achieved by modifying the DAO implementations while keeping the client code unchanged.
  • Enhanced Testability:
    • The separation of concerns achieved through the DAO pattern improves testability. Unit testing becomes more straightforward as developers can easily create mock DAO implementations for testing the application’s business logic without the need for an actual database connection.
  • Security and Validation:
    • DAO classes provide a centralized location to implement security measures and data validation. Input parameters can be validated before executing database operations, reducing the risk of SQL injection attacks. Security-related concerns can be addressed consistently across the application.

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

  • Increased Complexity for Simple Applications:
    • For simple applications with limited data access requirements, implementing the DAO pattern might introduce unnecessary complexity. In such cases, the overhead of creating DAO interfaces and classes could outweigh the benefits.
  • Potential for Code Duplication:
    • If the application works with multiple entities, each requiring its own DAO, there is a risk of code duplication. Each DAO may have similar boilerplate code for CRUD operations, leading to maintenance challenges and potential inconsistencies.
  • Learning Curve for Developers:
    • Developers unfamiliar with the DAO pattern may face a learning curve when adapting to its principles. Understanding the abstraction layers and designing effective DAO interfaces can be challenging for those new to the pattern.
  • Overhead in Small Projects:
    • In small projects or prototypes where the data access requirements are minimal, implementing the DAO pattern might introduce unnecessary overhead. The additional layers of abstraction may be perceived as cumbersome for projects with straightforward data access needs.
  • Performance Overhead:
    • Depending on the implementation, the DAO pattern can introduce a slight performance overhead. The additional layer of abstraction might incur additional method invocations and object creations, impacting performance in high-throughput scenarios. Careful design and optimization are necessary to mitigate this drawback.

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.



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads