与从属对象类的一对多关系既可表示为 java.util.Collection 类型,也可表示为java.util.Set 类型(注:在本规范的后续版本中,java.util.Map 和java.util.List被视为附加的返回类型),而与从属对象的一对一关系则使用从属对象的类型。
实体 bean 也可以定义与其它实体 bean 的关系。这些关系可以是一对一、一对多或多对多。例如,Employee bean 可能有许多子级 bean,而只有一个配对的bean。下面的代码段使用抽象持久性方案的方法习语,说明了如何为这些关系建模。该应用程序中,子级 bean 和配对的 bean 都表现为 Person bean。
|
与另一个 bean 的一对多关系表示为 java.util.Collection 类型或java.util.Set类型,而一对一关系则使用该 bean 的远程接口类型。从属对象本身与同一个 bean中的其它从属对象之间可以有一对一、一对多和多对多的关系。此外,从属对象与其它实体 bean(除其父级 bean 之外)也可以有一对一、一对多的关系。下面的示例显示,Benefit 从属对象类与 Salary从属对象(一种报酬计算程序)之间怎样具有一对一的关系,而与 Investment bean又怎样具有一对多的关系。
|
在部署时,部署者将使用持久性管理器工具来具体实现这个 bean类及其从属类。这些具体实现将在运行时保持各种关系,并使各 bean实例的状态与数据库同步。容器将在运行时管理持久性实例,从而提供一种强健的环境,其中具有自动的访问控制和事务控制。
bean 也可以定义从属对象的值,这些对象是可序列化的对象,如 EJB 1.1 示例中的Address 对象。这些值通过序列化而变为持久的,它们并不形成与 bean 的关系 --它们是严格的容器管理的持久性字段。
容器与持久性管理器之间也已经定义了一个合约,使持久性管理器可以获得事务的句柄,并访问由该容器管理的数据库连接池。这个合约稍嫌宽松,将来还需要使其更为严格,但它是允许持久性管理器跨 EJB容器移植的基础。容器和持久性管理器之间合约的细节已超出了本文的范围。
除了通过抽象持久性方案定义持久性之外,EJB 2.0 还提供了一种新的查询语言,用来说明持久性管理器应该如何实现 CMP 中的各种查找方法。
EJB 查询语言
EJB 查询语言 (EJB QL) 规定了持久性管理器应该如何实现在本地接口中定义的各种查找方法。 EJB QL 以 SQL-92 为基础,可由持久性管理器自动编译,这使得实体bean 具有更高的可移植性,并且更容易部署。
EJB QL 和查找方法
EJB QL 语句是在实体 bean 的部署描述符中声明的。使用 EJB QL 非常简单。作为一个例子,Employee bean 的本地接口可以按以下方式声明:
|
给定了上面的本地接口定义之后,您就可以使用 EJB QL 来指定持久性管理器应该如何执行查找方法。每个实体 bean 都必须有一个 findByPrimaryKey()方法。为执行该方法所需的查询是很明显的 -- 使用主关键字的(一个或几个)字段在数据库中查找bean,这样就不需要任何 EJB QL 语句。
findByZipCode() 方法用来获得具有某个邮政编码的所有 Employee bean。这将使用部署描述符中的下列 EJB QL 来表达。
|
该语句本质上是表示“选择其邮政编码等于 zipcode 参数的所有 Employee bean”。
在用于查找方法的 EJB QL 语句中,不需要使用 SELECT子句来表明要选择的内容。这是因为,查找方法将总是选择与其自身的 bean类型相同的远程引用。在这种情况下,就可以认为选择语句将返回远程 Employee bean 的全部引用。
如果各种查找方法都一起部署在同一个 ejb-jar 文件中,并且其间具有可导航的实际关系,那么这些查找方法就甚至可以跨越到另一些 bean 的抽象持久性方案中去。例如,findByInvestment() 方法将要求该查找查询从 Employee 导航到投资 bean的抽象持久性方案中去。声明来表达这种查找操作的 EJB QL 语句如下所示。
|
以上语句是说:“选择全部这样的 Employee bean:其获利从属对象至少包含一个投资 bean 的引用,并且其名称等于 findByInvestment() 方法的 investmentName参数。”
EJB QL 和选择方法