Translation zh (#1646)
* add state and callback pattern * add command and template-method pattern * add iterator pattern * add bridege and DI pattern * fix issue #1600 * add converter,proxy,visitor pattern * add caching,composite,delegation,dirty-flag,interpreter patterns * add dao and producer-consumer * add dto and provate class data pattern * fix #1646 png path problems * fix #1646 composite png path case problem Co-authored-by: Mike <admin@xiaod.info> Co-authored-by: Subhrodip Mohanta <hello@subho.xyz>
This commit is contained in:
162
zh/dao/README.md
Normal file
162
zh/dao/README.md
Normal file
@ -0,0 +1,162 @@
|
||||
---
|
||||
layout: pattern
|
||||
title: Data Access Object
|
||||
folder: dao
|
||||
permalink: /patterns/dao/
|
||||
categories: Architectural
|
||||
tags:
|
||||
- Data access
|
||||
---
|
||||
|
||||
## 目的
|
||||
|
||||
对象为某种类型的数据库或其他持久性机制提供了抽象接口。
|
||||
|
||||
## 解释
|
||||
|
||||
真实世界例子
|
||||
|
||||
> 有一组客户数据需要持久化到数据库中。 我们需要整个额外的增删改查操作以便操作客户数据。
|
||||
|
||||
通俗的说
|
||||
|
||||
> DAO是我们通过基本持久性机制提供的接口。
|
||||
|
||||
维基百科说
|
||||
|
||||
> 在计算机软件中,数据访问对象(DAO)是一种模式,可为某种类型的数据库或其他持久性机制提供抽象接口。
|
||||
|
||||
**程序示例**
|
||||
|
||||
通过我们的客户示例,下面是基本的`客户`实体。
|
||||
|
||||
```java
|
||||
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`接口及其两个不同的实现。
|
||||
|
||||
Here's the `CustomerDao` interface and two different implementations for it. `InMemoryCustomerDao`
|
||||
将简单的客户数据映射保存在内存中 而`DBCustomerDao`是真正的RDBMS实现。
|
||||
|
||||
```java
|
||||
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管理客户数据的方式。
|
||||
|
||||
```java
|
||||
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);
|
||||
```
|
||||
|
||||
程序输出:
|
||||
|
||||
```java
|
||||
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
|
||||
```
|
||||
|
||||
## 类图
|
||||
|
||||

|
||||
|
||||
## 适用性
|
||||
|
||||
在以下情况下,请使用数据访问对象::
|
||||
|
||||
* 当您要巩固如何访问数据层时。
|
||||
* 当您要避免编写多个数据检索/持久层时。
|
||||
|
||||
## 鸣谢
|
||||
|
||||
* [J2EE Design Patterns](https://www.amazon.com/gp/product/0596004273/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596004273&linkCode=as2&tag=javadesignpat-20&linkId=48d37c67fb3d845b802fa9b619ad8f31)
|
Reference in New Issue
Block a user