跳转到内容

WebObjects/EOF/使用 EOF

来自维基教科书,开放世界中的开放书籍

Jerry W. Walker

[编辑 | 编辑源代码]

我本来很想像 Kieren 一样回复,但我理解在开始时 WebObjects 可能是多么令人生畏。Kieren 的建议很好,请使用它。但也许以下内容也会有所帮助。

首先:我需要一些认真的帮助。一旦我使用 fetch 命令将数据库中的一行作为对象引入,这工作正常,我如何访问对象中的单元格?

在早期的项目中,你可能会使用 EOUtilities 及其快捷方式来执行你的提取操作。但让我回到基础,这样你就可以在 API 参考中查找类名。

在基本级别上,你需要定义或引用 7 个对象才能从你的关系数据库中获取数据

  • 一个 EOModel,它将你的关系表、行和列映射到 Java 类、实例和属性。使用 EOModeler 创建它。
  • EOModel 中的一个实体,你想要从中获取数据的实体(例如 Customer)。同样,这应该由 EOModeler 创建。
  • 一个 EOQualifier,它定义了你提取操作的条件(例如,纽约的所有客户)。
  • 一个 EOSortOrdering,它设置用于对结果进行排序的标准(例如,按 lastName、firstName、然后是 state 进行排序)。
  • 一个 EOFetchSpecification,它收集提取操作的标准,尤其是前 3 个对象。
  • 一个 EOEditingContext,用于管理你的数据库数据。对于你的早期项目,请使用你的 Session 类提供的默认值。
  • 一个 NSArray,用于保存已提取的对象(例如,myCustomers)。

实际上,你并不需要所有这些,但至少你需要一个 EOModel、一个实体、一个 EOEditingContext 和一个 NSArray 来保存你的数据。

回到基本级别,我假设你或其他人已经创建了 EOModel 来将你的数据库表映射到你的 Java 类。我还假设有人在该 EOModel 中定义了至少一个你感兴趣的获取其数据的实体。

你也可以通过使用 EOUtilities 中的快捷方式来避免 EOSortOrderings、EOQualifier 和 EOFetchSpecification。但是,无论你如何操作,最终都应该定义一个 NSArray 并用你的提取操作填充它。例如,在 WebObjects 组件中执行典型提取操作的代码可能如下所示

  EOEditingContext myEditingContext = session().defaultEditingContext();
  NSArray myCustomers  = EOUtilities.objectsMatchingKeyAndValue(myEditingContext, "Customer", "state", "New York");

在这一行中,我有一个名为 userGroup 的 int。如何从该对象中获取该 int 的值并将其放入一个变量中?基本上,我的问题是,我如何访问我引入的数据,以便在我的程序中使用它?

我的代码示例的结果是一个名为 myCustomers 的 NSArray,其元素是为你的 EOModel 中的“Customer”实体定义的 Java 类的实例。(通常,Java 类也会被命名为“Customer”。)

NSArray,myCustomers,是与你从数据库中检索的行相对应的 Java 对象的数组。它们不再是行,而是被 EOF 转换为成熟的 Java 对象,并且可以像这样进行操作。数组的第一个元素是检索到的第一行,第二个元素是第二行,依此类推。

我尝试过 EOUtilities.objectMatchingKeyAndValue,但到底什么是 Key?我还尝试过 EOUtilitlies.objectMatchingValues,但如何向字典中添加数据?

在我的代码示例中,我使用了 EOUtilities.objectsMatchingKeyAndValue() 方法。该方法的签名为

  NSArray EOUtilities.objectsMatchingKeyAndValue(EOEditingContext ec, String entityName, String key, Object value)

所以从我的示例中,你可以看到

  ec = myEditingContext
  entityName = "Customer"
  key = "state"
  value = "New York"

特别是,为了回答你的问题,键是你要提取的实体的 EOModel 属性名称。如果你仔细观察 EOModel,你会注意到每个实体都有三个名称,即实体名称、表示该实体的数据库中的表的名称,以及表示该实体的程序中的 Java 类的名称。通常,后两者是相同的,但不要混淆它们。

同样地,每个实体的属性都有一个对应的三个名称集:实体属性的名称、表示该实体属性的数据库中的列的名称,以及表示该实体属性的 Java 类中的 Java 成员(方法或实例变量)。再次强调,通常后两者是相同的,但不要混淆它们。

与其说“Java 成员(方法或实例变量)…”,我们只是说“键”。对象封装应该允许我们不关心值是通过访问器方法还是通过实例变量来表示。苹果公司的一项名为 Key-Value-Coding(或 KVC)的专有技术允许我们引用该值,而不必关心。实际上,我们提供键名,并且可以完全忽略对象是通过访问器方法还是通过实例变量提供该值。

第二:BLOB。我几乎没有找到关于 blob 的任何信息。如何将它们放入数据库?我知道人们不喜欢使用 BLOB,但我的导师希望我这样做,所以我必须这样做,并且如何在我需要将它们作为我的主程序调用的另一个程序的输入时在程序中稍后调用它们?

你的 EOModel 定义了对象关系映射,以便给定表的任何列都可以映射到 Java 类方法或 iVar(键)。EOModel 定义了这种映射,不仅包括名称对应关系,还包括属性对应关系,以便 EOF 可以将数据库表中给定行中的任何列值转换为 Java 对象中的适当键值。

请记住,列值具有数据库属性,例如整数或 BLOB。同样地,Java 对象中的键值具有类或原始值(例如,NSData 或 int)。如果你已正确设置 EOModel 映射,那么只需在将该对象提取到数组中后引用 Java 对象中的键即可。例如,从上面的示例中,要获取单个客户的数据

  Customer aCustomer = myCustomers.objectAtIndex(0);

你现在有一个由变量 aCustomer 引用的单个 Customer 对象。如果该 Customer 对象有一个由整数表示的 age 属性,你可以像引用任何 Java 对象变量值一样引用它

  int theAge = myCustomer.age();  // presuming that there is an age() accessor method, a fairly safe assumption for EOs.

如果要获取的对象成员是客户的照片,有些人会将该照片存储在数据库中(对于 WO 应用程序,我会在这样做之前犹豫很长时间,但假设我被迫这样做)。这些数据通常作为数据库中的 BLOB 和 Java 类中的 NSData 对象存储。在这种情况下,你可以通过以下方式检索照片

  NSData customerPicture = aCustomer.picture();
华夏公益教科书