迹忆客 专注技术分享

当前位置:主页 > 学无止境 > 编程语言 > Java >

Java 中存储库模式和 DAO 之间的区别

作者:迹忆客 最近更新:2023/09/28 浏览次数:

今天,我们将了解数据访问对象 (DAO) 和存储库模式。本文还介绍了它们之间的差异。


数据访问对象模式

这种模式是数据持久化的抽象,也被认为更接近底层存储,主要以表为中心。这就是为什么在大多数情况下,数据访问对象 (DAO) 与数据库表相匹配,从而允许最直接的方法从存储中检索和发送数据,同时隐藏丑陋的查询。


存储库模式

存储库模式是从我们的应用程序中检索存储数据的过程,它隐藏了数据存储系统的各个方面。以下是存储库界面,可让我们通过其 username 查找一个 User

interface UserRepository {
    User findUserByUsername( Username name );
}

这可以基于我们的存储技术进行一个或多个实施,例如 MySQL、Amazon DynamoDB、Web Service、Oracle 或其他。

我们也可以说存储库模式是一种将数据源与应用程序的其余部分隔离开来的设计模式。存储库在数据源(例如 Web 服务和持久模型)和应用程序的其余部分之间进行调解。

以下是存储库模式使用的图形表示。

java 中 repository 模式和 dao 的区别——repository 可视化

你理解正确,存储库类似于 Data Access Object (DAO),但它是一种抽象,它隐藏了用于从业务逻辑中检索数据的所有逻辑。

它的行为类似于模型的包装器,负责从持久存储中访问数据。使用存储库的好处是它将我们的东西如何存储的精确细节与使用它的应用程序分开。

这对于测试非常重要,因为我们可以编写总是返回一个用户但不访问数据库的存根代码。它使我们摆脱了各种问题,让我们可以为我们的应用程序代码编写快速的单元测试,这将不依赖于存储的数据。


Java 中数据访问对象 (DAO) 和存储库模式之间的区别

主要区别在于存储库仅返回调用层可以理解的对象。大多数情况下,存储库由业务层使用,因此它输出业务对象。

另一方面,数据访问对象返回可能/可能不是整个业务对象的数据。这意味着数据不是有效的业务概念。

如果我们的业务对象只是数据结构,那么它可以暗示我们有建模问题。这意味着糟糕的设计,而至少正确封装对象的存储库将更有意义。

如果我们只是加载或保存数据结构,那么很可能我们不需要存储库。对象关系映射(ORM)就足够了。

如果我们必须处理由各种其他对象(聚合)组成的业务对象,并且该特定对象要求其所有部分保持一致(聚合根),存储库模式是最佳解决方案。

这是因为它抽象了完整的持久性信息。我们的应用程序只要求一个产品,并且存储库将其作为一个整体返回;恢复对象需要多少查询/表并不重要。

请记住,业务对象不是对象关系映射 (ORM) 实体。这可能是从技术的角度来看,但考虑到设计,一个模型是业务的东西,另一个模型是持久性的东西。

大多数时候,没有直接的兼容性。

以下是我们更喜欢使用存储库模式的一些情况:

  • 它用于我们有许多繁重查询的系统中。
  • 我们使用存储库模式来避免重复查询。
  • 它用于数据存储和域(实体)之间。
  • 它还用于使用为其创建存储库的实体规范搜索和删除元素。

现在,让我们通过代码实现来了解这种差异。


DAO 和存储库模式实现之间的区别

让我们从数据访问对象模式的实现开始。

数据访问对象模式实现

在这里,我们需要有下面列出的三个类:

  1. 一个基本的 Employee 域类
  2. EmployeeDAO 接口,为 Employee 域提供简单的 CRUD 操作
  3. 实现 EmployeeDAO 接口的 EmployeeDAOImplementation

示例代码(员工类):

public class Employee {
    private Long id;
    private String employeeCode;
    private String firstName;
    private String email;

    // write your getters/setters
}

示例代码(EmployeeDAO 接口):

public interface EmployeeDAO {
    void create(Employee employee);
    Employee read(Long id);
    void update(Employee employee);
    void delete(String employeeCode);
}

示例代码(EmployeeDAOImplementation 类):

public class EmployeeDAOImplementation implements EmployeeDAO {
    private final EntityManager entityManager;

    @Override
    public void create(Employee employee) {
        entityManager.persist(employee);
    }

    @Override
    public Employee read(long id) {
        return entityManager.find(Employee.class, id);
    }

    // ... continue with remaining code
}

我们正在使用 JPA EntityManager Interface 与底层存储进行通信。此外,为 Employee 域提供数据访问机制。

存储库模式实现

该模式封装了存储、搜索行为和检索,模拟了对象的集合。与 DAO 一样,它也隐藏查询和处理数据,但位于更接近应用程序业务逻辑的更高级别。

存储库也可以使用 DAO 从数据库中获取数据。此外,它可以填充域对象或从域准备数据,然后使用 DAO 将其发送到存储系统以进行持久性。

在这里,我们需要以下类:

  1. EmployeeRepository 接口
  2. EmployeeRepositoryImplementation

示例代码(EmployeeRepository 接口):

public interface EmployeeRepository {
    Employee get(Long id);
    void add(Employee employee);
    void update(Employee employee);
    void remove(Employee employee);
}

示例代码(EmployeeRepositoryImplementation 类):

public class EmployeeRepositoryImplementation implements EmployeeRepository {
    private EmployeeDAOImplementation employeeDAOImplementation;

    @Override
    public Employee get(Long id) {
        Employee employee = employeeDAOImplementation.read(id);
        return employee;
    }

    @Override
    public void add(Employee employee) {
        employeeDAOImplementation.create(employee);
    }

    // ... continue with remaining code
}

在这里,我们使用 EmployeeDAOImplementation 从数据库中检索/发送数据。所以,我们可以说存储库的实现和 DAO 看起来很相似。

这是因为 Employee 类是贫血领域,而存储库只是数据访问层 (DAO) 之上的另一层;但是,存储库是实现业务用例的最佳方式。相比之下,数据访问对象看起来很适合访问数据。

转载请发邮件至 1244347461@qq.com 进行申请,经作者同意之后,转载请以链接形式注明出处

本文地址:

相关文章

如何在 Java 中延迟几秒钟的时间

发布时间:2023/12/17 浏览次数:217 分类:Java

本篇文章主要介绍如何在 Java 中制造程序延迟。本教程介绍了如何在 Java 中制造程序延时,并列举了一些示例代码来了解它。

如何在 Java 中把 Hashmap 转换为 JSON 对象

发布时间:2023/12/17 浏览次数:187 分类:Java

它描述了允许我们将哈希图转换为简单的 JSON 对象的方法。本文介绍了在 Java 中把 Hashmap 转换为 JSON 对象的方法。我们将看到关于创建一个 hashmap,然后将其转换为 JSON 对象的详细例子。

如何在 Java 中按值排序 Map

发布时间:2023/12/17 浏览次数:171 分类:Java

本文介绍了如何在 Java 中按值对 Map 进行排序。本教程介绍了如何在 Java 中按值对 Map 进行排序,并列出了一些示例代码来理解它。

如何在 Java 中打印 HashMap

发布时间:2023/12/17 浏览次数:192 分类:Java

本帖介绍了如何在 Java 中打印 HashMap。本教程介绍了如何在 Java 中打印 HashMap 元素,还列举了一些示例代码来理解这个主题。

在 Java 中更新 Hashmap 的值

发布时间:2023/12/17 浏览次数:146 分类:Java

本文介绍了如何在 Java 中更新 HashMap 中的一个值。本文介绍了如何在 Java 中使用 HashMap 类中包含的两个方法-put() 和 replace() 更新 HashMap 中的值。

Java 中的 hashmap 和 map 之间的区别

发布时间:2023/12/17 浏览次数:79 分类:Java

本文介绍了 Java 中的 hashmap 和 map 接口之间的区别。本教程介绍了 Java 中 Map 和 HashMap 之间的主要区别。在 Java 中,Map 是用于以键值对存储数据的接口,

在 Java 中获取用户主目录

发布时间:2023/12/17 浏览次数:218 分类:Java

这篇文章向你展示了如何在 Java 中获取用户主目录。本教程介绍了如何在 Java 中获取用户主目录,并列出了一些示例代码以指导你完成该主题。

Java 中 size 和 length 的区别

发布时间:2023/12/17 浏览次数:179 分类:Java

这篇文章教你如何知道 Java 中大小和长度之间的区别。本教程介绍了 Java 中大小和长度之间的区别。我们还列出了一些示例代码以帮助你理解该主题。

Java 中的互斥锁

发布时间:2023/12/17 浏览次数:111 分类:Java

了解有关 Java 中互斥锁的一切,在计算机科学领域,互斥或互斥被称为并发控制的属性。每台计算机都使用称为线程的最小程序指令序列。有一次,计算机在一个线程上工作。为了更好地理解,

扫一扫阅读全部技术教程

社交账号
  • https://www.github.com/onmpw
  • qq:1244347461

最新推荐

教程更新

热门标签

扫码一下
查看教程更方便