🔍目的
对象为某种类型的数据库或其他持久性机制提供了抽象接口。
🔍解释
真实世界例子
有一组客户数据需要持久化到数据库中。 我们需要整个额外的增删改查操作以便操作客户数据。
通俗描述
DAO是我们通过基本持久性机制提供的接口。
维基百科
在计算机软件中,数据访问对象(DAO)是一种模式,可为某种类型的数据库或其他持久性机制提供抽象接口。
程序示例
创建客户实体:
public class Customer {private int id;private String firstName;private String lastName;public Customer(int id, String firstName, String lastName) {this.id = id;this.firstName = firstName;this.lastName = lastName;}// getters and setters ->...
}
创建CustomerDao
接口及其两个不同的实现。
public interface CustomerDao {Stream<Customer> getAll() throws Exception;Optional<Customer> getById(int id) throws Exception;boolean add(Customer customer) throws Exception;boolean update(Customer customer) throws Exception;boolean delete(Customer customer) throws Exception;
}public class InMemoryCustomerDao implements CustomerDao {private final Map<Integer, Customer> idToCustomer = new HashMap<>();// implement the interface using the map...
}public class DbCustomerDao implements CustomerDao {private static final Logger LOGGER = LoggerFactory.getLogger(DbCustomerDao.class);private final DataSource dataSource;public DbCustomerDao(DataSource dataSource) {this.dataSource = dataSource;}// implement the interface using the data source...
使用DAO管理客户数据的方式:
final var dataSource = createDataSource();createSchema(dataSource);final var customerDao = new DbCustomerDao(dataSource);addCustomers(customerDao);log.info(ALL_CUSTOMERS);try (var customerStream = customerDao.getAll()) {customerStream.forEach((customer) -> log.info(customer.toString()));}log.info("customerDao.getCustomerById(2): " + customerDao.getById(2));final var customer = new Customer(4, "Dan", "Danson");customerDao.add(customer);log.info(ALL_CUSTOMERS + customerDao.getAll());customer.setFirstName("Daniel");customer.setLastName("Danielson");customerDao.update(customer);log.info(ALL_CUSTOMERS);try (var customerStream = customerDao.getAll()) {customerStream.forEach((cust) -> log.info(cust.toString()));}customerDao.delete(customer);log.info(ALL_CUSTOMERS + customerDao.getAll());deleteSchema(dataSource);
程序输出:
customerDao.getAllCustomers():
Customer{id=1, firstName='Adam', lastName='Adamson'}
Customer{id=2, firstName='Bob', lastName='Bobson'}
Customer{id=3, firstName='Carl', lastName='Carlson'}
customerDao.getCustomerById(2): Optional[Customer{id=2, firstName='Bob', lastName='Bobson'}]
customerDao.getAllCustomers(): java.util.stream.ReferencePipeline$Head@7cef4e59
customerDao.getAllCustomers():
Customer{id=1, firstName='Adam', lastName='Adamson'}
Customer{id=2, firstName='Bob', lastName='Bobson'}
Customer{id=3, firstName='Carl', lastName='Carlson'}
Customer{id=4, firstName='Daniel', lastName='Danielson'}
customerDao.getAllCustomers(): java.util.stream.ReferencePipeline$Head@2db0f6b2
customerDao.getAllCustomers():
Customer{id=1, firstName='Adam', lastName='Adamson'}
Customer{id=2, firstName='Bob', lastName='Bobson'}
Customer{id=3, firstName='Carl', lastName='Carlson'}
customerDao.getCustomerById(2): Optional[Customer{id=2, firstName='Bob', lastName='Bobson'}]
customerDao.getAllCustomers(): java.util.stream.ReferencePipeline$Head@12c8a2c0
customerDao.getAllCustomers():
Customer{id=1, firstName='Adam', lastName='Adamson'}
Customer{id=2, firstName='Bob', lastName='Bobson'}
Customer{id=3, firstName='Carl', lastName='Carlson'}
Customer{id=4, firstName='Daniel', lastName='Danielson'}
customerDao.getAllCustomers(): java.util.stream.ReferencePipeline$Head@6ec8211c
🔍类图
🔍适用场景
在以下情况下,请使用数据访问对象::
- 当您要巩固如何访问数据层时。
- 当您要避免编写多个数据检索/持久层时。