【发布时间】:2010-12-12 18:02:04
【问题描述】:
我正在开发一个示例 Java 应用程序,该应用程序使用 Oracle 的内置“HR”数据库模式。我想将表行视为 Java 对象。 HR 模式中的一个表 EMPLOYEES 是自引用的。它有一个 MANAGER_ID 列,其中包含(如果不是 NULL)到 EMPLOYEES 表中另一行的外键。
在面向对象的术语中,问题是如何访问给定 Employee 对象的经理(这是另一个 Employee 对象)。急切加载似乎不是一个好的解决方案,因为给定的 Employee 对象的经理也可能有一个经理,等等。在这种情况下急切加载的对象数量是无限的。
到目前为止,我决定做的是在实例化 Employee 对象时急切地加载 MANAGER_ID 字段。然后,当请求 Employee 的经理 Employee 对象时(通过getManager() 方法),后者将被延迟加载。在代码中:
public class Employee
{
private int id;
private int managerId;
private Employee manager;
public int getId()
{
return id;
}
public Employee getManager()
{
if(manager == null && managerId > 0)
{
// Lazy loading!
}
return manager;
}
public void setManager(Employee manager)
{
this.manager = manager;
this.managerId = manager.getId();
}
}
那么这是一个好方法吗?我唯一遇到的问题是如何实现延迟加载。 Employee 对象似乎需要对其实例化器的引用——大概这与实例化其经理 Employee 对象相同。
另外,我知道我可以只使用现有的众多 ORM 框架之一,而不是自己动手,但我自己这样做是为了更深入地了解底层流程。
编辑: 澄清一下,我的这项工作的架构(例如)根本不涉及 Java EE。这是一种 Java SE 架构,其中客户端通过简单的 RMI 与服务器交互。
此外,上面的 Employee 类显然确实需要对 DAO 的引用来执行延迟加载。但是,我认为这不一定是紧密耦合的,因为:
- Employee 对象可以持有对 DAO 实现的抽象接口的引用;和/或
- Employee 对象可以持有对服务器对象的引用,而服务器对象又持有对 DAO 的(私有)引用。
请注意,在 #2 的情况下,Employee 对象引用的服务器对象可能与客户端引用的服务器对象相同。
【问题讨论】:
-
我不明白这里的用例。这看起来不像是自动 ORM,而更像是手动 ORM。我可以告诉你延迟加载是如何在其他 ORM 中实现的,但这是你想要的吗?
-
对不起,我应该更具体。是的,这是一个手动 ORM。我想知道我的延迟加载实现在这种情况下是否有意义。
-
你为什么不简单地将管理器配置为延迟加载?我不会按照你现在的想法去做。另请注意,当您手动进行延迟加载(不使用代理、AOP 或类似的东西)时,您很可能必须包含一个实体管理器或类似的东西才能在您的类中进行实际的延迟加载,将您的模型与您的方式耦合重新从数据库中检索数据。因此,您的方法不再是松散耦合的,除了您将不再拥有简单的 POJO。
-
对不起,“将管理器配置为延迟加载”是什么意思?对于我正在做的事情,它没有使用任何 ORM 框架,只是使用常规 Java 代码,我不明白手动延迟加载和(大概)自动延迟加载之间可能有什么区别。不过,我对这些东西还很陌生,所以我可能遗漏了很多东西。
标签: java object-relational-model