UML软件工程组织

容器管理持久性EJB组件
作者:苏洋    本文选自:赛迪网  2002年12月26日

 

上一讲曾利用组件管理持久性实体类型EJB组件实现对公司员工注册信息进行管理和维护的功能。在组件代码设计过程中,程序设计人员必须在组件类中的创建组件对象方法和组件生命期管理方法中编写用于操作数据库的SQL语句。编写这些代码不仅烦琐,而且代码调试的难度很大,极大程度地降低了组件的开发效率。为此,EJB规范定义了另外一种类型的实体组件——容器管理持久性实体类型EJB组件。
EJB系列讲座
第一讲:分布式多层体系结构
第二讲:EJB基本结构解析
第三讲:EJB会话组件分析
第四讲:如何定义无状态会话类型EJB组件
第五讲:创建有状态会话类型EJB组件
第六讲:EJB的实体组件
第七讲:组件管理持久性EJB组件详解


顾名思义,容器管理持久性实体类型EJB组件由组件部署的EJB容器负责处理数据库的存储和访问操作并且在组件部署过程中可以设置不同组件之间的容器管理关系(Container-Managed Relationship)。这种类型EJB组件的引入,不仅大大减少了构成组件的代码量,更重要的是提高了同一EJB组件在不同数据库服务器之间的可移植性。

在本讲的内容中,将利用容器管理持久性实体类型EJB组件重新设计用于对公司员工的基本信息进行管理的EJB组件。

容器管理的关系

在创建容器管理持久性实体类型EJB组件之前,需要详细分析组件之间的容器管理关系,这种组件之间的关系在组件部署描述文件中由CMR字段表示。EJB2.0规范支持组件间三种类型关系:

◇一对一关系

◇一对多关系

◇多对多关系

当组件之间的关系确定后,EJB容器自动维护组件之间关系的完整性。例如,在一对一关系的组件中改变了一个组件的状态,则EJB容器自动将另外一个组件进行更新。在组件类中,可以利用组件的本地(Local)接口对象表示"一"、利用Java的集合类(Collection)表示"多"。

容器管理持久性实体类型EJB组件的容器管理字段

基于EJB1.0或EJB1.1规范的组件设计中,利用实体组件类中的实例变量表示组件代表数据库记录的相应字段。基于EJB2.0规范的实体组件则需要在组件部署过程中配置容器管理持久性(CMP)字段和容器管理关系(CMR)字段,实现组件的持久性管理以及组件之间的关系管理。相应地,在组件类中需要编写获取和设置CMP和CMR字段内容的方法。

与其它类型的EJB组件类似,容器组件管理持久性实体类型EJB组件同样具有远程(Remote)和本地(Local)两种类型的接口,分别用于提供组件的远程和本地客户端视角(View)。通常,组件的本地接口用于同处在一个EJB容器中的其它类型EJB组件获取该组件中定义的方法。本地接口是普通的Java接口对象而不是RMI远程对象,因此该组件的客户端可以通过引用的方式访问该组件。组件的远程接口是继承RMI对象的远程类型接口,用于处在网络层中的客户端访问该组件获取服务。

由于不需要在容器管理持久性实体类型EJB组件的组件类中编写用于访问数据库的SQL语句,使得容器管理持久性组件与组件管理持久性组件在代码设计方面具有较大区别,见下表:

表1 组件管理持久性和容器管理持久性组件定义对比表


区别 容器管理持久性 组件管理持久性
组件类定义方式 抽象类 非抽象类
数据库访问代码 由部署工具创建 由组件程序设计人员编写
组件的持久性状态 组件类中的虚拟持久性字段 组件类中的实例变量
findByPrimaryKey方法代码 由EJB容器实现 组件程序设计人员编写
ejbCreate方法的返回值 组件的主键类
其它类型组件定位方法 由EJB容器实现 组件程序设计人员编写
持久性字段和关系字段的访问方法 需要 不需要

分析组件之间的关系

由于EJB2.0规范引入了容器管理关系的概念,因此在组件程序设计之前,需要详细分析待创建的员工注册信息管理EJB组件之间的关系。为了方便说明,针对员工注册信息管理功能创建三个容器管理持久性实体类型EJB组件:表示注册员工的组件EmployeeEJB、表示员工联系方式的组件ContactionEJB、表示员工职位的组件PositionEJB。

由于一个员工可以有多种联系方式,使得EmployeeEJB与ContactionEJB之间构成"一对多关系";一个员工只能拥有一个职位,而相同类型的职位可以有多个员工,因此,EmployeeEJB与PositionEJB之间的关系为"多对一关系"。三个EJB组件之间关系如下图所示:


图1 员工注册信息管理系统组件之间关系图


创建EmployeeEJB组件的Local Home接口

