一个是容器来做所有事  
一个是自己来做所有事  
---------------------------------------------------------------  
 
这个例子希望对你有帮助  
 
实体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为例:  
 
public  abstract  class  AddressEJB  implements  EntityBean  {    
private  EntityContext  context  =  null;  
 
//  getters  and  setters  for  PO  CMP  fields  
 
public  abstract  String  getFirstName();  
public  abstract  void  setFirstName(String  name);  
public  abstract  String  getLastName();  
public  abstract  void  setLastName(String  name);  
public  abstract  String  getStreet1();  
public  abstract  void  setStreet1(String  name);  
public  abstract  String  getStreet2();  
public  abstract  void  setStreet2(String  name);  
public  abstract  String  getCity();  
public  abstract  void  setCity(String  name);  
public  abstract  String  getState();  
public  abstract  void  setState(String  name);  
public  abstract  String  getCountry();  
public  abstract  void  setCountry(String  name);  
public  abstract  String  getZip();  
public  abstract  void  setZip(String  name);  
 
public  Object  ejbCreate(String  fName,  String  lName,  String  s1,  
String  s2,  String  cy,  String  st,  
String  cnty,  String  pcode)  
throws  CreateException  {  
setFirstName(fName);  
setLastName(lName);  
setStreet1(s1);  
setStreet2(s2);  
setCity(cy);  
setState(st);  
setCountry(cnty);  
setZip(pcode);  
return  null;  
}  
 
public  void  ejbPostCreate(String  fName,  String  lName,  String  street1,  
String  street2,  String  city,  String  state,  
String  country,  String  zip)  
throws  CreateException{}  
public  void  setEntityContext(EntityContext  c){  context  =  c;  }  
public  void  unsetEntityContext(){}  
public  void  ejbRemove()  throws  RemoveException  {}  
public  void  ejbActivate()  {}  
public  void  ejbPassivate()  {}  
public  void  ejbStore()  {}  
public  void  ejbLoad()  {}  
}  
 
   
 
在上面的AddressEJB中,我们看到只有setXXX或getXXX的方法。  
 
在相应的部署描述文件ejb-jar.xml中我们看到:  
 
<entity>  
  <display-name>AddressEJB</display-name>  
  <ejb-name>AddressEJB</ejb-name>  
  <local-home>com.sun.j2ee.blueprints.address.ejb.AddressLocalHome</local-home>  
  <local>com.sun.j2ee.blueprints.address.ejb.AddressLocal</local>  
  <ejb-class>com.sun.j2ee.blueprints.address.ejb.AddressEJB</ejb-class>  
  <persistence-type>Container</persistence-type>  
  <prim-key-class>java.lang.Object</prim-key-class>  
  <reentrant>False</reentrant>  
  <cmp-version>2.x</cmp-version>  
  <abstract-schema-name>Address</abstract-schema-name>  
 
 
  <cmp-field>  
    <field-name>firstName</field-name>  
  </cmp-field>  
  <cmp-field>  
    <field-name>lastName</field-name>  
  </cmp-field>  
  <cmp-field>  
    <field-name>street1</field-name>  
  </cmp-field>  
  <cmp-field>  
    <field-name>street2</field-name>  
  </cmp-field>  
  <cmp-field>  
    <field-name>city</field-name>  
  </cmp-field>  
  <cmp-field>  
    <field-name>state</field-name>  
  </cmp-field>  
  <cmp-field>  
    <field-name>country</field-name>  
  </cmp-field>  
  <cmp-field>  
    <field-name>zip</field-name>  
  </cmp-field>  
 
 
  <security-identity>  
    <description></description>  
    <use-caller-identity></use-caller-identity>  
  </security-identity>  
 
</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()为例:  
 
public  Object  ejbCreate(String  fName,  String  lName,  String  s1,  
String  s2,  String  cy,  String  st,  
String  cnty,  String  pcode)  throws  CreateException  {  
 
//  insert  row  into  database  
this.fName  =  fName;  
this.lName  =  lName;  
this.s1  =  s1;    
this.s2  =  s2;    
this.cy=cy;  
this.st=st;  
this.cnty=cnty;  
this.pcode=pcode;    
 
//  Insert  database  record  
try  {  
Connection  connection  =  getConnection();  
PreparedStatement  statement  =  connection.prepareStatement  
("INSERT  INTO  Address  (firstName,lastName,street1,street2,city,state,country,zip)  VALUES  (?,  ?,  ?,?,?,?)");  
statement.setString(1,  fName);    
statement.setString(2,  lName);    
statement.setString(3,  pcode);  
statement.setString(4,  s1);  
statement.setString(5,  s2);  
statement.setString(6,  st);  
statement.setString(7,  cy);  
statement.setString(8,  cnty);  
if  (statement.executeUpdate()  !=  1)  {  
statement.close();  
connection.close();  
throw  new  CreateException("Could  not  create:  "  );  
}  
statement.close();  
connection.close();  
}  
catch(SQLException  e)  {  
throw  new  EJBException("Could  not  create:  "  );  
}  
}