java - 不使用 ORM 实现实体类之间的关系

标签 java database design-patterns dao


我有一些与其他实体具有一对一和/或一对多关系的实体类。

我尝试制作一个非常通用的示例来反射(reflect)我的情况...假设我将以下表存储在数据库中(不允许空值):

   operations (ID, workerID, customerID, etc_etc)
      workers (ID, email, password, etc_etc)
    customers (ID, etc_etc)
 mobilePhones (workerID, phoneNumber)

应该很清楚:

  • 1 运营只有 1 员工和 1 客户。
  • 1 客户至少 1 个手机号码。

因此我有以下实体类:

public class Customer {
    private int id;
    //other fields, then constructors, getters and setters
}

public class Worker {
    private int id;
    //other fields
    private String[] mobilePhones;
}

正如我在标题中已经说过的,我无法使用 Hibernate 等 ORM,所以我将使用 DAO。
{ 编辑:我应该知道你很想知道为什么我不能使用 ORM...好吧,正如我在此处的评论中所写:这是一项作业(软件工程考试的项目)。 }

现在,我想我不会对WorkerDAO有任何问题。 ,可以通过从 mobilePhones 中进行选择来轻松管理一对多关系。所有电话号码 workerID等于实际 worker 的id。

对我来说真正的问题是如何管理 Operation 之间的关系及其同事 WorkerCustomer 。 如果我想避免浪费内存,我应该设计我的 Operation像这样的实体:

public class Operation { // here I have some doubts
    private int id;
    private int workerId;
    private int customerId;
    //other fields
}

或者可能像这样:

public class Operation { // here I have some doubts
    private int id;
    private Worker worker;
    private Customer customer;
    //other fields
}

后者似乎更面向对象,但有一个微不足道的含义:工作人员和客户的实例必须位于内存中,即使 Operation 的客户端也是如此。可能不需要它们。

更糟糕的是:如果 OperationDAO将worker和customer设置为新的Worker和Customer实例,这将导致在内存中保留多个引用同一worker/customer的实例(例如,同一worker执行的两个操作)。 除了浪费内存之外,这肯定会导致数据不一致(例如,修改一个实例而不更新其他实例)。

为了避免这种情况,应该引入一些类来了解当前加载的实例(例如使用 List<Worker>List<Customer> 等)...老实说,在我看来这似乎是一种矫枉过正。

我还认为我可以尝试实现某种延迟获取,例如仅在第一个请求时设置工作实例,但我仍然需要一些类来跟踪内存中的内容以及必须查询的内容;我什至不知道这个类是否应该与数据访问逻辑业务逻辑相关(我猜是前者,但仍然不确定)。

无论如何,没有理由实现这一切,因为我不需要缓存系统(而且我觉得它看起来很像那样)。

有什么建议吗?

最佳答案

您不能使用框架,但可以使用框架本身使用的模式。所以我根据 P of EAA. by Martin Fowler 向您推荐这些解决方案

  1. 您可以使用第一个选项(使用workerId和customerId字段进行操作)并使用 Row Data Gateway对于每个实体(操作、 worker 、客户)。 现在,如果内存是一个问题并且您的模型需要它,请使用 Identity Map 来控制所有 Worker 和 Customer 加载的实例。并避免重新加载。

  2. 您可以使用第二个选项(在操作中拥有工作人员和客户实例)并使用 Table Data GatewayLazy Load仅在需要时加载实例。

担心是否加载多个实例取决于您正在构建的应用程序类型和实例的范围;例如,如果您正在创建基于 CRUD 的应用程序,您的实例通常会有一个请求范围,因此使用第二种方法,不用担心内存浪费或数据不一致。

建议:使用接口(interface)来定义您的类型。

关于java - 不使用 ORM 实现实体类之间的关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12058595/

相关文章:

java - 如何在freemarker中实现BigDecimal渲染的逻辑?

java - 您可以将 GWT 屏幕添加到 Web 应用程序中已有的屏幕吗?

java - 如何在 saucelabs 上的 firefox 浏览器中覆盖 useragent

java - 使用状态模式解耦状态

java - Perl 或 Java 情感分析

php - PHP 变量的值作为 HTML 链接

php - 将简单列表服务器端/差异存储到本地存储

mysql - 检索聚合函数受条件约束的记录

Javascript函数

objective-c - XCode 4 - 创建 AppController 标准?