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

时间:2013-10-03 08:20:37

标签: java dao

我正在阅读一份文件,我遇到了一个名为DAO的术语。我发现它是一个数据访问对象。有人可以解释一下这究竟是什么吗?

我知道它是某种用于访问来自不同类型来源的数据的界面,在我的这个小小的研究中,我碰到了一个名为数据源或数据源对象的概念,事情搞得一团糟我脑海。

我真的想知道DAO在编程方面的用途。如何使用?任何从基本内容解释这个概念的页面的链接也很受欢迎。

13 个答案:

答案 0 :(得分:387)

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

该定义来自: 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服务器,另一个用于处理平面文件等。

答案 1 :(得分:73)

  

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

对象/接口,用于从数据存储数据库访问数据

  

为什么我们使用DAO:

它抽象了从数据库(如数据库)中检索数据。其概念是&#34;将数据资源的客户端接口与其数据访问机制分开。&#34;

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

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


它全部称为 DAO模式,它由以下内容组成:

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

请查看此示例,这样可以更清楚地清除事情。

Example
我认为这些东西必须在一定程度上清除你对DAO的理解。

答案 2 :(得分:13)

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

DAO Example

请注意,有不同的方法来实现原始DAO Pattern,并且有许多框架可以简化您的工作。例如,像iBatis或Hibernate这样的ORM(对象关系映射)框架用于将SQL查询的结果映射到java对象。

希望它有所帮助, 再见!

答案 3 :(得分:4)

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

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

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

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

示例代码here ..

答案 4 :(得分:4)

不要过多地解释,不要混淆。 DAO:从名称本身来看,它意味着使用Object访问数据。 DAO与其他Business Logics分开。

答案 5 :(得分:3)

我认为你可以在oracle网站上找到最好的例子(以及解释):here。可以找到另一个好的tuturial here

答案 6 :(得分:3)

我将成为一般而不是特定于Java,因为DAO和ORM用于所有语言。

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

type Person {
name
age
}

现在在DAO的帮助下,而不是编写一些特定的查询,来获取所有人,你正在使用的任何类型的数据库(这可能容易出错),而不是:

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

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

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

答案 7 :(得分:1)

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

答案 8 :(得分:1)

DAO就像&#34; Persistence Manager&#34;在3层架构以及DAO也设计模式,因为你可以咨询&#34; Gang of Four&#34;书。 你的应用服务层只需要调用DAO类的方法而不需要知道隐藏&amp; DAO方法的内部细节。

答案 9 :(得分:1)

Spring 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();
    }    
}

答案 10 :(得分:0)

Pojo也被认为是Java中的Model类,我们可以为私有中定义的特定变量创建getter和setter。 请记住,所有变量都在此处使用私有修饰符声明

答案 11 :(得分:0)

Dao clases用于重用jdbc逻辑&amp; Dao(数据访问对象)是一种设计模式。 dao是一个包含JDBC逻辑的简单java类。

数据访问层在单独的业务逻辑层和持久层中证明是好的。 DAO设计模式完全隐藏了客户端的数据访问实现

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

答案 12 :(得分:0)

我只是想用自己在一个项目中遇到的一个小故事用自己的方式来解释它。首先,我想解释 DAO为何重要?,而不是进入什么是DAO?以获得更好的理解。

为什么DAO重要?
在项目的一个项目中,我使用了Client.class,其中包含系统用户的所有基本信息。然后在需要客户端的地方,每次需要在需要的地方进行丑陋查询。然后,我觉得这降低了可读性,并制作了大量多余的样板代码

然后,我的一位高级开发人员介绍了QueryUtils.class,其中所有查询都是使用public static访问修饰符添加的,因此我不需要到处进行查询。假设当我需要激活的客户端时,我只是打电话给-

QueryUtils.findAllActivatedClients();

通过这种方式,我对代码进行了一些优化。

但是还有另一个问题!!!

我觉得QueryUtils.class的增长非常快。该类中包含100多种方法,而且阅读和使用它们也很麻烦。因为此类包含其他域模型(例如产品,类别位置等)的其他查询。

然后是超级英雄先生。 CTO 引入了名为 DAO 的新解决方案,最终解决了该问题。我觉得DAO非常针对特定领域。例如,他创建了一个名为ClientDAO.class的DAO,在其中找到了所有与Client.class相关的查询,这对我来说非常容易使用和维护。巨大的QueryUtils.class被分解为许多其他特定于域的DAO,例如-ProductsDAO.classCategoriesDAO.class等,使代码更可读,更 Maintainable ,更多去耦

什么是DAO?

这是一个对象或接口,它提供了一种轻松的方式来访问数据库中的数据,而无需每次以可重用的方式编写 complex ugly 查询。