关于EJB--实体Bean的BMP和CMP选择

EJB有两种主要类型BMP(Bean managed persistence )和CMP(Container managed persistence ),这两种类型各有优缺点。

BMP是在Bean中完成对数据库JDBC的各种调用,也就是说,在你的实体bean(entity bean)中,明确写入了SQL语句,如"insert .. "或"select ..",并且使用Datasource获得一个数据库资源以及连接(connection)从而对数据库直接进行增加删除修改。

CMP是由EJB容器自动完成对数据库的操作,你所有做的,就是在实体bean重写入SetXXX或getXXX方法,然后在ejb-jar.xml中定义cmp-field就可以。

很明显,CMP编写要简单多,而且数据库操作由EJB容器完成应该是一种趋势,但是CMP有个缺点就是不够灵活,如果我们要完成类似SQL搜索语句的like命令,如"select * from A where name like ‘%banqiao‘",CMP就无法自动帮助我们完成,这样我们就需要BMP自己来写。

在实际应用,一般为了效率考虑,我们尽量使用CMP,但如何为将来有可能使用BMP作好准备,就是说有可以延伸到BMP的基础。EJB 2.0对CMP的抽象类支持为我们提供了这种实现的基础。

总体思路是,先使用抽象类完成CMP 如果需要BMP 可以extend这个抽象类,然后覆盖原来的方法(用自己的特殊SQL语句操作来覆盖该方法)。

以Java 宠物店(Java Pet Store Demo 1.3)中的地址实体bean:AddressEJB为例:

Java代码  

  1. public abstract class AddressEJB implements EntityBean {
  2. private EntityContext context = null;
  3. // getters and setters for PO CMP fields
  4. public abstract String getFirstName();
  5. public abstract void setFirstName(String name);
  6. public abstract String getLastName();
  7. public abstract void setLastName(String name);
  8. public abstract String getStreet1();
  9. public abstract void setStreet1(String name);
  10. public abstract String getStreet2();
  11. public abstract void setStreet2(String name);
  12. public abstract String getCity();
  13. public abstract void setCity(String name);
  14. public abstract String getState();
  15. public abstract void setState(String name);
  16. public abstract String getCountry();
  17. public abstract void setCountry(String name);
  18. public abstract String getZip();
  19. public abstract void setZip(String name);
  20. public Object ejbCreate(
  21. String fName,
  22. String lName,
  23. String s1,
  24. String s2,
  25. String cy,
  26. String st,
  27. String cnty,
  28. String pcode)
  29. throws CreateException {
  30. setFirstName(fName);
  31. setLastName(lName);
  32. setStreet1(s1);
  33. setStreet2(s2);
  34. setCity(cy);
  35. setState(st);
  36. setCountry(cnty);
  37. setZip(pcode);
  38. return null;
  39. }
  40. public void ejbPostCreate(
  41. String fName,
  42. String lName,
  43. String street1,
  44. String street2,
  45. String city,
  46. String state,
  47. String country,
  48. String zip)
  49. throws CreateException {
  50. }
  51. public void setEntityContext(EntityContext c) {
  52. context = c;
  53. }
  54. public void unsetEntityContext() {
  55. }
  56. public void ejbRemove() throws RemoveException {
  57. }
  58. public void ejbActivate() {
  59. }
  60. public void ejbPassivate() {
  61. }
  62. public void ejbStore() {
  63. }
  64. public void ejbLoad() {
  65. }
  66. }

在上面的AddressEJB中,我们看到只有setXXX或getXXX的方法。

在相应的部署描述文件ejb-jar.xml中我们看到:

Java代码  

  1. <entity>
  2.   <display-name>AddressEJB</display-name>
  3.   <ejb-name>AddressEJB</ejb-name>
  4.   <local-home>com.sun.j2ee.blueprints.address.ejb.AddressLocalHome</local-home>
  5.   <local>com.sun.j2ee.blueprints.address.ejb.AddressLocal</local>
  6.   <ejb-class>com.sun.j2ee.blueprints.address.ejb.AddressEJB</ejb-class>
  7.   <persistence-type>Container</persistence-type>
  8.   <prim-key-class>java.lang.Object</prim-key-class>
  9.   <reentrant>False</reentrant>
  10.   <cmp-version>2.x</cmp-version>
  11.   <abstract-schema-name>Address</abstract-schema-name>
  12.   <cmp-field>
  13.     <field-name>firstName</field-name>
  14.   </cmp-field>
  15.   <cmp-field>
  16.     <field-name>lastName</field-name>
  17.   </cmp-field>
  18.   <cmp-field>
  19.     <field-name>street1</field-name>
  20.   </cmp-field>
  21.   <cmp-field>
  22.     <field-name>street2</field-name>
  23.   </cmp-field>
  24.   <cmp-field>
  25.     <field-name>city</field-name>
  26.   </cmp-field>
  27.   <cmp-field>
  28.     <field-name>state</field-name>
  29.   </cmp-field>
  30.   <cmp-field>
  31.     <field-name>country</field-name>
  32.   </cmp-field>
  33.   <cmp-field>
  34.     <field-name>zip</field-name>
  35.   </cmp-field>
  36.   <security-identity>
  37.     <description></description>
  38.     <use-caller-identity></use-caller-identity>
  39.   </security-identity>
  40. </entity>

在上面部署文件中,标明了Address数据库字段:

firstName,lastName,street1,street2,city,state,country,zip

一旦我们要使用BMP, 只要继承上面的CMP bean:

public class AddressBeanBMP extends AddressEJB {

用我们自己的BMP方法覆盖AddressEJB中的方法:

ejbLoad() -->从数据库中获取数据(SELECT) 
ejbStore() -->修改数据库数据UPDATE) 
ejbRemove() -->删除数据库数据(DELETE) 
ejbCreate() -->插入新的数据记录(INSERT) 
ejbFindByPrimaryKey(primary key) --> 确保 primary key 存在. 
ejbFindAllPrimaryKey() -->自己的定义 返回一个primary key所有数据记录的collectionxiam

下面以ejbCreate()为例:

Java代码  

    1. public Object ejbCreate(
    2. String fName,
    3. String lName,
    4. String s1,
    5. String s2,
    6. String cy,
    7. String st,
    8. String cnty,
    9. String pcode)
    10. throws CreateException {
    11. // insert row into database
    12. this.fName = fName;
    13. this.lName = lName;
    14. this.s1 = s1;
    15. this.s2 = s2;
    16. this.cy = cy;
    17. this.st = st;
    18. this.cnty = cnty;
    19. this.pcode = pcode;
    20. // Insert database record
    21. try {
    22. Connection connection = getConnection();
    23. PreparedStatement statement =
    24. connection.prepareStatement(
    25. "INSERT INTO Address (firstName,lastName,street1,street2,city,state,country,zip) VALUES (?, ?, ?,?,?,?)");
    26. statement.setString(1, fName);
    27. statement.setString(2, lName);
    28. statement.setString(3, pcode);
    29. statement.setString(4, s1);
    30. statement.setString(5, s2);
    31. statement.setString(6, st);
    32. statement.setString(7, cy);
    33. statement.setString(8, cnty);
    34. if (statement.executeUpdate() != 1) {
    35. statement.close();
    36. connection.close();
    37. throw new CreateException("Could not create: ");
    38. }
    39. statement.close();
    40. connection.close();
    41. } catch (SQLException e) {
    42. throw new EJBException("Could not create: ");
    43. }
    44. }

转自 http://gimgen1026.iteye.com/blog/148106

时间: 2024-11-08 05:33:47

关于EJB--实体Bean的BMP和CMP选择的相关文章

EJB实体Bean怎样和数据库中表关联?

<?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&qu

EJB实体Bean如何和数据库中表关联?

<?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&qu

J2EE的十三个技术——EJB之实体Bean

概述: 实体Bean与会话Bean不同,实体Bean是持久的,即使应用程序结束,它仍然存在.它允许共享访问,具有主键. 组成: 1)本地(Local)接口 本地访问EJB,只有在EJB与客户在同一个应用的情况下才可以使用.使用时,它可以与远程接口同时使用. 它可以优化访问EJB,绕过了RMI. 2)远程(Remote)接口 与本地接口最大的不同在于远程接口可以从任何地方访问. 命名: 如果只使用local或Remote接口之一,可使用正常名称.例如HelloWorld和HelloWorldHom

EJB初级篇--EJB组件之实体Bean

上文我们对会话Bean的生命周期和两个子类型(有状态会话Bean和无状态会话Bean)进行了详细解说,本篇博文中我们继续说说EJB组件中的实体Bean. 其实实体Bean就是一个加了注释符(@Entity)的简单java对象(POJO),实体关系和O/R映射也是通过注释符来定义的,并且提供了几种不同的数据库操作规范.一旦被EntityManager访问,它就成为了一个持久化对象,我们就可以像以前使用Hibernate一样来使用实体对象了. 下图是实体Bean的内容结构图,方便我们宏观的了解实体B

EJB学习(四)——Enterprise Bean(企业Bean)和Entity Bean(实体Bean)

    一.为什么使用EJB ? 企业Bean运行在EJB容器中,企业Bean实际上就是一个封装了业务逻辑的Java类,那么我们为什么要使用EJB呢 ? 1.最重要的原因:分布式.简要的说,分布式可以将分布在各处的资源综合利用,但是对于用户来说展现的是一个统一的整体:分布式可以动态分配任务,分散物理的和逻辑的资源,从而提高执行效率:分布式技术可以避免由于单个节点失效而使整个系统崩溃的危险. 2.分布式对象之间的事务支持,RMI(Remote Method Invocation,远程方法调用)不支

EJB_开发单表映射的实体bean

开发单表映射的实体bean 实体bean 它属于java持久化规范(JPA)里的技术,实体bean通过元数据在Javabean和数据库表之间建立起映射关系,然后Java程序猿就能够随心所欲的使用面向对象的编程思想来操纵数据库. JPA的出现主要是为了简化现有的持久化开发工作和整合ORM技术,眼下实现的JPA规范的主流产品有Hibernate.TopLink和OpenJPA,在JBoss中採用了Hibernate 作为其持久化实现产品. 加入JPA的配置文件persistence.xml 依据JP

持久化API(JPA)系列(三)实体Bean的开发技术-建议与数据库的连接

在EJB 2.x中,EJB有3种类型的Bean,分别是会话Bean(Session Bean).消息驱动Bean(Message-Driven Bean)和实体Bean(Entity Bean). 随着EJB 3的推出,EJB2.x中的实体Bean逐渐被JPA规范所替代,JPA不仅能在EJB环境中使用,而且能在Java SE.Java EE环境中使用,相对于EJB 2.x中的实体Bean,它的使用范围更广. 但这里我们仍然将其称做实体Bean. 与会话Bean和消息驱动Bean类似,新的实体Be

Java深度历险(二) EJB Session Bean有状态和无状态的区别与联系

刚开始对两种sessionbean存在误解,认为有状态是实例一直存在,保存每次调用后的状态,并对下一次调用起作用,而认为无状态是每次调用实例化一次,不保留用户信息.仔细分析并用实践检验后,会发现,事实恰好相反:有状态和无状态会话bean的本质区别是它们的生命期. 首先解释一个下面要用到的概念--用户:sessionbean 的用户实际上就是直接调用ejb的类的实例,甚至是这个实例的某个方法.同一个类的不同实例对于session bean来说是不同的用户. 实例解析 有状态的StatefulEjb

hibernate查询部分字段转换成实体bean

//hibernate查询部分字段转换成实体bean /** * 查询线路信息 */ @Override public List<Line> getSimpleLineListByTj(Map<String,Object> paramMap){ Criteria cr=this.getSession().createCriteria(Line.class,"Line"); // cr.setFetchMode("chuTuanInfo", F