|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
还有就是总有人问我到底该学习什么语言,什么语言有前途,那么我的回答是不论是C,C++,java,.net,ruby,asp或是其他语言都可以学,编程的关键不是语言,而是思想。 在入手下手会商如何从EJB2.1迁徙到EJB3.0之前,有需要先懂得一下迁徙以后将会失掉甚么:次要来讲,EJB3.0削减了在创立EJB时所需的类、接口、部署形貌符的数目。EJB3.0经由过程用纯新式Java对象(POJO)代替笼统bean类,用纯新式Java接口(POJI)代替组件与主接口(Component&Home),简化了EJB的开辟历程,在此,后者是可选项--你不用全体包括进它们。
部署形貌符--ejb-jar.xml--由其指定了EJB名、bean对象名、接口、查找者办法、容器办理干系(CMR),在此就不再必要其他与开辟商相干的部署形貌符了,由于已被组件类中的元数据正文所代替。这就是你为何必要利用JDK5.0来开辟EJB3.0使用的缘故原由,由于它们利用了正文,而正文在JDK5.0之前不成用。
EJB3.0用javax.persistence.EntityManagerAPI代替了EJB2.1中的查找者办法,一般EJB2.1的客户端使用利用JNDI名来取得一个对实体(entity)及会话(session)bean对象的援用,而EJB3.0客户端使用则是利用@Resource、@Inject和@EJB。
在EJB2.1中,可以使用javax.ejb包装类与接口来开辟实体预会话,在此,一个会话bean完成了SessionBean接口,而一个实体bean完成了EntityBean接口;比拟之下,EJB3.0的会话与实体bean类是POJO,并没有完成SessionBean和EntityBean接口。
一个EJB2.1的会话bean类指定了一个或多个ejbCreate办法、回调办法、setSessionContext办法和营业(business)办法;与此相似,一个EJB2.1实体指定了ejbCreate()、ejbPostCreate()、回调、容量办理耐久性(CMP)、CMR的getter/setter和营业办法。一个EJB3.0会话bean类只指定了营业办法;一样地,一个EJB3.0实体bean只指定了营业办法、对分歧bean属性的getter/setter办法及对bean干系的getter/setter办法。
EJB2.1主接口扩大了javax.ejb.EJBHome接口、尚有一个当地主接口扩大了javax.ejb.EJBLocalHome接口;EJB2.1的远程接口扩大了javax.ejb.EJBObject接口,尚有一个当地接口扩大了javax.ejb.EJBLocalObject接口。在EJB3.0中,并没有指定组件与主接口--它们已被POJI代替,假如一个会话bean类没有指定一个营业接口,那末EJB服务器将从会话bean类中为它天生一个POJI营业接口。
请在脑海中记着这些变更,本文的后续部分,将用两个示例来会合报告把一个会话bean和一个实体bean,从EJB2.1迁徙到EJB3.0时所需的具体信息。
迁徙会话bean
示例中的EJB2.1会话bean类--BookCatalogBean--指定了一个ejbCreate办法、一个称为getTitle()的营业办法和一个回调办法:
//BookCatalogBean.java
importjavax.ejb.SessionBean;
importjavax.ejb.SessionContext;
publicclassBookCatalogBeanimplementsSessionBean
{
privateSessionContextctx;
publicStringgetEdition(Stringtitle)
{
if(title.equals("Java&XML"))
returnnewString("第二个版本");
if(title.equals("JavaandXSLT"))
returnnewString("第一个版本");
}
publicvoidejbCreate(){}
publicvoidejbRemove(){}
publicvoidejbActivate(){}
publicvoidejbPassivate(){}
publicvoidsetSessionContext(SessionContextctx)
{this.ctx=ctx;}
}
在EJB3.0会话bean中,可以使用元数据正文来指定bean范例,即便用@Stateful和@Stateless来分离指定Stateful(有形态)或Stateless(无形态)。也可在一个会话bean顶用一个营业接口来代替组件与主接口,由于营业接口是一个POJI,以是可用@Local和@Remote来指定其为当地或远程范例,而一个会话bean可同时完成当地与远程接口。
假如在bean类不指定接口范例(当地或远程),那EJB服务器在默许情形下会主动天生一个当地营业接口,在此也可以使用@Local和@Remote正文来指定接口类。
上面的EJB3.0会话bean是一个POJO,其由后面的BookCatalogBean.javaEJB2.1无形态会话bean移植而来,注重它利用了@Stateless正文,完成了一个当地营业接口,并在@Local正文中指定了当地接口类名。
//BookCatalogBean.javaEJB3.0SessionBean
@Stateless
@Local({BookCatalogLocal.java})
publicclassBookCatalogBeanimplements
BookCatalogLocal
{
publicStringgetEdition(Stringtitle)
{
if(title.equals("Java&XML"))
returnnewString("第二个版本");
if(title.equals("JavaandXSLT"))
returnnewString("第一个版本");
}
}
别的,也要注重,经由过程@Local正文,下面的EJB3.0bean类用一个当地营业接口(POJI)代替了EJB2.1中的组件与主接口。
<P> 迁徙EJB会话bean客户端
一个EJB2.1会话bean的客户端经由过程利用JNDI名可获得一个会话bean对象,以下所示的客户端利用了BookCatalogLocalHome的JNDI名获得一个当地主对象,接着挪用了create()办法,随后,客户端用getEdition(String)营业办法输入特定题目的版本值。
importjavax.naming.InitialContext;
publicclassBookCatalogClient
{
publicstaticvoidmain(String[]argv)
{
try{
InitialContextctx=newInitialContext();
Objectobjref=ctx.lookup("BookCatalogLocalHome");
BookCatalogLocalHomecatalogLocalHome=(BookCatalogLocalHome)objref;
BookCatalogLocalcatalogLocal=(BookCatalogLocal)catalogLocalHome.
create();
Stringtitle="JavaandXML";
Stringedition=catalogLocal.getEdition(title);
System.out.println("题目的版本:"+title+""+edition);
}
catch(Exceptione){}
}
}
在EJB3.0中,可经由过程依附性注进,来猎取一个对会话bean对象的援用,这一般由@Inject、@Resource、@EJB正文来完成。以下所示的EJB3.0会话bean客户端利用了@Inject正文注进到BookCatalogBean类中,仍可由getEdition(String)营业办法来猎取题目的版本值。
publicclassBookCatalogClient
{
@InjectBookCatalogBean;
BookCatalogBeancatalogBean;
Stringtitle="JavaandXML";
Stringedition=catalogBean.getEdition(edition);
System.out.println("题目版本:"+title+""+edition);
}
迁徙实体bean
本节报告怎样迁徙EJB2.1的实体bean到EJB3.0。一个EJB2.1实体bean完成了EntityBean接口,其由getter和setterCMP字段办法、getter和setterCMR字段办法、回调办法及ejbCreate/ejbPostCreate办法构成。示例实体bean(见例1)--BookCatalogBean.java,由CMP字段题目、作者、刊行者和CMR字段版本构成。
例1:BookCatalogBean.java
importjavax.ejb.EntityBean;
importjavax.ejb.EntityContext;
publicclassBookCatalogBeanimplementsEntityBean
{
privateEntityContextctx;
publicabstractvoidsetTitle();
publicabstractStringgetTitle();
publicabstractvoidsetAuthor();
publicabstractStringgetAuthor();
publicabstractvoidsetPublisher();
publicabstractStringgetPublisher();
publicabstractvoidsetEditions(java.util.Collectioneditions);
publicabstractjava.util.CollectiongetEditions();
publicStringejbCreate(Stringtitle)
{
setTitle(title);
returnnull;
}
publicvoidejbRemove(){}
publicvoidejbActivate(){}
publicvoidejbPassivate(){}
publicvoidejbLoad(){}
publicvoidejbStore(){}
publicvoidsetEntityContext(EntityContextctx)
{
this.ctx=ctx;
}
publicvoidunsetEntityContext()
{
ctx=null;
}
}
而这个EJB2.1实体bean的ejb-jar.xml部署形貌符(见例2)文件,指定了EJB类、接口、CMP字段、EJBQL查询和CMR干系。BookCatalogBean实体Bean界说了一个查找办法findByTitle()、一个CMR字段及版本。
例2:ejb-jar.xml部署形貌符
<?xmlversion="1.0"?>
<!DOCTYPEejb-jarPUBLIC
"-//SunMicrosystems,Inc.//DTDEnterpriseJavaBeans2.0//EN"
"http://java.sun.com/dtd/ejb-jar_2_0.dtd">
<ejb-jar>
<enterprise-beans>
<entity>
<ejb-name>BookCatalog</ejb-name>
<local-home>BookCatalogLocalHome</local-home>
<local>BookCatalogLocal</local>
<ejb-class>BookCatalogBean</ejb-class>
<persistence-type>Container</persistence-type>
<prim-key-class>String</prim-key-class>
<reentrant>False</reentrant>
<cmp-version>2.x</cmp-version>
<abstract-schema-name>BookCatalog</abstract-schema-name>
<cmp-field>
<field-name>title</field-name>
</cmp-field>
<cmp-field>
<field-name>author</field-name>
</cmp-field>
<cmp-field>
<field-name>publisher</field-name>
</cmp-field>
<query>
<query-method>
<method-name>findByTitle</method-name>
<method-params>
<method-param>java.lang.String</method-param>
</method-params>
</query-method>
<ejb-ql>
<![CDATA[SELECTDISTINCTOBJECT(obj)FROMBookCatalogobjWHEREobj.title=?1]]>
</ejb-ql>
</query>
</entity>
</enterprise-beans>
<relationships>
<ejb-relation>
<ejb-relation-name>BookCatalog-Editions</ejb-relation-name>
<ejb-relationship-role>
<ejb-relationship-role-name>
BookCatalog-Has-Editions
</ejb-relationship-role-name>
<multiplicity>One</multiplicity>
<relationship-role-source>
<ejb-name>BookCatalog</ejb-name>
</relationship-role-source>
<cmr-field>
<cmr-field-name>editions</cmr-field-name>
<cmr-field-type>java.util.Collection</cmr-field-type>
</cmr-field>
</ejb-relationship-role>
<ejb-relationship-role>
<ejb-relationship-role-name>
Editions-Belong-To-BookCatalog
</ejb-relationship-role-name>
<multiplicity>One</multiplicity>
<cascade-delete/>
<relationship-role-source>
<ejb-name>Edition</ejb-name>
</relationship-role-source>
</ejb-relationship-role>
</ejb-relation>
</relationships>
</ejb-jar>
<P> 比拟之下,对应于EJB2.1实体bean类的EJB3.0实体Bean类是一个纯新式Java对象(POJO),而且十分复杂(请看例3)。此bean类的EJB3.0版本利用了元数据正文@Entity,而EJB2.1部署形貌符ejb-jar.xml文件顶用元素符指定的查找办法,在EJB3.0Bean类中,则利用@NamedQueries和@NamedQuery正文来指定;ejb-jar.xml文件顶用元素符指定的CMR干系,在EJB3.0Bean类中,则用元数据正文来指定;别的,次要的关头字段经由过程@Id正文来指定。表1中列出了一些EJB3.0的元数据正文。
例3:BookCatalogBean.java
importjavax.persistence.Entity;
importjavax.persistence.NamedQuery;
importjavax.persistence.Id;
importjavax.persistence.Column;
importjavax.persistence.OneToMany;
@Entity
@NamedQuery(name="findByTitle",queryString=
"SELECTDISTINCTOBJECT(obj)FROMBookCatalogobjWHEREobj.title=?1")
publicclassBookCatalogBean
{
publicBookCatalogBean(){}
publicBookCatalogBean(Stringtitle)
{
this.title=title;
}
privateStringtitle;
privateStringauthor;
privateStringpublisher;
@Id
@Column(name="title",primaryKey="true")
publicStringgetTitle(){returntitle;}
publicvoidsetTitle(){this.title=title;}
publicvoidsetAuthor(Stringauthor){this.author=author;}
publicStringgetAuthor(){returnauthor;}
publicvoidsetPublisher(Stringpublisher)
{
this.publisher=publisher;
}
publicStringgetPublisher(){returnpublisher;}
privatejava.util.Collection<Edition>editions;
@OneToMany
publicvoidsetEditions(java.util.Collectioneditions)
{
this.editions=editions;
}
publicjava.util.CollectiongetEditions(){returneditions;}
}
表1:EJB3.0经常使用元数据正文
正文申明正文元素@Entity说明一个实体bean类。@Table说明实体bean表。假如未指定@Table,表名与EJB名不异。name,schema@Id说明一个次要关头属性或字段。@Transient说明一个非耐久性属性或字段。@Column为一个耐久性实体bean属性说明一个映照栏。Name、primaryKey、nullable、length。默许栏名为属性或字段名。@NamedQueries说明一组定名查询。@NamedQuery说明一个定名查询或与查找办法相干的查询。name,queryString@OneToMany说明一个一对多接洽。Cascade@OneToOne说明一个一对一接洽。Cascade@ManyToMany说明一个多对多接洽。Cascade@ManyToOne说明一个多对一接洽。Cascade
EJB2.1bean类中的查找办法findByTitle(),在EJB3.0中则利用响应的@namedQuery正文;EJB2.1实体bean中的CMR干系,在EJB3.0实体bean中则利用@OnetoMany正文。正文@Id说明了标识符属性题目,正文@Column指定了与标识符属性题目对应的数据库栏。假如一个耐久性实体bean属性未用@Column说明,那EJB服务器会假定栏名与实体bean属性名不异。而瞬态实体bean属性一般用@Transient来说明。
<P> 迁徙EJB实体Bean客户端
你可在实体bean主接口或当地主接口中利用create()办法,来创立一个EJB2.1实体bean主对象或当地主对象。一般,一个EJB2.1实体bean的客户端可经由过程JNDI查找来猎取一个实体bean的当地或远程对象。上面有一段示例代码,其创立了一个EJB2.1实体bean的当地主对象。
InitialContextctx=newInitialContext();
Objectobjref=ctx.lookup("BookCatalogLocalHome");
BookCatalogLocalHomecatalogLocalHome=(BookCatalogLocalHome)objref;
在下面的代码段中,BookCatalogLocalHome是BookCatalogBean实体bean的JNDI名。
在失掉一个援用以后,EJB2.1的客户端经由过程create()办法创立了一个当地对象。
BookCatalogLocalcatalogLocal=(BookCatalogLocal)
catalogLocalHome.create(title);
在EJB2.1中,可经由过程查找办法,从一个当地主对象中获得一个当地或远程对象。比方,你可像以下所示经由过程findByPrimaryKey办法获得一个当地对象。
BookCatalogLocalcatalogLocal=(BookCatalogLocal)
catalogLocalHome.findByPrimaryKey(title);
别的在EJB2.1中,可以使用remove()办法移除一个实体bean的实例:
catalogLocal.remove();
EJB3.0经由过程javax.persistence.EntityManager类完成了耐久性、查找和移除。表2列出了EntityManager类顶用于代替EJB2.1办法的一些经常使用办法。
表2:EntityManager类办法
EntityManager办法形貌persist(Objectentity)使一个实体bean实例耐久化。createNamedQuery(Stringname)创立一个Query对象的实例,以实行定名查询。find(ClassentityClass,ObjectprimaryKey)查找一个实体bean实例。createQuery(StringejbQl)创立一个Query对象,以运转EJBQL查询。remove(Objectentity)移除实体bean的一个实例。
在EJB3.0实体bean的客户类中,可以使用@Resource正文来注进EntityManager对象。
@Resource
privateEntityManagerem;
可挪用EntityManager.persist()办法来使一个实体bean的实例耐久化,比方:
BookCatalogBeancatalogBean=newBookCatalogBean(title);
em.persist(catalogBean);
相似地,可挪用EntityManager.find()办法来获得一个实体bean的实例。
BookCatalogBeancatalogBean=(BookCatalogBean)
em.find("BookCatalogBean",title);
在此还能够界说一个相称于定名查询findByTitle的EJB3.0客户类查找办法(与EJB2.1中的查找办法可纷歧样),用createNamedQuery(String)办法获得一个Query对象。
Queryquery=em.createNamedQuery("findByTitle");
经由过程setParameter(intparamPosition,StringparamValue)或setParameter(StringparameterName,Stringvalue)办法设置Query对象的参数,注重此处的参数地位是从0入手下手的。
query.setParameter(0,title);
利用Query.getResultList()办法获得BookCatalogBean对象的一个汇合,假如断定查询只前往一个单一的了局,还可使用getSingleResult()办法取代。
java.util.CollectioncatalogBeanCollection=(BookCatalogBean)query.getResultList();
最初,用EntityManager.remove(Objectentity)办法移除实体bean的实例。
BookCatalogBeancatalogBean;
em.remove(catalogBean);
例4演示了一个完全的EJB3.0实体bean的无形态会话bean客户类。
例4:BookCatalogClient类
importjavax.ejb.Stateless;
importjavax.ejb.Resource;
importjavax.persistence.EntityManager;
importjavax.persistence.Query;
@Stateless
@Local
publicclassBookCatalogClientimplementsBookCatalogLocal
{
@Resource
privateEntityManagerem;
publicvoidcreate(Stringtitle)
{
BookCatalogBeancatalogBean=newBookCatalogBean(title);
em.persist(catalogBean);
}
publicBookCatalogBeanfindByPrimaryKey(Stringtitle)
{
return(BookCatalogBean)em.find("BookCatalogBean",title);
}
publicjava.util.CollectionfindByTitle(Stringtitle)
{
Queryquery=em.createNamedQuery("findByTitle");
query.setParameter(0,title);
return(BookCatalogBean)query.getResultList();
}
publicvoidremove(BookCatalogBeancatalogBean)
{
em.remove(catalogBean);
}
}
以上的示例演示了怎样把一个会话bean和实体bean从EJB2.1迁徙到EJB3.0,从EJB2.0迁徙的情形也与此相似。
在本文脱稿时,已有一些使用服务器撑持EJB3.0标准,如JBoss使用服务器、Oracle使用服务器及Caucho使用服务器。不幸的是,这些使用服务器对EJB3.0的完成会有所分歧----它们大概没有完成全体的EJB3.0特征,以是,在入手下手编写程序之前,必定要细心浏览相干使用服务器供应的文档申明。
手机用到的是用j2me所编出来的小程序。 |
|