容器管理持久性实体类型EJB组件的Local Home接口用于定义组件的create方法、find方法以及组件的生命期和持久性控制方法。这些方法是由与该组件部署在相同EJB容器中的其它组件调用。

容器管理持久性实体类型EJB组件的Local Home接口继承EJBLocalHome接口,在该接口中除了定义根据主键查找组件对象的findByPrimaryKey方法外,还可以定义利用组件的其它持久性字段对组件对象进行定位的方法,如下面接口中定义的findByName方法。EmployeeEJB组件的Local Home接口定义如下:

public interface LocalEmployeeHome extends EJBLocalHome {
        public LocalEmployee create (String id, String name, double salary)
        throws CreateException;
        public LocalEmployee findByPrimaryKey (String id) throws FinderException;
        public Collection findByName(String name) throws FinderException;
     	… …
  	}

创建EmployeeEJB组件的Local接口

容器管理持久性实体组件的Local接口继承EJBLocalObject接口对象,用于定义组件的商务方法以及访问组件持久性字段和关系字段的方法。由于这些方法由处于同一EJB容器中的其它EJB组件对象调用,因而可以限制其它组件访问EmployeeEJB组件方法的范围,如下面接口中只定义了其它组件获取EmployeeEJB组件的持久性字段和关系字段内容的方法,而没有定义对这些字段进行赋值的方法。EmployeeEJB组件的Local接口定义如下:

public  interface LocalPlayer extends EJBLocalObject {
    	public  String getPlayerId();
    public  String getName();
    public  double getSalary();
}

创建EmployeeEJB实体组件类

组件类的编写规则

编写容器管理持久性实体类型EJB组件的组件类需要遵循如下规则:

◇组件类必须定义为抽象(abstract)类型、访问方式定义为公共(public)类型;

◇可以定义数量不限的ejbCreate方法和ejbPostCreate方法;

◇必须将获取和设置持久性字段和关系字段的方法定义为抽象类型,选择(select)方法同样必须定义为抽象类型;

◇需要在组件类中定义组件生命期管理方法;

◇在组件类中编写组件的商务方法的实现代码。

定义访问组件持久性字段的方法

EJB规范中定义的容器管理持久性实体类型EJB组件的持久性字段和关系字段是组件类中的虚拟字段,没有实例变量与这些字段相对应。为使该组件的客户端能够访问这些字段,在组件类中必须定义获取和设置这些字段内容的方法。

EJB规范规定设置组件持久性字段内容的方法名称为setXxx,其中Xxx为与持久性字段相对应的关系数据库表的相应字段。根据上一讲中创建的用于存储公司员工注册信息的关系数据库表结构,定义组件的持久性字段访问方法如下:

publi abstract String getId();
publi abstract void setId(String id);
publi abstract String getName();
publi abstract void setName(String name);
publi abstract double getSalary();
publi abstract void setSalary(double salary);

由上述方法定义可以看出:访问组件持久性字段的方法必须定义为抽象类型,获取持久性字段方法的返回值类型以及设置持久性字段方法中的参数类型必须与相应数据库表字段的类型相同。

定义访问组件关系字段的方法

根据前面对EmployeeEJB组件与ContactionEJB组件以及PositionEJB组件之间的关系进行分析,定义组件类中关系字段的访问方法如下面代码所示:

public abstract Collection getContactions();
public abstract void setContactions(Collection contactions);
public abstract Collection getPositions();
public abstract void setPositions(Collection positions);

由上述方法定义可以看出:由于EmployeeEJB组件对应多个ContactionEJB组件以及PositionEJB组件。因此在EmployeeEJB组件的组件类中获取关系字段内容方法的返回值类型为Java集合类型,而设置关系字段内容方法的参数同样为集合类型。

定义组件生命期方法和持久性方法

对于容器管理持久性实体类型EJB组件,组件部署的EJB容器维护组件的生命期和持久性,因此,在组件类中除了编写ejbCreate方法的实现代码外,只需给出其它方法的定义框架即可。定义ejbCreate方法的实现代码如下:

public String ejbCreate(String id,String name,double salary) 
throws CreateException {
    setId(id);
    setName(name);
    setSalary(salary);
    return null;
}

经过上述组件类、组件Local Home接口和Local接口定义,完成了容器管理持久性实体类型组件EmployeeEJB的定义。但需要注意的是:创建容器管理持久性类型组件的主要工作是在组件的部署过程中定义持久性字段以及配置关系字段的内容。限于篇幅,在本讲座中没有对组件的部署过程进行讲解,请读者参考相关资料。

到这里,实体类型的EJB组件我们就讲完了,在下一讲中,我们将开始学习EJB的消息驱动组件。



版权所有:UML软件工程组织