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
- public abstract class AddressEJB implements EntityBean {
- private EntityContext context = null;
-
-
-
- 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()爲例:
ide
- public Object ejbCreate(
- String fName,
- String lName,
- String s1,
- String s2,
- String cy,
- String st,
- String cnty,
- String pcode)
- throws CreateException {
-
-
- this.fName = fName;
- this.lName = lName;
- this.s1 = s1;
- this.s2 = s2;
- this.cy = cy;
- this.st = st;
- this.cnty = cnty;
- this.pcode = pcode;
-
-
- 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: ");
- }
- }
轉自 http://gimgen1026.iteye.com/blog/148106this