DAO · Data Access Object
Spring Concepts / DAO · Data Access Object
A DAO is a component that reads and writes persistent data. Its interface declares the available operations; an implementation class contains the code that performs them.
Understand the idea
DAO names an architectural responsibility, not a special Java keyword. A service asks for data operations through a DAO. The DAO talks to a database using JDBC, MongoTemplate, or another persistence API. Separating these responsibilities keeps HTTP handling and business rules away from database-specific details.
A concrete example
Browser → Controller → Service → DAO → Database
TodoDao dao = new MongoTodoDao(mongoTemplate);
// Declared type: TodoDao interface
// Actual object: MongoTodoDao implementation classIn the application
The Spring Boot labs use TodoRepository extends MongoRepository<Todo, String> for database access. This fills the data-access role; the labs do not require an extra hand-written DAO layer. The Servlet/JSP introduction stores todos in the browser session and has no database DAO.
An ordinary DAO interface does not produce database code by itself. Java cannot instantiate an interface with new TodoDao(). With a custom DAO, provide a class that implements it. Spring Data repository interfaces are a separate framework feature that supplies a runtime implementation.
Stage 10 versus Stage 11: repository and DAO
The product repository fulfills the DAO responsibility: it gives ProductService methods for accessing stored products. DAO emphasizes data access; a repository presents operations on application objects. These related ideas do not require two separate layers in this example.
In Stage 10 we write FileProductRepository, including its findAll() and findById() method bodies. In Stage 11 ProductRepository extends MongoRepository<Product, Integer>. Spring Data creates the repository implementation at startup; Spring injects that object into ProductService. Product is the handled Java type and Integer is its ID type.
| Stage | Actual data-access object | Implementation supplied by |
|---|---|---|
| 10 | FileProductRepository | Our Java code |
| 11 | Spring Data repository implementing ProductRepository | Spring Data MongoDB |
// Stage 11: interface declaration
public interface ProductRepository
extends MongoRepository<Product, Integer> {
}
// Calls made by ProductService
repository.findAll();
repository.findById(1);Two findAll methods with different responsibilities
ProductService.findAll(boolean inStockOnly) is our own Java method. It calls repository.findAll() to obtain the products, then applies our stock rule. Spring Data supplies the inherited repository operation; it does not invent or implement our business rule.
An arbitrary DAO interface cannot implement itself. @Repository alone does not write method bodies. Stage 11 works because MongoRepository is a supported Spring Data repository interface. No extra hand-written ProductDao is required.
Interface versus implementation: where each belongs
Think of the interface as a contract: WHAT operations are available. The implementation class supplies HOW those operations work. A service field uses the interface type, while the object assigned to that field is an implementation instance.
| Place | Example | Purpose |
|---|---|---|
| Contract | TodoDao interface | Declare findById and save. |
| Database layer | MongoTodoDao implements TodoDao | Call MongoDB through MongoTemplate. |
| Business layer | TodoDao field in a service | Use the contract without choosing the database code. |
| Object assembly | Spring configuration or new MongoTodoDao(...) | Provide an actual implementation object. |
1. TodoDao.java — declare the contract
Illustrative alternative for a Spring Boot MongoDB project using the existing com.example.todo.Todo model. Each block below is a separate Java file. These are not files to paste into the Servlet-only starter.
package com.example.todo;
import java.util.Optional;
public interface TodoDao {
Optional<Todo> findById(String id);
Todo save(Todo todo);
}2. MongoTodoDao.java — implement the database operations
This class implements every method in the contract. MongoTemplate performs the database work. Returning Optional makes the missing-record case explicit. @Repository marks this concrete component for Spring discovery; that annotation does not write these method bodies for you.
package com.example.todo;
import java.util.Optional;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Repository;
@Repository
public class MongoTodoDao implements TodoDao {
private final MongoTemplate mongoTemplate;
public MongoTodoDao(MongoTemplate mongoTemplate) {
this.mongoTemplate = mongoTemplate;
}
@Override
public Optional<Todo> findById(String id) {
return Optional.ofNullable(
mongoTemplate.findById(id, Todo.class));
}
@Override
public Todo save(Todo todo) {
return mongoTemplate.save(todo);
}
}3. DaoTodoService.java — depend on the interface
The service receives TodoDao through its constructor. If MongoTodoDao is the only matching bean in the scanned application, Spring can supply it. If multiple implementations are beans, choose one explicitly with @Qualifier or @Primary.
package com.example.todo;
import java.util.Optional;
import org.springframework.stereotype.Service;
@Service
public class DaoTodoService {
private final TodoDao todoDao;
public DaoTodoService(TodoDao todoDao) {
this.todoDao = todoDao;
}
public Optional<Todo> findById(String id) {
return todoDao.findById(id);
}
}The declared field type is TodoDao. At runtime, that reference can point to a MongoTodoDao object. The service calls findById without containing MongoTemplate calls.
Understand the object reference
In this illustrative assembly snippet, mongoTemplate means an already configured MongoTemplate object:
TodoDao dao = new MongoTodoDao(mongoTemplate);
DaoTodoService service = new DaoTodoService(dao);new creates the concrete class. The interface type limits which operations callers see. In a Spring-managed application, constructor injection assembles this object graph instead of putting these new statements in a controller.
Can a DAO be just a class?
Yes. A small application can use a concrete DAO class directly without a separate interface. An interface is useful when it gives a meaningful boundary, supports another implementation, or helps substitute test data access. It is a design choice, not a rule that every DAO must have two files.
For example, a test can supply an in-memory TodoDao implementation. Switching to a different real database may still require changes to queries, mappings, configuration and behavior; an interface does not make every database interchangeable automatically.
What changes with Spring Data MongoRepository?
In the actual Spring Boot tutorial, use this repository interface rather than adding the illustrative DAO files above:
package com.example.todo;
import org.springframework.data.mongodb.repository.MongoRepository;
public interface TodoRepository
extends MongoRepository<Todo, String> {
}With repository scanning configured, Spring Data supplies the repository implementation at runtime. Common methods include save, findAll, findById and deleteById. An arbitrary interface named TodoDao does not get that behavior. The library-provided repository support is what makes this declaration work.
DAO and Repository: related, not identical
DAO emphasizes persistence operations and database access. Repository is a domain-oriented abstraction for retrieving and storing domain objects. In this course, TodoRepository performs the data-access role, but the two pattern names are not exact synonyms.
Keep the existing repository approach when following the runnable labs. The custom DAO examples explain the interface/class distinction; they are an alternative architecture, not another required layer between every service and repository.
Check your understanding
Which type appears in the service field? TodoDao, the interface. Which class is instantiated? MongoTodoDao. Where is the database call written? In MongoTodoDao. Who supplies the implementation in the repository-based labs? Spring Data.