Enterprise JavaBean(EJB)

转贴自 http://www.blogjava.net/mrklmxy/archive/2007/09/13/144659.html

 

Enterprise JavaBean(EJB)

a.Enterprise JavaBeans (EJBs) are a part of the Java 2 Enterprise Edition specifications

b.Some Problems Within The Distribution Application

(Distributed, Transactional ,Persistent)



 

1.  Ejb主要包括:Session Bean(业务逻辑),Entity Bean(业务数据),Message Driven Bean

2.  Ejb远程调用的核心:RMI—>Client –(RMI-IIOP)协议—ejb home

3.  EjbBean远程访问的基础:Seriliable,因为不同接口继承了Remote,所以bean要通过网络传播只能序列化才行,常见的数据类型如:String,Double都是已经可以序列化的

.wsadejb实例:

1新建Enterprise Application Project—>选择New Moduleejb+clientà创建Stateless SessionBeanà Finish。生成了三个类:Home Object,EJB Object,SessionBean

2.代码如下:a. Home Object :

public interface SayHelloHome extends javax.ejb.EJBHome {

public mypack.SayHello create()

        throws javax.ejb.CreateException, java.rmi.RemoteException; }

  b. EJB Object

import java.rmi.RemoteException;

public interface SayHello extends javax.ejb.EJBObject {

        public void sayHello()throws RemoteException;  }

c. public class SayHelloBean implements javax.ejb.SessionBean {

   private javax.ejb.SessionContext mySessionCtx;

   public void sayHello(){  System.out.println("nihao");   }

   public javax.ejb.SessionContext getSessionContext() {

       return mySessionCtx;    }

   public void setSessionContext(javax.ejb.SessionContext ctx) {

       mySessionCtx = ctx; }

   public void ejbCreate() throws javax.ejb.CreateException {  }

   public void ejbActivate() { }      //交给缓冲池管理挂起和激活

   public void ejbPassivate() {    }

   public void ejbRemove() {   }  }

 

 c.Generate部署并生成远程代码ejb-jar.xml,主要作用是产生stubSkeleton,产生的内容:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN" "http://java.sun.com/dtd/ejb-jar_2_0.dtd">

<ejb-jar id="ejb-jar_ID">

    <enterprise-beans>

        <session id="SayHello">

  <ejb-name>SayHello</ejb-name>

            <home>mypack.SayHelloHome</home>

            <remote>mypack.SayHello</remote>

            <ejb-class>mypack.SayHelloBean</ejb-class>

            <session-type>Stateless</session-type>

            <transaction-type>Container</transaction-type>

        </session>

    </enterprise-beans>

</ejb-jar>

双击ejbModule可以得到jndi地址:ejb/mypack/sayHelloHome-----à运行服务器

 

 

3.编写测试:a.new Client, EJB Module加到build path中:

  b.编写测试类:public class HelloTest {

   public static void main(String args[])throws Exception{

   InitialContext ctx=new InitialContext();

SayHelloHome home=(SayHelloHome) ctx.lookup("ejb/mypack/sayHelloHome");

   SayHello hello=home.create();   hello.sayHello();    }}

  c. 添加测试类运行期依赖的EJB组件,右击—>open with jar—>钩选ejb.jarà找到main class

d.运行测试类(确定你的WebSphere已经启动):即先要启动Servers下的服务器后才可以

  run as application client,在客户端看到的是客户端的内容,服务器断才能看到服务器结果

(也可以将打包的jar导入到eclipse的进行了封装,然后调用测试)

 

 

三.Entity bean RDBMS的视图,分为CMPBMP两种

1.CMP实例:

a.Create ejb to RDB mapping-à加载数据库的驱动—>根据数据库表结构生成CMP EntityBeanàbottom Upà填写包名就可以自动创建了entity bean

映射方式一共有三种:
bottom-up:通过数据库表直接生成相应的cmp
top-down:通过已有的entity bean生成相应的数据库表
meet-in-the-middle:前两者汇合



 

b.LocalHome:

public interface AccountLocalHome extends javax.ejb.EJBLocalHome {

    public mypack.AccountLocal create(java.lang.String id)

        throws javax.ejb.CreateException;

    public mypack.AccountLocal findByPrimaryKey(mypack.AccountKey primaryKey)

        throws javax.ejb.FinderException;}

c. public interface AccountLocal extends javax.ejb.EJBLocalObject { //业务方法

public java.lang.String getOwername();

  public void setOwername(java.lang.String newOwername);

  public java.lang.Double getBalance();

   public void setBalance(java.lang.Double newBalance); }

d. public abstract class AccountBean implements javax.ejb.EntityBean {

  private javax.ejb.EntityContext myEntityCtx;

  public void setEntityContext(javax.ejb.EntityContext ctx) {

      myEntityCtx = ctx;  }

  public javax.ejb.EntityContext getEntityContext() {return myEntityCtx;  }

  public void unsetEntityContext() {  myEntityCtx = null; }

  public mypack.AccountKey ejbCreate(java.lang.String id)

      throws javax.ejb.CreateException {  setId(id);  return null;    }

  public void ejbPostCreate(java.lang.String id)

      throws javax.ejb.CreateException {  }

  public void ejbActivate() { }

  public void ejbLoad() { }

  public void ejbPassivate() {    }

  public void ejbRemove() throws javax.ejb.RemoveException {  }

  public void ejbStore() {    }

  public abstract java.lang.String getOwername();

  public abstract void setOwername(java.lang.String newOwername);

  public abstract java.lang.Double getBalance();

  public abstract void setBalance(java.lang.Double newBalance);

  public abstract java.lang.String getId();

  public abstract void setId(java.lang.String newId);   }

 

e. public class AccountKey implements java.io.Serializable { //一定要可序列化的

    static final long serialVersionUID = 3206093459760846163L;

    public java.lang.String id; public AccountKey() {   }

    public AccountKey(java.lang.String id) {    this.id = id;   }

    public boolean equals(java.lang.Object otherKey) {

        if (otherKey instanceof mypack.AccountKey) {

            mypack.AccountKey o = (mypack.AccountKey) otherKey;

            return ((this.id.equals(o.id)));        }   return false;   }

    public int hashCode() { return (id.hashCode()); }  }

f.部署generate,生成ejb-jar.xml对主键,由容器管理,对应的字段映射进行描述

g. 打开server进行配置security,添加用户的访问密码和用户名(jaas)

h. 采用数据源的方式和数据库进行连接(websphere数据源):serveràdate source

  àadd listàdb2 jdbc Provideràdefine jdbcà改变数据源jndi地址-à改变databaseName

i. 配置EJB组件访问DataSource-àcmp open with Deployment Descriptionà改成自设jndi地址

 



2.CMP
方法详述:

  a.context变量:将成员变量,安全信息和环境属性等放在上下文中

  b.跟单行纪录相关的业务逻辑方法,是abstract的,由容器去生成jdbc代码,工具生成接口

  c.Home接口中的跟整个数据库有关的业务逻辑方法,findAll不是单条记录对应的entity

  d.entity bean必须的方法,用于管理,load将数据库中放到内存,store相反

 f.容器自动调用的方法,不含jdbc,entityBean中继承来的

 

3.CMPBMP的比较:

a.cmp是模拟bmp的,cmp没有持久化字段,没有get.set方法,都是从ejb-jar.xml中读取

b.cmp bean classabstract,标明由容器去实现

c.cmp中对数据库的操作可以写成抽象方法,由容器去实现

 

 

 

2. item添加EJBQL:打开EJB部署描述文件(ejb-jar.xml),找到Bean Item,添加Queriesà

   方法名为findAll-à返回为collection  即:select object(o) from item o



3.
entity bean配置Transaction:切换到“Assembly Descriptor”页:为Requried

  事务:一系列方法的集合,同时成功,不成功可以回滚同时失败。相当于jdbcconnectionrollback;类型如下:

a.       supports:A事务运动,B发现有就加入这一事务中,没有就算

b.     notSupported:A有没有都不加入,B不一定是事务,B执行,A挂起,B重开启事务

c.     required:上下文中A有就加入,没有就new一个事务

d.     requiresNew:都自己去启动一个事务, B要执行,A挂起,B不加入别人事务

e.     mandatory:强制独裁,事务A必须有,没有B就报错

f.     never:有事务在B之前就抛异常,没有就算



4
修改实体关系:切换到“Overview”页,找到relationships关联关系,编辑关系的导航性

   一般只是单导航性



 

5.创建值对象(Value Objects):只要是传递entity bean对象,供sessionbean调用

切换到“Project Navigator”页,新建Java ProjectSalesValueObjects

a.     ItemVo:Long id;String name; //setter/getter方法     //必须要实现Serialiable接口

b.     LocationVoString city;String state;String zipcode;String areaCode;  //setter/getter

  

6.
SalesValueObjects project加到sales project中:整个应用中

打开“EAR Deployment Descriptor”(META-INF/application.xml),切换“Module”页:

--à 选中Project Utility JARs

 

7创建业务层 ---- Stateless SessionBeanSalesFacade

  
8.
下面配置SessionBean访问EntityBean的本地引用  sessionentity bean 关联

打开“EJB Development Descriptor”(META-INF/ejb-jar.xml),切换“References”页

---àejb local reference,因为entity bean 都是local

   9.在EJB组件中添加对SalesValueObjects project的依赖àopen with jar dependency editor



 

10. SalesFacade中添加三个业务方法(Remote接口的EJB OBJECT)

public LocationVo getLocation(String zipCode)throws RemoteException;

public ItemVo[] getAllItems()throws RemoteException;

public boolean makePurchase(String zipCode,Long[] itemIds)throws RemoteException;

   11.为了业务方法能够得到EntityBean ItemitemId,在ItemKey中添加get()方法:

  

12SalesFacadeBean中实现业务方法:如:

public LocationVo getLocation(String zipCode){

            final String locRef="java:comp/env/ejb/Location";

            LocationVo locationVo=new LocationVo();

            try{    Context ctx=new InitialContext();

            LocationLocalHome locationHome=(LocationLocalHome)ctx.lookup(locRef);

    LocationLocal location=locationHome.findByPrimaryKey(new LocationKey(zipCode));

    locationVo.setAreaCode(location.getAreacode());locationVo.setZipCode(zipCode);

locationVo.setCity(location.getCity());locationVo.setState(location.getState());

    }catch(NamingException ne){throw new EJBException(ne);

    }catch(FinderException fe){     return locationVo;  }  return locationVo;}

 

findByPrimaryKeyhome中为entity bean 创建的主键查找方法

new LocationKey(zipCode)key中的一个构造方法

 

public ItemVo[] getAllItems(){

    final String itRef="java:comp/env/ejb/Item";  ItemVo[] itemVos=null;

        try{    Context ctx=new InitialContext();

            ItemLocalHome itemHome=(ItemLocalHome)ctx.lookup(itRef);

            Collection items=itemHome.findAll();//home中添加查找这个数据库的方法

            if(items!=null){

                itemVos=new ItemVo[items.size()];

                int i=0;

                for(Iterator it=items.iterator();it.hasNext();i++){

                    ItemLocal item=(ItemLocal)it.next();    ItemVo vo=new ItemVo();

                    vo.setItemId(((ItemKey)item.getPrimaryKey()).getItemid());

                    vo.setName(item.getName()); itemVos[i]=vo;} }

        }catch(NamingException ne){ throw new EJBException(ne);

        }catch(FinderException fe){return new ItemVo[0];}   return itemVos; }

 

13创建Web:添加Web ModuleSalesValueObjects projectEJB Module的依赖

14.添加Web ModuleEJB的引用:

打开“Web Development Descriptor”(WEB-INF/web.xml),切换到“References


绝大多数情况下web采用了struts,可以在action中lookup homeobject.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值