WebObjects/EOF
WebObjects 具有两个方面。一方面,它将关系数据库或其他持久性数据源转换为对象图,即相互连接的对象组。另一方面,它使用模板将对象图转换为 HTML。第一个方面是 EOF。EOF 桥接了关系数据库的世界和对象的世界。换句话说,EOF 允许您从数据库开始,构建代表您想要在数据库之上执行的操作的 POJO(POJO = "Plain Old Java Object"),以使其更智能,更能响应您的目标受众。
如果您来自关系数据库环境,您可能已经接受过以表格、行、列、联接、笛卡尔积、结果集等方面的思维方式进行训练。只要您继续用这些术语来思考您的应用程序,WebObjects 将顽固地站在您和成功之间,在您找到 SQL 解决方案的快速方法时,通过施加大量“便利”来阻碍您。应用程序下的模式设计很重要,但模式设计与数据库设计不同。EOF 为您提供了一层抽象,覆盖了简单的关系数据库。
如果您能理解面向对象的概念,使用面向对象的集合类,如数组(或向量)、集合、字典(或哈希表),并以您正在使用的对象图的思维方式思考,您会发现 WebObjects 是一项非常支持且有帮助的技术。与所有复杂技术一样,它有自己的故障和错误,但对于表面下令人难以置信的复杂性来说,这些故障和错误出奇地少。
使用 EOF 有两种方法。它既可以用作使现有数据库更灵活的方法,也可以用作在开发的应用程序中持续保存模型的方法。它既被那些先在白板上建模然后编写代码的企业家使用,也被拥有 15 年历史的数据库、遗留代码和系统并且必须使其更灵活的企业使用。
如果您已经有了一个数据库,最好的入门方法是反向工程模型。如果您在 Mac OS X 系统上安装了 WebObjects,您有一个示例数据库和一个 JDBC 驱动程序。
了解 WebObjects 对您的意义的最佳方法是将您的 EOModel 仔细地看成一个 ER 图。在 EOModeler 中打开您的 EOModel,并切换到图形实体关系视图(EOModeler 窗口左上角的小弹出窗口)。该视图表示您模型对象的图。通过拖动重新排列实体,以使线条交叉尽可能少,以便您可以清楚地看到图表。完成此操作后,您可能希望将其打印出来以方便访问。如果您使用的是 Mac,一个简单的做法是截取屏幕截图,然后您可以将生成的 .pdf 文件打印出来,并将其缩放为一张纸。
请注意,该图上每个实体中的属性名称是官方 EOModel “属性”名称,而不是数据库列名称。如果您要求 EOModeler 创建每个实体的 java 类文件,java 成员名称(ivars 和方法名称)也将与这些名称相对应。这是以 WebObjects 方式思考的第一步。在任何操作中都考虑这些官方“属性”名称,而不是数据库列名称。
在您理解了模型之后,下一步是获取一些数据。选择一个您感兴趣的实体。为了在您的应用程序中实例化该实体的一组对象,您通常需要创建一个 EOQualifier,以便从您对象存储中所有存在的实例中选择合适的实例(请注意,我说的是对象实例,而不是表行,以及对象存储,而不是关系数据库;您必须习惯于思考对象)。
假设您有一些 Employee 和 Department 记录,并且您想要获取所有在您部门工作的 Employee,以便向他们发送部门年终聚会(EOYBO)的邀请函。此外,假设您的 Employee 和 Department 实体具有以下属性
Employee lastName firstName lengthOfService ... Department name location division
如果您只想要特定性别的员工,例如“female”,最简单的方法是使用 EOUtilities 作为一种便捷的快捷方式来进行简单的查询。
myEditingContext = session().defaultEditingContext(); NSArray femaleEmployees = EOUtilities.objectsMatchingKeyAndValue(myEditingContext, "Employee", "gender ", "female");
这里有很多内容,但您可以在 EOUtilities 文档中查找该方法以查看参数的含义。无论如何,一旦执行此语句,您就获得了您正在查找的员工的 NSArray。(也查阅 NSArray 并将其与 Java 的 Array 或 Vector 进行比较,它们是类似的)。不幸的是,仅仅通过特定值与给定属性进行比较有点局限性,因此更长但更灵活的方法是创建一个 EOQualifier,然后在获取规范中使用它来获取您的初始对象。创建限定符的最简单方法是使用魔法方法,“qualifierWithQualifierFormat()”。使用这些工具,我们可以获取我们最初要找的员工,即我们部门的员工。我们可以这样操作
myDepartmentName = "Information Technology"; EOQualifier myQual = EOQualifier.qualifierWithQualifierFormat("department.name = %@", myDepartmentName); EOFetchSpecification myFetcher = new EOFetchSpecification("Employee", myQual, null); EOEditingContext myEC = session().defaultEditingContext(); NSArray employeesToInvite = myEC.objectsWithFetchSpecification(myFetcher);
我们再次获得了一个 Employee 数组,但使用了一种稍微更难的方法。但是请注意,我们要求数据库为我们进行联接,方法是在限定符格式中使用“department.name”结构。这意味着,获取与名称为... 的部门对象连接的员工。当然,它的优势在于魔法方法,qualifierWithQualifierFormat() 允许我们构建一些非常复杂的限定符,并且可以轻松地构建它们,例如
EOQualifier myQual = EOQualifier.qualifierWithQualifierFormat("(department.name = %@ and age > %@ and boss.gender = %@) or gender = 'female'", myDepartmentName, new Integer(40), "male");
困难的部分已经完成。现在只剩下 WebObjects 作为面向对象程序员为我们提供的简单内容了。假设对于每个员工,您想要通过向他们的老板发送邮件来安排他们的 EOYBO。还假设,老板和员工一样,都是 Employee,因此具有相同的属性,如上所示。只需遍历 Employee 数组,并询问每个对象其老板的电子邮件地址,然后发送邀请函,如下所示
Enumeration enum = likelyEmployees.objectEnumerator; while (enum.hasMoreElements()) { Employee anEmployee = enum.nextElement(); sendScheduleRequestTo(anEmployee.boss().emailAddress()); }
请注意,我们不需要任何其他获取规范或限定符!WebObjects 通过其企业对象框架自动识别了对更多数据库记录(老板)的需求,并直接为我们获取了这些记录,而无需更多明确的获取操作。
当然,有人必须编写“sendScheduleRequestTo(EMailAddress addr)”方法,但是有很多库可用,而且您可能对 Java 非常熟悉,可以自己完成。
重点是,我们不必为老板进行额外的明确获取操作,因为 WebObjects 为我们完成了。它基本上执行了联接操作,并为我们提供了结果,而我们却不知道。只需使用获取操作获取您的第一组对象,然后按照对象图进行操作。
忘记结果集、联接、选择和其他所有关系数据库工件。或者,至少在您遇到麻烦之前,忘记它们,以某种方式获得您想要的结果。如果问题很严重,请设置 WebObjects 运行时参数,-EOAdaptorDebugEnabled YES,EOAdaptor 将将其生成的所有 SQL 倾倒到您的运行日志中,以便您可以准确地了解它正在为您做的事情(或正在对您做的事情)。 :-)
但是,在您开始构建第一个对您至关重要、人命关天的、无错误的 WebObjects 程序之前,您应该看看“管理对象图的常规指南”。它更深入地介绍了我在这里提到的某些概念,而且写得非常好。
您可以在 Apple 文档中找到它:/Developer/Documentation/WebObjects/Reference/API/com/webobjects/eocontrol/concepts/EOEditingContextConcepts.html#GENERALGUIDELINES
或
/Developer/ADC Reference Library/WebObjects/Reference/API/com/webobjects/eocontrol/concepts/EOEditingContextConcepts.html#GENERALGUIDELINES
当然,这是更大页面中的一个 HTML 片段,所有内容都值得一读。
无论如何,祝您 WebObjects 未来好运。