📄 ejb2_0中的变化增强,应用程序开发的灵活性和可移植性2.htm
字号:
<META content="MSHTML 5.00.2920.0" name=GENERATOR></HEAD>
<BODY bgColor=#ffffff text=#000000>
<table>
<table><tbody>
<TR>
<TD height=21>
<DIV align=center><B><FONT size=3>EJB2.0中的变化增强,应用程序开发的灵活性和可移植性2 <BR><FONT size=2> </FONT></FONT></FONT>
<HR align=center color=#cccccc noShade SIZE=1>
</DIV></TD></TR>
<TR>
<TD class=line><FONT
color=#333300><BR><BR>bean 类的继承层次结构 <BR><BR><BR>为了使讨论更充实,这里提供一个 CMP 实体的示例,它更具体地说明了抽象持久性方案是如何工作的。 <BR><BR>EJB 2.0 中的一个示例 CMP 实体 <BR>在 EJB 2.0 中,容器管理的实体 bean 被定义为抽象的,而且它的持久性字段并不在 bean 类中直接定义。作为替代,开发了一种抽象的持久性方案,从而允许 bean 提供者间接地声明持久性字段和 bean 关系。下面是 Employee bean 的一个示例,它使用了新的抽象持久性方案。请注意,该 bean 类中未声明任何持久性字段。 <BR><BR>public abstract EmployeeBean implements <BR>javax.ejb.EntityBean { <BR>. // 实例字段 <BR>EntityContext ejbContext; <BR><BR>// 容器管理的持久性字段 <BR>public abstract void setIdentity(int <BR>identity); <BR>public abstract int getIdentity(); <BR>public abstract void setFirstName(String <BR>firstName); <BR>public abstract String getFirstName(); <BR>public abstract void setLastName(String <BR>lastName); <BR>public abstract String getLastName(); <BR><BR>// 容器管理的关系字段 <BR>public abstract void <BR>setContactInfo(ContactInfo info); <BR>public abstract ContactInfo <BR>getContactInfo(); <BR><BR>... <BR>} <BR><BR><BR>在此 bean 的 XML 部署描述符中,抽象的持久性方案声明容器管理的各个字段和各种关系。 <BR><BR><ejb-jar> <BR><enterprise-beans> <BR><entity> <BR><ejb-name>EmployeeEJB</ejb-name> <BR>... <BR><persistence-type>Container</persistence-type> <BR><BR>... <BR><cmp-field><field-name>identity</field-name></cmp-field> <BR><BR><cmp-field><field-name>firstName</field-name></cmp-field> <BR><BR><cmp-field><field-name>lastName</field-name></cmp-field> <BR><BR>... <BR></entity> <BR></enterprise-beans> <BR><dependents> <BR><dependent> <BR><dependent-class>ContactInfo</dependent-class> <BR><BR><dependent-name>ContactInfo</dependent-name> <BR><BR><cmp-field>street</cmp-field> <BR><cmp-field>city</cmp-field> <BR><cmp-field>state</cmp-field> <BR><cmp-field>zip</cmp-field> <BR><cmp-field>homePhone</cmp-field> <BR><cmp-field>workPhone</cmp-field> <BR><cmp-field>email</cmp-field> <BR>... <BR></dependent> <BR><relationships> <BR><ejb-relation> <BR><ejb-relation-name>Employee-ContactInfo</ejb-relation-name> <BR><BR><ejb-relationship-role> <BR><ejb-relationship-role-name> <BR>employee-has-contactinfo <BR><BR></ejb-relationship-role-name> <BR><multiplicity>one</multiplicity> <BR><role-source> <BR><ejb-name>EmployeeEJB</ejb-name> <BR><BR></role-source> <BR><cmr-field> <BR><cmr-field-name>contactInfo</cmr-field-name> <BR><BR><cmr-field-type>ContactInfo</cmr-field-type> <BR><BR></cmr-field> <BR></ejb-relationship-role> <BR><ejb-relationship-role> <BR><ejb-relationship-role-name> <BR>contactinfo_belongsto_employee <BR><BR></ejb-relationship-role-name> <BR><multiplicity>one</multiplicity> <BR><role-source> <BR><dependent-name>ContactInfo<dependent-name> <BR><BR></role-source> <BR></ejb-relationship-role> <BR></ejb-relation> <BR></relationships> <BR><ejb-jar> <BR><BR><BR><BR>用来描述容器管理的关系的 XML 元素可能变得非常复杂,因为他们必须处理各种关系的对应性和方向(单向的还是双向的)。上面的代码段说明,为了描述 bean 与其从属对象类之间的简单关系,您需要哪些元素。虽然即使是简单的关系也会被转换为冗长的 XML,但所有这些元素都是必需的,以便持久性管理器能够将复杂的对象图映射到数据库中。 <BR><BR>虽然用于定义 CMP bean 的抽象持久性方案的 XML 元素是 EJB 2.0 中的 CMP 的主要问题,但为了简洁起见,本文不再提供 XML 示例。作为替代,本文将纯粹依靠 bean 类中必须使用的抽象习语,来说明 EJB 2.0 中的 CMP 背后的基本概念。这些代码习语与 XML 部署描述符中的关系元素一起使用,并由后者定义,所以您不能只有其一而没有另一个,但它们比该方案的 XML 部分较容易理解。 <BR><BR>除了 XML 元素之外,抽象的持久性方案还定义了一组习语,它们在声明 bean 类及其相关的对象时必然会用到。用来访问和修改字段的方法是严格定义了的,要求用 set<METHOD> 方法修改持久性字段,而用 get<METHOD> 方法访问它们。这些方法的名称和返回类型由部署描述符中它们相应的 XML 关系元素规定。 <BR><BR>实体 bean 类和从属类都遵循相同的抽象持久性方案。下面是如何将 ContactInfo 对象定义为从属对象类的示例。 <BR><BR>public abstract class ContactInfo { <BR>// 家庭地址信息 <BR>public abstract void setStreet(String street); <BR>public abstract String getStreet(); <BR>public abstract void setState(String state); <BR>public abstract String getState(); <BR>public abstract void setZip(String zip); <BR>public abstract String getZip(); <BR>public abstract void setHomePhone(String phone); <BR>public abstract String getHomePhone(); <BR><BR>// 工作地址信息 <BR>public abstract void setWorkPhone(String phone); <BR>public abstract String getWorkPhone(); <BR>public abstract void setEMail(String email); <BR>public abstract String getEMail(); <BR>... <BR>} <BR><BR><BR><BR>从属对象随实体 bean 的存在而存在,随实体 bean 的中止而中止,这是理解从属对象与实体 bean 之间关系的关键。从属对象包含在一个具体的实体中,所以删除这个实体将导致从属对象也被删除。用关系数据库的术语来说,有时这就称为级联删除。 <BR><BR>从属对象,如 ContactInfo,用在关系字段中。与实体 bean 形成关系的从属对象技术上称为从属对象类。EJB 客户端应用程序永远不能直接访问从属对象类;这种类不能用作 bean 的远程或本地接口中的参数或返回值。从属对象类只对 bean 类才是可见的。 <BR><BR>从属对象类不适合作为远程参数类型,因为它们与 bean 在运行时的持久性逻辑有密切的联系。持久性管理器扩展了抽象的从属对象类,以便能提供一种实现,可用于在运行时管理 bean 的持久性状态。此外,抽象的持久性方案还为数据建模 -- 而不是为那些由企业级 bean 表示的业务概念建模 -- 所以,作为一种设计策略,将抽象的持久性方案对 EJB 客户机隐藏起来是有意义的。 <BR><BR>例如,ContactInfo 关系字段中除了 bean 的客户机所需的简单地址信息之外,还包含许多其它信息。虽然您可以使用抽象持久性方案中的从属对象类 ContactInfo(它对 bean 的客户机是隐藏的),但是,您得用其它的对象来把这些数据实际表露给客户机。下面是一个示例,说明了如何对 EJB 客户机隐藏 ContactInfo 从属对象。在此例中,地址信息是通过在 EJB 1.1 的示例中开发的 Address 对象来表露的。 <BR><BR>// Employee bean 的远程接口 <BR>public interface Employee extends javax.ejb.EJBObject { <BR><BR>public Address getHomeAddress(); <BR>public void setHomeAddress(Address address); <BR><BR>public int getIdentity() throws RemoteException; <BR>public void setFirstName(String firstName) throws <BR>RemoteException; <BR>public String getFirstName()throws RemoteException; <BR>public void setLastName(String lastName) throws <BR>RemoteException; <BR>public String getLastName() throws RemoteException; <BR>} <BR><BR>// Employee bean 的 bean 类 <BR>public abstract EmployeeBean implements <BR>javax.ejb.EntityBean { <BR>... <BR>public Address getHomeAddress(){ <BR>ContactInfo info = getContactInfo(); <BR>Address addr = new Address(); <BR>addr.street = info.getStreet(); <BR>addr.city = info.getCity(); <BR>addr.state = info.getState(); <BR>addr.zip = info.getZip(); <BR>return addr; <BR>} <BR>public void setHomeAddress(Address addr){ <BR>ContactInfo info = getContactInfo(); <BR>info.setStreet(addr.street); <BR>info.getCity(addr.city); <BR>info.getState(addr.state); <BR>info.getZip(addr.zip); <BR>} <BR>.... <BR>// 容器管理的关系字段 <BR>public abstract void setContactInfo(ContactInfo <BR>info); <BR>public abstract ContactInfo getContactInfo(); <BR>... <BR>} <BR><BR><BR><BR>尽管容器管理的关系字段没有表露给客户机,但您仍然可以从远程接口直接使用容器管理的持久性字段。请注意,用来访问 firstName 和 lastName 的容器管理的持久性字段是在远程接口中使用的。 <BR><BR>一个 bean 与各种从属对象类之间可能具有多种不同的关系,它们由这种关系的对应性和方向来定义。Bean 与从属对象类之间可以有一对多和一对一的关系。例如,Employee bean 可能仅有一个 Benefit 从属对象类,但可能有许多 ContactInfo 从属对象类。 <BR><BR>public abstract EmployeeBean implements <BR>javax.ejb.EntityBean { <BR>... <BR>public abstract void setContactInfos(Collection <BR>addresses); <BR>public abstract Collection getContactInfos(): <BR><BR>public abstract void setBenefit(Benefit benefit); <BR><BR>public abstract Benefit getBenefit(); <BR>... <BR>} <BR><BR><BR>与从属对象类的一对多关系既可表示为 java.util.Collection 类型,也可表示为 ava.util.Set 类型(注:在本规范的后续版本中,java.util.Map 和 java.util.List 被视为附加的返回类型),而与从属对象的一对一关系则使用从属对象的类型。 <BR><BR>实体 bean 也可以定义与其它实体 bean 的关系。这些关系可以是一对一、一对多或多对多。例如,Employee bean 可能有许多子级 bean,而只有一个配对的 bean。下面的代码段使用抽象持久性方案的方法习语,说明了如何为这些关系建模。该应用程序中,子级 bean 和配对的 bean 都表现为 Person bean。 <BR><BR>public abstract EmployeeBean implements <BR>javax.ejb.EntityBean { <BR><BR>... <BR>public abstract void setSpouse(Person manager); <BR>public abstract Person getSpouse(); <BR><BR>public abstract void setChildren(Collection <BR>family); <BR>public abstract Collection getChildren(); <BR>... <BR>} <BR><BR><BR><BR>与另一个 bean 的一对多关系表示为 java.util.Collection 类型或 java.util.Set 类型,而一对一关系则使用该 bean 的远程接口类型。 <BR><BR>从属对象本身与同一个 bean 中的其它从属对象之间可以有一对一、一对多和多对多的关系。此外,从属对象与其它实体 bean(除其父级 bean 之外)也可以有一对一、一对多的关系。下面的示例显示,Benefit 从属对象类与 Salary 从属对象(一种报酬计算程序)之间怎样具有一对一的关系,而与 Investment bean 又怎样具有一对多的关系。 <BR><BR>public abstract class Benefit { <BR>public abstract void setSalary(Salary salary); <BR>public abstract Salary getSalary(); <BR><BR>public abstract void setInvestments(Collection <BR>investments); <BR>public abstract Collection getInvestments(); <BR>} <BR></FONT></TD></TR>
<TR>
<TD height=5>
<HR align=center color=#cccccc noShade SIZE=1>
</TD></TR></TBODY></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -