实体 Bean

      实体 Bean 是两种主要 bean(实体和会话)中的一种。实体 Bean 用于表示数据库中的数据。它向 JDBC 或其它一些后端 API 经常访问的数据提供了一个面向对象的接口。不仅如此,实体 Bean 提供了一个组件模型,可以让 bean 开发人员将精力集中在 bean 的商业逻辑上,而容器负责管理持续、事务和访问控制。


     有两种基本的实体 Bean:容器管理的持续 (CMP)bean 管理的持续 (BMP) :
容器使用 CMP 管理实体 Bean 的持续。供应商工具用于将实体字段映射到数据库,并且绝对没有数据库访问代码写入 bean 类。

使用 BMP,实体 Bean 包含了数据库访问代码(通常是 JDBC),负责读取其自身状态并将此状态写入数据库。BMP 实体对此有很大帮助,因为容器将提醒 bean 何时需要更新状态或从数据库读取状态。容器还可以处理任何锁定或事务,因此数据库可以保持完整性。

     容器管理的持续 bean 对于 bean 开发人员是最易于创建的,但对于 EJB 服务器来说,却是最难以支持的。这是因为容器要自动处理所有用于使 bean 的状态与数据库同步的逻辑。这就意味着 bean 开发人员不需要编写任何数据访问逻辑,而 EJB 服务器应该自动负责所有持续要求 -- 对于任何供应商都是一个很高的要求。大多数 EJB 供应商都支持关系数据库的自动持续,但支持级别却各不相同。某些提供非常复杂的对象到关系映射,而某些供应商却非常有限。

Enterprise Bean 是一个完整的组件,它由至少两个接口和一个 bean 实现类组成。
Bean类
其定义如下:

import javax.ejb.EntityBean;

public class CustomerBean implements EntityBean 
{

    
int
        customerID;
    Address    myAddress;
    Name       myName;
    CreditCard myCreditCard;

    
// CREATION METHODS

    public Integer ejbCreate(Integer id) {
        customerID 
=
 id.intValue();
        
return null
;
    }


    
public void ejbPostCreate(Integer id) {
    }


    
public Customer ejbCreate(Integer id, Name name) {
        myName 
=
 name;
        
return
 ejbCreate(id);
    }


    
public void ejbPostCreate(Integer id, Name name) {
    }

    
    
// BUSINESS METHODS
    public Name getName() {
        
return
 myName;
    }


    
public void setName(Name name) {
        myName 
=
 name;
    }


    
public Address getAddress() {
        
return
 myAddress;
    }


    
public void setAddress(Address address) {
        myAddress 
=
 address;
    }


    
public CreditCard getCreditCard() {
        
return
 myCreditCard;
    }


    
public void setCreditCard(CreditCard card) {
        myCreditCard 
=
 card;
    }


    
// CALLBACK METHODS
    public void setEntityContext(EntityContext cntx) {
    }


    
public void unsetEntityContext() {
    }

    
    
public void ejbLoad() {
    }


    
public void ejbStore() {
    }


    
public void ejbActivate() {
    }


    
public void ejbPassivate() {
    }


    
public void ejbRemove() {
    }

}


这是个很好的示例,说明了一个非常简单的 CMP 实体 Bean。请注意,在这个 bean 中没有数据库访问逻辑。这是因为 EJB 供应商提供了将 CustomerBean 中的字段映射到数据库的工具。例如,CustomerBean 类可以映射到任何数据库,只要该数据库包含类似于 bean 中字段的数据。在此情况下,bean 的实例字段包括原语 int 和简单从属对象(NameAddressCreditCard),以及它们自己的属性。以下是这些从属对象的定义:

// The Name class
public class Name implements Serializable {

    
public String lastName, firstName, middleName;

    
public Name(String lastName, String firstName,
                String middleName) 
{
        
this.lastName   = lastName;
        
this.firstName  = firstName;
        
this.middleName = middleName;
    }


    
public Name() {}
}


// The Address class
public class Address implements Serializable {

    
public String street, city, state, zip;

    
public Address(String street, String city,
                   String state, String zip) 
{
        
this.street = street;
        
this.city   = city;
        
this.state  = state;
        
this.zip    = zip;
    }


    
public Address() {}
}


// The CreditCard class
public class CreditCard implements Serializable {

    
public String number, type, name;
    
public Date expDate;

    
public CreditCard(String number, String type,
                      String name, Date expDate) 
{
        
this.number  = number;
        
this.type    = type;
        
this.name    = name;
        
this.expDate = expDate;
    }


    
public CreditCard() {}
}


这些字段称作容器管理的字段,因为容器负责将它们的状态与数据库同步;即容器管理这些字段。容器管理的字段可以是任何原语数据类型或可串行化类型。本例中使用原语 int (customerID) 和可串行化对象(Address、Name、CreditCard)。要将从属对象映射到数据库,需要使用非常复杂的映射工具。在 bean 中,并不是所有字段都是容器自动管理的字段;某些可能只是 bean 过渡使用的纯实例字段。bean 开发人员在部署描述信息中指出哪些字段是容器管理的,以便区别容器管理字段和纯实例字段。

容器管理的字段在数据库中必须有相应类型(RDBMS 中的栏),它们之间的关系可以是直接映射或通过对象关系映射。例如,CustomerBean 可以映射到数据库中的 CUSTOMER 表,其定义如下:
CREATE TABLE CUSTOMER
{
    id            INTEGER PRIMARY KEY,
    last_name     CHAR(30),
    first_name    CHAR(20),
    middle_name   CHAR(20),
    street        CHAR(50),
    city          CHAR(20),
    state         CHAR(2),
    zip           CHAR(9),
    credit_number CHAR(20),
    credit_date   DATE,
    credit_name   CHAR(20),
    credit_type   CHAR(10)
}

使用容器管理的持续,供应商必须有一些专用工具以能够将 bean 的容器管理字段映射到一个特定表中它们相应的栏,在本例中是 CUSTOMER。

一旦 bean 的字段映射到数据库,且部署了 Customer bean 之后,容器将负责在 CUSTOMER 表中创建记录、装入记录、更新记录和删除记录,以响应在 Customer bean 的远程和本地接口上调用的方法。

容器管理的字段的子集(一个或多个)还将被标识成 bean 的主键。主键是索引或指针,它指向数据库中组成 bean 的状态的唯一记录。在 CustomerBean 的情况中,id 字段是主键字段,用于定位数据库中 bean 的数据。原语单一字段主键表示成其相应的对象封装。例如,Customer bean 的主键是 bean 类中的原语 int,但对于 bean 的客户机,它将自己表示成 java.lang.Integer 类型。有几个字段组成的主键叫作复合主键,它由 bean 开发人员定义的特定类表示。主键在概念上类似于关系数据库中的主键 -- 实际上当关系数据库用于持续时,它们通常是相同的。

posted @ 2005-03-28 13:51 微醺人生 阅读(616) 评论(0) 编辑

(一)概述

1、Enterprise JavaBean (EJB) 是 Sun Microsystems 对 CORBA 的可移植性和复杂性的解决方案。EJB 引入了比 CORBA 更简单的编程模块,它可以让开发人员创建可移植分布式组件,称作 Enterprise Bean。EJB 编程模块可以让开发人员创建安全的、事务性的和持久的商业对象 (Enterprise Bean),该对象使用非常简单的编程模块和声明属性。与 CORBA 不同,例如访问控制(授权安全性)和事务管理等设施非常易于编程。CORBA 需要使用复杂的 API 来利用这些服务,而 EJB 则根据一种称作“部署描述信息”的特性文件中的声明将这些服务自动应用到 Enterprise Bean。这个模型确保了 bean 开发人员可以集中精力编写商业逻辑,而容器会自动管理更复杂但又必要的操作。

由于 EJB 规范颁布了一组明确的 EJB 容器(供应商服务器)和 EJB 组件(商业对象)之间的契约,因此 EJB 中实现了可移植性。这些契约或规则确切规定容器必须为

2、Enterprise Bean 提供什么服务,bean 开发人员需要使用什么 API 和声明属性来创建 Enterprise Bean。由于详细指定了 Enterprise Bean 的生命周期,因此供应商知道如何在运行时管理 bean,bean 开发人员确切知道 Enterprise Bean 在其存在期间可以做什么。


3、Enterprise JavaBean 简化了分布式对象的开发、部署和访问。EJB 分布式对象(一种 Enterprise Bean)的开发人员只需依照为 Enterprise JavaBean 建立的契约和协议实现对象。支持 EJB 的应用程序服务器可以,也确实,使用任何分布式网络协议,包括本地 Java RMI 协议 (JRMP)、专有协议或 CORBA 的网络协议 (IIOP)。不管在某个特定产品中使用的基本网络协议是什么,EJB 使用相同的编程 API 和语义以 Java RMI-IIOP 访问分布式对象。协议的细节对应用程序和 bean 开发人员隐藏;对于所有供应商来说,定位和使用分布式 bean 的方法是相同的。


注:
Enterprise Bean 与 JavaBean 不同。JavaBean 是使用 java.beans 包开发的,它是 Java 2 标准版的一部分。JavaBean 是一台机器上同一个地址空间中运行的组件。JavaBean 是进程 组件。Enterprise Bean 是使用 javax.ejb 包开发的,它是标准 JDK 的扩展,是 Java 2 Enterprise Edition 的一部分。Enterprise Bean 是在多台机器上跨几个地址空间运行的组件。因此 Enterprise Bean 是进程组件。JavaBean 通常用作 GUI 窗口小部件,而 Enterprise Bean 则用作分布式商业对象。

(二)EJB规范
 

Enterprise JavaBean 规范为基于组件的事务性、分布式对象系统定义了一个体系结构。该规范颁布了一个编程模块,即组成 EJB API 的契约或协议以及一组类和接口。EJB 编程模块向 bean 开发人员和 EJB 服务器供应商提供了一组契约,这组契约定义了开发的公共平台。这些契约的目标是在支持一组丰富功能性的同时能够确保供应商之间的可移植性。


Enterprise Bean 依赖容器来获取它的需求。如果 Enterprise Bean 需要访问 JDBC 连接或另一个 Enterprise Bean,那么它需要利用容器来完成此项操作;如果 Enterprise Bean 需要访问调用者的身份、获取它自身的引用或访问特性,那么它需要利用容器来完成这些操作。Enterprise Bean 通过以下三种机制之一与容器交互:回调方法、EJBContext 接口或 JNDI。

  • 回调方法:
    每个 bean 都会实现 EnterpriseBean 接口的子类型,该接口定义了一些方法,称作回调方法。每个回调方法在 bean 的生命周期期间向它提示一个不同事件,当容器要合用某个 bean、将其状态存储到数据库、结束事务、从内存中除去该 bean 等操作时,它将调用这些方法来通知该 bean。回调方法可以让 bean 在事件之前或之后立即执行内部调整。
  • EJBContext:
    每个 bean 都会得到一个 EJBContext 对象,它是对容器的直接引用。EJBContext 接口提供了用于与容器交互的方法,因此那个 bean 可以请求关于环境的信息,如其客户机的身份或事务的状态,或者 bean 可以获取它自身的远程引用。

  • Java 命名和目录接口 (JNDI):
    JNDI 是 Java 平台的标准扩展,用于访问命名系统,如 LDAP、NetWare、文件系统等。每个 bean 自动拥有对某个特定命名系统(称作环境命名上下文 (ENC))的访问权。ENC 由容器管理,bean 使用 JNDI 来访问 ENC。JNDI ENC 允许 bean 访问资源,如 JDBC 连接、其它 Enterprise Bean,以及特定于该 bean 的属性。

远程和本地接口

远程和本地接口表示 bean,但容器不允许从客户机应用程序直接访问 bean。每次请求、创建、或删除 bean 时,容器都会管理整个过程。


本地接口:表示组件的生命周期方法(创建、破坏、查找)。
远程接口:表示 bean 的商业方法。

远程和本地接口分别扩展 javax.ejb.EJBObjectjavax.ejb.EJBHome 接口。这些 EJB 接口类型定义了一组标准的实用程序方法,并为所有远程和本地接口提供了常用基本类型。


远程接口定义了 bean 的商业方法,这些方法特定于 bean 表示的商业概念。远程接口是从 javax.ejb.EJBObject 接口划分出的子类,而这个接口又是 java.rmi.Remote 接口的子类。

import javax.ejb.EJBObject;
import java.rmi.RemoteException;

public interface Customer extends EJBObject {

    
public Name getName() throws RemoteException;
    
public void setName(Name name) throws RemoteException;
    
public Address getAddress() throws RemoteException;
    
public void setAddress(Address address) throws RemoteException;

}


 

远程接口定义了读方法和写方法,用于读取和更新有关商业概念的信息。这代表一种 bean,叫作实体 Bean,它表示持久商业对象(数据存储在数据库中的商业对象)。实体 Bean 表示数据库中的商业数据,并添加特定于该数据的行为。


商业方法
       商业方法还可以表示 bean 执行的任务。虽然实体 Bean 通常都会有面向任务的方法,但是任务通常代表另一种 bean,称作会话 Bean。会话 Bean 不表示类似于实体 Bean 的数据。它们表示执行服务(如在旅馆预定房间)的商业进程或代理程序。以下是 HotelClerk bean 的远程接口的定义,这个 bean 是一种会话 Bean


import javax.ejb.EJBObject;
import java.rmi.RemoteException;

public interface HotelClerk extends EJBObject {
  
    public void reserveRoom(Customer cust, RoomInfo ri,
                            Date from,     Date to)
                throws RemoteException;

    public RoomInfo availableRooms(Location loc, Date from, Date to)
                    throws RemoteException;
}

HotelClerk 远程接口中定义的商业方法表示进程而不是简单的读方法。HotelClerk bean 充当代理程序,因为它代表用户执行任务,但它自己在数据库中并不是持久的。您不需要有关 HotelClerk 的信息;您需要旅馆店员为您执行任务。这是会话 Bean 的典型行为。

      有两种基本的 Enterprise Bean:实体 Bean,表示数据库中的数据,以及会话 Bean,表示进程或充当执行任务的代理程序。在构建 EJB 应用程序时,您会创建许多 Enterprise Bean,每一个都表示不同的商业概念。每个商业概念都将由实体 Bean 或会话 Bean 表示。您将根据如何使用商业概念来选择它将成为哪种 bean。

posted @ 2005-03-28 11:37 微醺人生 阅读(788) 评论(0) 编辑