
前进:从EJB 2.1到EJB 3.0(4) |
||||||||||||||||||||||||||||||||||||||||||||||||
表1:EJB 3.0常用元数据注释
EJB 2.1 bean类中的查找方法findByTitle(),在EJB 3.0中则使用相应的@namedQuery注释;EJB 2.1实体bean中的CMR关系,在EJB 3.0实体bean中则使用@OnetoMany注释。注释@Id注明了标识符属性标题,注释@Column指定了与标识符属性标题对应的数据库栏。如果一个持久性实体bean属性未用@Column注明,那EJB服务器会假定栏名与实体bean属性名相同。而瞬态实体bean属性通常用@Transient来注明。
迁移EJB实体Bean客户端 InitialContext ctx=new InitialContext(); Object objref=ctx.lookup("BookCatalogLocalHome"); BookCatalogLocalHome catalogLocalHome = (BookCatalogLocalHome)objref; 在上面的代码段中,BookCatalogLocalHome是BookCatalogBean实体bean的JNDI名。 在得到一个引用之后,EJB 2.1的客户端通过create()方法创建了一个本地对象。 BookCatalogLocal catalogLocal = (BookCatalogLocal) catalogLocalHome.create(title); 在EJB 2.1中,可通过查找方法,从一个本地主对象中取得一个本地或远程对象。例如,你可像如下所示通过findByPrimaryKey方法取得一个本地对象。 BookCatalogLocal catalogLocal = (BookCatalogLocal) catalogLocalHome.findByPrimaryKey(title); 另外在EJB 2.1中,可使用remove()方法移除一个实体bean的实例: catalogLocal.remove(); EJB 3.0通过javax.persistence.EntityManager类实现了持久性、查找和移除。表2列出了EntityManager类中用于取代EJB 2.1方法的一些常用方法。 表2:EntityManager类方法
在EJB 3.0实体bean的客户类中,可使用@Resource注释来注入EntityManager对象。 @Resource private EntityManager em; 可调用EntityManager.persist()方法来使一个实体bean的实例持久化,例如: BookCatalogBean catalogBean = new BookCatalogBean (title); em.persist(catalogBean); 类似地,可调用EntityManager.find()方法来取得一个实体bean的实例。 BookCatalogBean catalogBean = (BookCatalogBean) em.find("BookCatalogBean", title); 在此还可以定义一个相当于命名查询findByTitle的EJB 3.0客户类查找方法(与EJB 2.1中的查找方法可不一样),用createNamedQuery(String)方法取得一个Query对象。 Query query=em.createNamedQuery("findByTitle"); 通过setParameter(int paramPosition, String paramValue)或setParameter(String parameterName, String value)方法设置Query对象的参数,注意此处的参数位置是从0开始的。 query.setParameter(0, title); 使用Query.getResultList()方法取得BookCatalogBean对象的一个集合,如果确定查询只返回一个单一的结果,还可以使用getSingleResult()方法代替。 java.util.Collection catalogBeanCollection = (BookCatalogBean)query.getResultList(); 最后,用EntityManager.remove(Object entity)方法移除实体bean的实例。 BookCatalogBean catalogBean; em.remove(catalogBean); 例4演示了一个完整的EJB 3.0实体bean的无状态会话bean客户类。 例4:BookCatalogClient类 import javax.ejb.Stateless; import javax.ejb.Resource; import javax.persistence.EntityManager; import javax.persistence.Query; @Stateless @Local public class BookCatalogClient implements BookCatalogLocal { @Resource private EntityManager em; public void create(String title) { BookCatalogBean catalogBean=new BookCatalogBean(title); em.persist(catalogBean); } public BookCatalogBean findByPrimaryKey(String title) { return (BookCatalogBean)em.find("BookCatalogBean", title); } public java.util.Collection findByTitle(String title) { Query query=em.createNamedQuery("findByTitle"); query.setParameter(0, title); return (BookCatalogBean)query.getResultList(); } public void remove(BookCatalogBean catalogBean) { em.remove(catalogBean); } } 以上的示例演示了如何把一个会话bean和实体bean从EJB 2.1迁移到EJB 3.0,从EJB 2.0迁移的情况也与此类似。 在本文完稿时,已有一些应用服务器支持EJB 3.0规范,如JBoss应用服务器、Oracle应用服务器及Caucho应用服务器。不幸的是,这些应用服务器对EJB 3.0的实现会有所不同----它们可能没有实现全部的EJB 3.0特性,所以,在开始编写程序之前,一定要仔细阅读相关应用服务器提供的文档说明。 |
||||||||||||||||||||||||||||||||||||||||||||||||