EJB技能的数据库应用
当前位置:以往代写 > JAVA 教程 >EJB技能的数据库应用
2019-06-14

EJB技能的数据库应用

EJB技能的数据库应用

副标题#e#

一、J2EE 技能简介

J2EE是 SUN 公司提出的在漫衍式情况中的一种体系布局,它提供了一种基于组件的设计、开拓、集成、陈设企业应用系统的要领,J2EE平台提供了多层漫衍式的应用系统模子、重用组件的本领、统一的安详模子和机动的事务节制。基于组件的J2EE企业应用系统具有平台独立性,所以不受任何软件产物和任何软件厂家API的约束。

J2EE界说了下面的组件:

·application client 和 applets 是客户层组件;

·Java Servlet 和 JSP 组件是WEB 层组件;

·Enterprise JavaBean(EJB) 组件是业务处理惩罚层组件。

EJB 技能是J2EE 体系一部门,EJB 组件是用 Java 语言编写的,是可以被客户端措施存取的可重用的处事器端组件,它运行在J2EE 处事器上,在客户/处事器系统中,EJB 提供雷同于中间件的处事。

J2EE 处事器提供给用系统系统级的处事,像事务打点、安详打点、数据库存取等,开拓人员不必本身开拓系统级处事,所以可以会合精神开拓应用系统中的业务逻辑处理惩罚;用EJB 组件处理惩罚业务逻辑。

二、EJB 组件简介

EJB 组件分为两类:Sesson bean 和 Entity bean

Sesson bean 代表 J2EE 处事器的客户端,客户端通过挪用 Sesson bean 的成果和J2EE 处事器通信,Sesson bean 和客户会话,可以认为是客户端的扩展,譬喻:网上帐务系统的客户可以挪用 Sesson bean 的"输入存款单"的成果来存入现金等。每一个Sesson bean 只能有一个客户,当客户终止时,与之相应的Sesson bean 也终止。因此Sesson bean 是临时的,不行耐久的。

Entity bean 代表业务处理惩罚工具,它存储在耐久的存贮机制如数据库中,譬喻,一个Entity bean 代表一个帐户存单,它是存储在干系数据库中存单表的一行。Entity bean 的信息不必然存储在干系数据库中,它也可以存储在工具数据库中、文件中或其他此外存储机制中( 本例子顶用干系数据库)。

Entity bean 可以被多个客户端共享。由于多个客户端大概改变沟通的数据,所以Entity bean 在事务打点下事情是很重要的。凡是环境下,EJB 容器提供事务打点。开拓人员可以在组件的陈设描写文件中指定事务的属性。每一个Entity bean 都有一个独一的工具标识符,也叫主键,这个主键可以让客户端定位一个Entity bean。

Entity bean 的耐久性可以被 Entity bean 本身打点,也可以让 EJB 容器打点,Entity bean本身打点要求开拓人员在Entity bean中提供数据存代替码。譬喻客户的Entity bean要挪用 SQL 语句来通过 JDBC 存取干系数据库。EJB 容器打点Entity bean耐久性意味着 EJB容器自动处理惩罚数据存取的挪用。

两种范例的EJB 组件(Session bean 和 Entity beans)都可以存取数据库。选择哪一类 EJB 组件来存取数据库依赖于详细的应用系统。

下面的环境可以在 Session bean 组件中挪用 SQL 语句来存取数据库:

· 应用系统相对简朴。

· SQL 语句返回的数据不能被多个客户端共享利用。

· 数据不代表一个业务实体。

下面的环境要用Entity beans 组件:

· 高出一个客户端利用数据库挪用返回的数据。

· 数据代表一个业务实体。

· 开拓者想从 Sesson bean 中埋没干系模子。

EJB 布局的这种机动性可以让开拓人员用差异的要领来开拓应用系统。


#p#副标题#e#

三、成立数据库毗连

EJB 容器维护数据库的毗连池,这个毗连池对 EJB 组件来说是透明的。当EJB 组件申请一个毗连时,EJB 容器从毗连池中提取一个毗连并分派给组件。由于EJB 容器只是分派一个毗连给 EJB 组件,所以组件很快就得到这个毗连并毗连数据库。数据库挪用之后,组件就可以释放毗连,这样它又可以快速申请到另一个毗连。又因为一个组件只占用这个毗连很短的时间,从而同一个毗连可以被多个组件利用。

组件不是通过数据库的绝对名来毗连数据库,而是用逻辑名毗连到数据库, 即用 JNDI lookup 来得到数据库毗连,譬喻:在下面例子中的AccountEJB 类中,毗连数据库有以下几个步调:

1、指定命据库的逻辑名:

private String dbName = "java:comp/env/jdbc/AccountDB";

2、得到数据源:

InitialContext ic = new InitialContext();

DataSource ds = (DataSource) ic.lookup(dbName);

3、从数据源获得数据库毗连:

Connection con = ds.getConnection();

这种间接的毗连数据库有以下几个利益:

· 可以在具有差异的数据库名的差异情况中陈设沟通的 EJB 组件。

· 可以在多个应用中重用EJB 组件。

· 可以集成 EJB 组件到运行在漫衍情况的应用系统中。

别的,EJB 类型没有要求 J2EE的实现支持某一个出格范例的数据库系统,因此EJB 组件可以毗连到差异的数据库系统。

四、EJB 数据库应用的例子

下面以一个简朴的例子 "银行帐户"应用系统来先容 EJB 组件的Entity bean范例的组件存取数据库。

Entity bean 的状态存储在干系数据库的 ACCOUNT 表中,表ACCOUNT 由下面的SQL 语句建设:

#p#分页标题#e#

CREATE TABLE ACCOUNT
    (id VARCHAR(3) CONSTRAINT pk_account PRIMARY KEY,
     firstname VARCHAR(24),
     lastname VARCHAR(24),
     balance DECIMAL(10.2));

和其他EJB 组件一样,开拓人员必需编写 Entity bean 的 Entity Bean Class 代码(AccountEJB.java)、Home Interface 代码(AccountHome.java)及Remote Interface 代码(Account.java)。

Entity Bean Class 代码( AccountEJB.java)

EntityBean 接口要领

EjbCreate 要领:当客户端挪用 create 要领时,EJB 容器挪用相应的ejbCreate 要领。一个Entity组件的ejbCreate 要领要实现下列事情:

· 插入Entity Bean 的状态到数据库中

· 初始化实例变量

· 返回主键。

AccountEJB的ejbCreate 要领挪用insertRow 要领,而insertRow 要领发出一个 insert SQL 语句插入Entity Bean 的状态到数据库中,下面是 Account 类中ejbCreate 要领的源代码:

sublic String ejbCreate (String id,String firstName,String lastName,double balance)throw CreateException{
    if (balance < 0.00)
{
    throw new CreateException("A negative initial balance is not allowed."); }
try {
      insertRow(id,firstName,lastName,balance); 
    } catch (Exception ex) {
       throw new EJBException("ejbCreate:"+ex.getMessage()); }     this.id = id; 
    this.firstName = firstName; 
    this.lastName = lastName; 
    this.balance = balance; 
    return id; }

throws 子句可以包括 javax.ejb.CreateException 和此外应用系统中指定的破例处理惩罚例程(exceptions)。Entity Bean的状态也可以通过非 J2EE 应用系统直接插入到数据库中,如SQL 语言剧本插入一行数据到 ACCOUNT表中,尽量这条数据不是通过 ejbCreate 要领插入到数据库中的,但Entity Bean 同样能通过客户端措施定位这条数据。

#p#副标题#e#

ejbPostCreate 要领

对付每一个ejbCreate 要领,开拓人员必需在Entity Bean中写一个ejbPostCreate 要领,EJB 容器在挪用完ejbCreate 今后,就当即挪用ejbPostCreate,和 ejbCreate 要领纷歧样,ejbPostCreate 要领可以挪用 getPrimaryKey 等要领,凡是ejbPostCreate 要领是空的。

ejbRemove 要领

当客户端通过挪用 remove 要领来删除一个 Entity Bean 的状态数据时,EJB 容器挪用 ejbRemove 要领,ejbRemove 要领从数据库中删除一个Entity Bean 状态数据。代码如下:

public void ejbRemove() {
     try {
       deleteRow(id);
     } catch (Exception ex){
       throw new EJBException ex("ejbRemove:"+exgetmessage());
     }
   }

假如ejbRemove 要领碰着系统级错误,将执行javax.ejb.EJBException. 假如碰着应用级错误,将执行javax.ejb.RemoveException。

entity bean 的状态数据也可以通过数据库的 delete 语句直接删除数据。

EjbLoad 要领和 ejbStore 要领

EJB 容器需要维持 Entity Bean 的实例变量与数据库中相应值的同步,这需要挪用 ejbLaod 要领和ejbStore 要领。ejbLoad 要领用数据库中的数据刷新变量的值,ejbStore 要领把变量的值写入到数据库中。客户端不能挪用 ejbLoad 要领和ejbStore 要领。

假如业务处理惩罚的要领干系到事物处理惩罚,EJB 容器要在业务处理惩罚要领挪用之前挪用 ejbLoad 要领刷新数据,业务处理惩罚要领执行之后,EJB 容器又当即挪用 ejbStore 要领把数据存储到数据库中。因为 EJB 容器挪用ejbLoad要领和ejbStore 要领,开拓人员在业务处理惩罚要领中不必刷新和存储实例变量的值。

假如ejbLoad 要领和ejbStore 要领不能在低层数据库中定位 Entity Bean,将执行 javax.ejb.NoSuchEntityException。

在 AccountEJB 类中,ejbLoad 要领挪用 loadRow 要领,loadRow 则发出一个 select 语句从数据库提取数据分派给实例变量;ejbStore 要领挪用 storeRow 要领,storeRow 要领例用 update 语句把实例变量的值存储到数据库。代码如下:

public void ejbLoad(){
     try{
       loadRow();
     }catch (Exception ex){
       throw new EJBException ("ejbLoad:"+ex.getMessage());
     }
   }
   public void ejbStore(){
     try{
       storeRow();
     }catch (Exception ex){
       throw new EJBException ("ejbStore:"+ex.getMessage());
     } }

Finder 要领 :

Finder 要领答允客户端查找 entity bean ,AccountClient 中有三种要领查找entity bean:

#p#分页标题#e#

Account jones = home.findByPrimaryKey("836");
     Collection c home.findByLastName("Smith");
     Collection c home.findInRange(20.00,99.00);

Entity bean 类必需实现相应的要领,而且文件名以ejbFind 前缀开始,如:AccountEJB 类实现 ejbFindByLastName 的要领如下:

public Collection ejbFinfBylastName(String lastName)
     throw FinderException {
     Collection result;
     Try {
       Result = selectByLastName(lastName);
     } catch (Exception ex) {
       throw new EJBException("ejbFindByLastName" + ex.getMessage()); }
     if (result.isEmpty()){
       throw new ObjectNotFoundException("No row found.");
     }    else {
       return result}  }

#p#副标题#e#

应用系统中特定的 finder,如 ejbFindByLastName 和ejbFindInRange,是可选的,可是必需含有 ejbFindByPrimaryKey 要领,ejbFindByPrimaryKey 要领用主键作参数,用来定位一个 entity bean 的状态数据,下面是 ejbFindByPrimaryKey 要领的代码:

public String ejbFindByPrimaryKey(String primaryKey)
     throws FinderException {
     boolean result;
     try {
       result = selectByPrimaryKey(primaryKey);
     } catch (Exception ex) {
       throw new EJBException("ejbFindByPrimaryKey: " + ex.getMessage()); }
     if (result) {
       return primaryKey;
     }
     else {
       throw new ObjectNotFoundException ("Row for id " + primaryKey + " not found.");
     }
   }

ejbFindByPrimaryKey 要领以 primaryKey 作为参数并返回它的值。

留意:

1.只有 EJB 容器可以挪用ejbFindByPrimaryKey,而客户端不能直接挪用 ejbFindByPrimaryKey 要领,客户端只能挪用在 home 接口中界说的 findByPrimaryKey。

2.在 entity bean 类中开拓人员必需实现ejbFindByPrimaryKey 要领。

3.一个 finder 要领的名字必需以 ejbFind 作为前缀。

4.返回值必需是主键可能是一个主键的荟萃。

throw 子句可以包括 javax.ejb.FinderException,和其他此外破例处理惩罚例程。假如一个finder 要领只要求返回独一一个主键,假如主键不存在,则应该执行 javax.ejb.ObjectNotFoundException,ObjectNotFoundException 是FoundException的一个子类;假如 finder 要领要求返回的是一个主键的荟萃,则应该执行 FinderException 来处理惩罚。

业务处理惩罚要领

业务处理惩罚要领包括想在 Entity Bean 中实现的业务处理惩罚逻辑。凡是业务处理惩罚要领不存取数据库,这答允开拓人员可以把业务处理惩罚逻辑从数据库存取中独立出来。

在 AccountEJB entity bean 中包括下面的业务处理惩罚要领:

public void debit(double amount)
     throw InsufficientBalanceException {
     if (balance - amount <0){
       throw new InsufficientBalanceException();
     }
     balance -= amount;
   }
   public void credit (double amount) {
     balance += amount;
   }
   public String getFirstName() {
     return firstName;
   }
   public String getLastName() {
     return lastName;
   }
   public double getBalance() {
     return balance;
   }

AccountClient 措施中挪用业务处理惩罚要领:

Account duke = home.create("123","Duke","Earl",0.00);
Duke.credit(88.50);
Duke.debit(20.25);
Double balance = duke.getBalance();

留意:

1、业务处理惩罚要领的名称不能和 EJB 体系中界说的要领的名称斗嘴,其他的要求和 entity bean 和 sesson bean 中其它要领的要求沟通。

2、可以在throw 子句中包括应用措施界说的破例处理惩罚例程,如 debit 要领执行InsufficientBalanceException。为了识别系统级错误,业务处理惩罚逻辑应该挪用 javax.ejb.EJBException。

下面是对 AccountEJB 类中存取数据库的总结:

因为业务处理惩罚要领中不需要存取数据库,所以在 AccountEJB 类中的业务处理惩罚要领没有存取数据库。但业务处理惩罚要领可以通过 EJB 容器挪用 ejbStore 来修改实例变量。虽然开拓人员也可以在 AccountEJB 类的业务处理惩罚要领中存取数据库,这依赖于应用措施的详细要求,在存取数据库之前必需毗连数据库。

#p#副标题#e#

Home 接口(Interface)

在home 接口中界说让客户端建设和查找 entity bean 的要领。Account Home 接口如下:

#p#分页标题#e#

import java.util.Collection;
   import java.rmi.RemoteException;
   import javax.ejb.*;
   public interface AccountHome extends EJBHome {
     public Account create(String id, String firstName, String lastName, double balance)
       throws RemoteException, CreateException;
      public Account findByPrimaryKey(String id)
       throws FinderException, RemoteException;
       public Collection findByLastName(String lastName)
      throws FinderException, RemoteException;
     public Collection findInRange(double low, double high)
       throws FinderException, RemoteException;
   }

在Home 接口中,每一种finder 要领必需和 entity bean 类中的 finder 要领对应;finder 要领的名称必需以 find 开始,就象 entity bean 类中的 finder 要领必需以 ejbFind 一样,譬喻:AccountHome 类中界说的findByLastName 要领和AccountEJB 类中实现的 ejbFindByLastName 要领。

Remote 接口

Remote 接口界说客户端可以挪用的业务处理惩罚要领,Account remote 接口的代码如下:

import javax.ejb.EJBObject;
   import java.rmi.RemoteException;
   public interface Account extends EJBObject {
     public void debit(double amount)
       throws InsufficientBalanceException, RemoteException;
     public void credit(double amount)
       throws RemoteException;
     public String getFirstName()
       throws RemoteException;
     public String getLastName()
       throws RemoteException;
     public double getBalance()
       throws RemoteException; }

    关键字:

在线提交作业