Object provides an abstract interface to some type of database or other persistence mechanism.
Real world example
There’s a set of customers that need to be persisted to database. Additionally we need the whole set of CRUD (create/read/update/delete) operations so we can operate on customers easily.
In plain words
DAO is an interface we provide over the base persistence mechanism.
Wikipedia says
In computer software, a data access object (DAO) is a pattern that provides an abstract interface to some type of database or other persistence mechanism.
Programmatic Example
Walking through our customers example, here’s the basic Customer
entity.
1public class Customer {
2
3 private int id;
4 private String firstName;
5 private String lastName;
6
7 public Customer(int id, String firstName, String lastName) {
8 this.id = id;
9 this.firstName = firstName;
10 this.lastName = lastName;
11 }
12 // getters and setters ->
13 ...
14}
Here’s the CustomerDao
interface and two different implementations for it. InMemoryCustomerDao
keeps a simple map of customers in memory while DBCustomerDao
is the real RDBMS implementation.
1public interface CustomerDao {
2
3 Stream<Customer> getAll() throws Exception;
4
5 Optional<Customer> getById(int id) throws Exception;
6
7 boolean add(Customer customer) throws Exception;
8
9 boolean update(Customer customer) throws Exception;
10
11 boolean delete(Customer customer) throws Exception;
12}
13
14public class InMemoryCustomerDao implements CustomerDao {
15
16 private final Map<Integer, Customer> idToCustomer = new HashMap<>();
17
18 // implement the interface using the map
19 ...
20}
21
22@Slf4j
23public class DbCustomerDao implements CustomerDao {
24
25 private final DataSource dataSource;
26
27 public DbCustomerDao(DataSource dataSource) {
28 this.dataSource = dataSource;
29 }
30
31 // implement the interface using the data source
32 ...
Finally here’s how we use our DAO to manage customers.
1 final var dataSource = createDataSource();
2 createSchema(dataSource);
3 final var customerDao = new DbCustomerDao(dataSource);
4
5 addCustomers(customerDao);
6 log.info(ALL_CUSTOMERS);
7 try (var customerStream = customerDao.getAll()) {
8 customerStream.forEach((customer) -> log.info(customer.toString()));
9 }
10 log.info("customerDao.getCustomerById(2): " + customerDao.getById(2));
11 final var customer = new Customer(4, "Dan", "Danson");
12 customerDao.add(customer);
13 log.info(ALL_CUSTOMERS + customerDao.getAll());
14 customer.setFirstName("Daniel");
15 customer.setLastName("Danielson");
16 customerDao.update(customer);
17 log.info(ALL_CUSTOMERS);
18 try (var customerStream = customerDao.getAll()) {
19 customerStream.forEach((cust) -> log.info(cust.toString()));
20 }
21 customerDao.delete(customer);
22 log.info(ALL_CUSTOMERS + customerDao.getAll());
23
24 deleteSchema(dataSource);
The program output:
1customerDao.getAllCustomers():
2Customer{id=1, firstName='Adam', lastName='Adamson'}
3Customer{id=2, firstName='Bob', lastName='Bobson'}
4Customer{id=3, firstName='Carl', lastName='Carlson'}
5customerDao.getCustomerById(2): Optional[Customer{id=2, firstName='Bob', lastName='Bobson'}]
6customerDao.getAllCustomers(): java.util.stream.ReferencePipeline$Head@7cef4e59
7customerDao.getAllCustomers():
8Customer{id=1, firstName='Adam', lastName='Adamson'}
9Customer{id=2, firstName='Bob', lastName='Bobson'}
10Customer{id=3, firstName='Carl', lastName='Carlson'}
11Customer{id=4, firstName='Daniel', lastName='Danielson'}
12customerDao.getAllCustomers(): java.util.stream.ReferencePipeline$Head@2db0f6b2
13customerDao.getAllCustomers():
14Customer{id=1, firstName='Adam', lastName='Adamson'}
15Customer{id=2, firstName='Bob', lastName='Bobson'}
16Customer{id=3, firstName='Carl', lastName='Carlson'}
17customerDao.getCustomerById(2): Optional[Customer{id=2, firstName='Bob', lastName='Bobson'}]
18customerDao.getAllCustomers(): java.util.stream.ReferencePipeline$Head@12c8a2c0
19customerDao.getAllCustomers():
20Customer{id=1, firstName='Adam', lastName='Adamson'}
21Customer{id=2, firstName='Bob', lastName='Bobson'}
22Customer{id=3, firstName='Carl', lastName='Carlson'}
23Customer{id=4, firstName='Daniel', lastName='Danielson'}
24customerDao.getAllCustomers(): java.util.stream.ReferencePipeline$Head@6ec8211c
Use the Data Access Object in any of the following situations: