Java中的数据访问对象(DAO)


347

我正在浏览一个文档,遇到了一个名为的术语DAO。我发现它是一个数据访问对象。有人可以解释一下这到底是什么吗?

我知道这是一种用于从不同类型的源访问数据的接口,在我的这项小小的研究中,我碰到了一个称为数据源或数据源对象的概念,然后我脑子里一团糟。

我真的很想知道a DAO的编程含义。如何使用?任何从最基本的东西解释这个概念的页面的链接也将受到赞赏。

Answers:


447

数据访问对象基本上是提供对基础数据库或任何其他持久性存储的访问的对象或接口。

该定义来自:http : //en.wikipedia.org/wiki/Data_access_object

在此处也检查序列图:http : //www.oracle.com/technetwork/java/dataaccessobject-138824.html

也许一个简单的示例可以帮助您理解概念:

假设我们有一个代表员工的实体:

public class Employee {

    private int id;
    private String name;


    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }

}

雇员实体将被持久保存到Employee数据库中的相应表中。一个简单的DAO接口可以处理操作雇员实体所需的数据库操作,如下所示:

interface EmployeeDAO {

    List<Employee> findAll();
    List<Employee> findById();
    List<Employee> findByName();
    boolean insertEmployee(Employee employee);
    boolean updateEmployee(Employee employee);
    boolean deleteEmployee(Employee employee);

}

接下来,我们必须为该接口提供一个具体的实现以处理SQL Server,并提供另一个实现以处理平面文件等。


4
嗨,拉米,我非常高兴您尝试用一个非常简单的示例来解释我,这正是我所需要的。您能解释一下“具体实现”一词的意思吗?您是说我们接下来必须通过实现类的接口来编写方法的定义。
Vasanth Nag KV

恩,那就对了。就像名为EmployeeSQLServerDAO的类一样,它通过以与SQL Server相关的方式为其方法提供完整的实现来实现EmployeeDAO接口
Rami

4
所以这就是DAO的全部吗?这只是我们正在编写的用于访问数据库的类。每当我们需要数据库中的服务时,我们都会创建一个DAO对象,将其用于数据库操作,然后从数据库中获得所需的DAO后就将其删除。我对吗??我可以知道这个DAO概念rami的范围吗?
Vasanth Nag KV

5
是的,DAO顾名思义是用于访问/更新有关某个实体/类的基础存储。因此,在上面的示例中,我们有一个雇员类/实体,我们使用SQL Server数据库表来保留该雇员/实体。员工DAO将包含用于插入/删除/更新/选择员工的方法
拉米

2
@PhilipRego我们当然可以有多种实现,例如MSSQL服务器实现,以及另一种使用CSV文件与单元测试一起使用的实现。
拉米

86

什么是数据访问对象(DAO) -

它是一个对象/接口,用于访问数据存储数据库中的数据。

为什么使用DAO:

它抽象了从数据库等数据资源中检索数据的方法。概念是“将数据资源的客户端接口与其数据访问机制分开”。

直接访问数据的问题是数据源可以更改。例如,考虑将您的应用程序部署在访问Oracle数据库的环境中。然后将其部署到使用Microsoft SQL Server的环境中。如果您的应用程序使用存储过程和特定于数据库的代码(例如生成数字序列),那么如何在应用程序中处理这些代码?您有两种选择:

  • 重写您的应用程序以使用SQL Server代替Oracle(或添加条件代码来处理差异),或者
  • 在应用程序逻辑和数据访问之间创建一个层


它的整体称为DAO模式,由以下部分组成:

  • 数据访问对象接口 -此接口定义要在模型对象上执行的标准操作
  • 数据访问对象具体类 -此类实现上述接口。此类负责从可以是数据库/ xml或任何其他存储机制的数据源获取数据
  • 模型对象或值对象 -此对象是简单的POJO,其中包含用于存储使用DAO类检索的数据的get / set方法

请检查此示例,这将使清除内容更加清晰。

示例
我假设这件事一定程度上已经清除了您对DAO的理解。


13

DAO(数据访问对象)是企业应用程序中非常常用的设计模式。它基本上是用于从每个源(DBMS,XML等)访问数据的模块。我建议您阅读一些示例,例如:

DAO示例

请注意,有多种方法可以实现原始DAO模式,并且有许多框架可以简化您的工作。例如,诸如iBatis或Hibernate之类的ORM(对象关系映射)框架用于将SQL查询的结果映射到java对象。

希望能有所帮助,再见!


8

数据访问对象模式或DAO模式用于将底层数据访问API或操作与高层业务服务分开。以下是数据访问对象模式的参与者。

数据访问对象接口-此接口定义要在模型对象上执行的标准操作。

数据访问对象具体类-此类实现上述接口。此类负责从可以是数据库/ xml或任何其他存储机制的数据源获取数据。

模型对象或值对象-此对象是简单的POJO,其中包含用于存储使用DAO类检索的数据的get / set方法。

示例代码在这里 ..


7

我将是通用的,而不是特定于Java的,因为所有语言都使用DAO和ORM。

要了解DAO,您首先需要了解ORM(对象有理映射)。这意味着,如果您有一个名为“ person”的表,其中包含“ name”和“ age”列,那么您将为该表创建对象模板:

type Person {
name
age
}

现在,在DAO的帮助下,而不是编写一些特定的查询来获取所有人,无论您使用哪种类型的db(可能容易出错),您都可以这样做:

list persons = DAO.getPersons();
...
person = DAO.getPersonWithName("John");
age = person.age;

您不必自己编写DAO抽象,它通常是某些开源项目的一部分,具体取决于您使用的语言和框架。

现在到这里的主要问题。“ ..使用它的地方.. ”。通常,如果您正在编写复杂的业务和特定于域的代码,那么如果没有DAO,您的生活将非常困难。当然,您不需要使用提供的ORM和DAO,而是可以编写自己的抽象和本机查询。我过去曾经这样做,后来几乎总是后悔。


6

我认为最好的例子(连同解释)可以在oracle网站上找到:here。在这里可以找到另一种很好的教学方法。


2
是我还是大多数Java教程和信息站点都过时了?该教程来自2008年!有关Java主题的许多顶级搜索结果甚至更旧。
bergie3000 '16

2
@ bergie3000:这种模式不是新的。
砰力丸

5

不要对太多的解释感到困惑。DAO:从名称本身来说,它意味着使用对象访问数据。DAO与其他业务逻辑分开。


4

数据访问对象管理与数据源的连接以获取和存储数据,它抽象化业务对象的基础数据访问实现以实现对数据源的透明访问。数据源可以是任何数据库,例如RDBMS,XML存储库或平面文件系统等。


4

春季JPA DAO

例如,我们有一些实体组。

我们为此实体创建存储库GroupRepository。

public interface GroupRepository extends JpaRepository<Group, Long> {   
}

然后,我们需要创建一个服务层,将使用它来使用此存储库。

public interface Service<T, ID> {

    T save(T entity);

    void deleteById(ID id);

    List<T> findAll();

    T getOne(ID id);

    T editEntity(T entity);

    Optional<T> findById(ID id);
}

public abstract class AbstractService<T, ID, R extends JpaRepository<T, ID>> implements Service<T, ID> {

    private final R repository;

    protected AbstractService(R repository) {
        this.repository = repository;
    }

    @Override
    public T save(T entity) {
        return repository.save(entity);
    }

    @Override
    public void deleteById(ID id) {
        repository.deleteById(id);
    }

    @Override
    public List<T> findAll() {
        return repository.findAll();
    }

    @Override
    public T getOne(ID id) {
        return repository.getOne(id);
    }

    @Override
    public Optional<T> findById(ID id) {
        return repository.findById(id);
    }

    @Override
    public T editEntity(T entity) {
        return repository.saveAndFlush(entity);
    }
}

@org.springframework.stereotype.Service
public class GroupServiceImpl extends AbstractService<Group, Long, GroupRepository> {

    private final GroupRepository groupRepository;

    @Autowired
    protected GroupServiceImpl(GroupRepository repository) {
        super(repository);
        this.groupRepository = repository;
    }
}

在控制器中,我们使用此服务。

@RestController
@RequestMapping("/api")
class GroupController {

    private final Logger log = LoggerFactory.getLogger(GroupController.class);

    private final GroupServiceImpl groupService;

    @Autowired
    public GroupController(GroupServiceImpl groupService) {
        this.groupService = groupService;
    }

    @GetMapping("/groups")
    Collection<Group> groups() {
        return groupService.findAll();
    }

    @GetMapping("/group/{id}")
    ResponseEntity<?> getGroup(@PathVariable Long id) {
        Optional<Group> group = groupService.findById(id);
        return group.map(response -> ResponseEntity.ok().body(response))
                .orElse(new ResponseEntity<>(HttpStatus.NOT_FOUND));
    }

    @PostMapping("/group")
    ResponseEntity<Group> createGroup(@Valid @RequestBody Group group) throws URISyntaxException {
        log.info("Request to create group: {}", group);
        Group result = groupService.save(group);
        return ResponseEntity.created(new URI("/api/group/" + result.getId()))
                .body(result);
    }

    @PutMapping("/group")
    ResponseEntity<Group> updateGroup(@Valid @RequestBody Group group) {
        log.info("Request to update group: {}", group);
        Group result = groupService.save(group);
        return ResponseEntity.ok().body(result);
    }

    @DeleteMapping("/group/{id}")
    public ResponseEntity<?> deleteGroup(@PathVariable Long id) {
        log.info("Request to delete group: {}", id);
        groupService.deleteById(id);
        return ResponseEntity.ok().build();
    }    
}

这似乎是在解释存储库模式,而不是按照原始作者的要求解释DAO模式。另外,我相信您的示例可能会误导您,因为您的界面应遵循类似集合的方法,因此某些操作不适合。
Jan Haesen

2

DAO就像3层体系结构中的“持久性管理器”一样,DAO也设计模式,您可以参考“四人帮”一书。您的应用程序服务层只需要调用DAO类的方法,而无需了解DAO方法的隐藏和内部细节。


2

Dao clase用于重用jdbc逻辑&Dao(数据访问对象)是一种设计模式。dao是一个简单的Java类,其中包含JDBC逻辑。

事实证明,数据访问层在单独的业务逻辑层和持久层中表现出色。DAO设计模式从其客户端完全隐藏了数据访问实现

Java数据访问对象(Java DAO)是业务应用程序中的重要组件。业务应用程序几乎总是需要访问关系数据库或对象数据库中的数据,而Java平台提供了许多访问此数据的技术。最古老和最成熟的技术是使用Java数据库连接(JDBC)API,该API提供了对数据库执行SQL查询然后一次获取结果的功能。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.