关于JBuilder和EJB的问题,请指点迷津 你可以使用 BMP 来解决多表的问题! 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 to lanlansky :能不能给我一个简单的例子:如何做一个BMP ? 或者发一个程序给我看看?我的邮件[email protected]谢谢 Bean 管理的持续性 bean 管理的持续 (BMP) Enterprise Bean 负责将其状态与数据库同步,就象容器管理的持续一样。bean 使用数据库 API(通常是 JDBC)来读取其字段并将字段写入数据库,但容器会告诉它何时执行每个同步操作,并会自动管理 bean 的事务。bean 管理的持续可以让 bean 开发人员灵活地执行对于容器来说太过于复杂的持续操作,或者使用容器不支持的数据源 -- 例如,定制或旧的数据库。 在本屏面中,您将把 CustomerBean 类修改成 BMP bean,而不是 CMP bean。这个修改根本不会影响远程或本地接口。实际上,不会直接修改原始 CustomerBean。事实上,您将通过扩展 bean 并覆盖适当方法来将它更改成 bean 管理的持续。以下是一个类定义,这个类将扩展 Customer bean 类以使它成为 BMP 实体。大多数情况下,不必扩展 bean 以使它成为 BMP,只要直接将 bean 实现成 BMP。执行这种策略(扩展 CMP bean)是出于两个原因:它允许 bean 可以是 CMP 或 BMP;它可以很方便地消减显示所需要的全部代码。以下是随着本屏的继续将要添加的 BMP 类的定义: public class CustomerBean_BMP extends CustomerBean { public void ejbLoad() { // override implementation } public void ejbStore() { // override implementation } public void ejbCreate() { // override implementation } public void ejbRemove() { // override implementation } private Connection getConnection() { // new helper method }}对于 BMP bean,它与 CMP bean 的差别在于容器和 bean 使用 ejbLoad() 和 ejbStore() 方法的方式不同。在 BMP 中,ejbLoad() 和 ejbStore() 方法分别包含了用于从数据库读取 bean 的数据和将更改写入数据库的代码。当 EJB 服务器决定要读写数据时,会自动在 bean 上调用这些方法。 CustomerBean_BMP bean 管理它自己的持续。换句话说,ejbLoad() 和 ejbStore() 方法必须包括数据库访问逻辑,只有这样,当 EJB 告诉 bean 要装入和存储数据时,它才能这么做。容器会在适当时自动执行 ejbLoad() 和 ejbStore() 方法。 通常在事务开始时,就在容器将商业方法委托给 bean 之前,容器会调用 ejbLoad() 方法。以下代码显示了如何使用 JDBC 实现 ejbLoad() 方法: import java.sql.Connection;public class CustomerBean_BMP extends CustomerBean { public void ejbLoad() { Connection con; try { Integer primaryKey = (Integer)ejbContext.getPrimaryKey(); con = this.getConnection(); Statement sqlStmt = con.createStatement("SELECT * FROM Customer " + " WHERE customerID = " + primaryKey.intValue()); ResultSet results = sqlStmt.executeQuery(); if (results.next()) { // get the name information from the customer table myName = new Name(); myName.first = results.getString("FIRST_NAME"); myName.last = results.getString("LAST_NAME"); myName.middle = results.getString("MIDDLE_NAME"); // get the address information from the customer table myAddress = new Address(); myAddress.street = results.getString("STREET"); myAddress.city = results.getString("CITY"); myAddress.state = results.getString("STATE"); myAddress.zip = results.getInt("ZIP"); // get the credit card information from the customer table myCreditCard = new CreditCard(); myCreditCard.number = results.getString("CREDIT_NUMBER"); myCreditCard.expDate = results.getString("CREDIT_DATE"); myCreditCard.type = results.getString("CREDIT_TYPE"); myAddress.name = results.getInt("CREDIT_NAME"); } } catch (SQLException sqle) { throw new EJBException(sqle); } finally { if (con!=null) con.close(); } }}在 ejbLoad() 方法中,使用对 bean 的 EntityContext 的 ejbContext() 引用来获取实例的主键。这种方法确保对数据库使用了正确的索引。显然,CustomerBean_BMP 需要使用前面所述的继承的 setEntityContext() 和 unsetEntityContext() 方法。 在事务结束时,就在容器试图将所有更改提交给数据库之前,容器会对 bean 调用 ejbStore() 方法。 import java.sql.Connection;public class CustomerBean_BMP extends CustomerBean { public void ejbLoad() { ... read data from database } public void ejbStore() { Connection con; try { Integer primaryKey = (Integer)ejbContext.getPrimaryKey(); con = this.getConnection(); PreparedStatement sqlPrep = con.prepareStatement( "UPDATE customer set " + "last_name = ?, first_name = ?, middle_name = ?, " + "street = ?, city = ?, state = ?, zip = ?, " + "card_number = ?, card_date = ?, " + "card_name = ?, card_name = ?, " + "WHERE id = ?" ); sqlPrep.setString(1,myName.last); sqlPrep.setString(2,myName.first); sqlPrep.setString(3,myName.middle); sqlPrep.setString(4,myAddress.street); sqlPrep.setString(5,myAddress.city); sqlPrep.setString(6,myAddress.state); sqlPrep.setString(7,myAddress.zip); sqlPrep.setInt(8, myCreditCard.number); sqlPrep.setString(9, myCreditCard.expDate); sqlPrep.setString(10, myCreditCard.type); sqlPrep.setString(11, myCreditCard.name); sqlPrep.setInt(12,primaryKey.intValue()); sqlPrep.executeUpdate(); } catch (SQLException sqle) { throw new EJBException(sqle); } finally { if (con!=null) con.close(); } }}在 ejbLoad() 和 ejbStore() 方法中,bean 都会使用 JDBC 将其自己的状态与数据库同步。如果仔细研究过代码,您也许会发现 bean 从神秘的 this.getConnection() 方法调用中获取它的数据库连接,而此方法尚未实现。getConnection() 方法并不是标准的 EJB 方法;它只是一个私有辅助方法,实现它是为了隐藏获取数据库连接的方法。以下是 getConnection() 方法的定义: import java.sql.Connection;public class CustomerBean_BMP extends CustomerBean { public void ejbLoad() { ... read data from database } public void ejbStore() { ... write data to database } private Connection getConnection() throws SQLException { InitialContext jndiContext = new InitialContext(); DataSource source = (DataSource) jndiContext.lookup("java:comp/env/jdbc/myDatabase"); return source.getConnection(); }}通过使用缺省 JNDI 上下文(称作 JNDI 环境命名上下文 (ENC)),从容器中获取数据库连接。ENC 通过标准连接库,javax.sql.DataSource 类型,提供对事务性、合用、JDBC 连接的访问权。 在 BMP 中,容器调用 ejbLoad() 和 ejbStore() 方法使 bean 实例与数据库中的数据同步。为了将实体插入数据库或除去数据库中的实体,使用类似的数据库访问来实现 ejbCreate() 和 ejbRemove() 方法。ejbCreate() 方法将新记录插入数据库,而 ejbRemove() 方法从数据库中删除实体的数据。容器调用 BMP 实体的 ejbCreate() 方法和 ejbRemove() 方法以响应对本地和远程接口中它们相应方法的调用。这些方法的实现显示如下: public void ejbCreate(Integer id) { this.customerID = id.intValue(); Connection con; try { con = this.getConnection(); Statement sqlStmt = con.createStatement("INSERT INTO customer id VALUES (" + customerID + ")"); sqlStmt.executeUpdate(); return id; } catch(SQLException sqle) { throw new EJBException(sqle); } finally { if (con!=null) con.close(); } } public void ejbRemove() { Integer primaryKey = (Integer)ejbContext.getPrimaryKey(); Connection con; try { con = this.getConnection(); Statement sqlStmt = con.createStatement("DELETE FROM customer WHERE id = " primaryKey.intValue()); sqlStmt.executeUpdate(); } catch(SQLException sqle) { throw new EJBException(sqle); } finally { if (con!=null) con.close(); } }在 BMP 中,bean 类负责实现在本地接口中定义的查找方法。对于本地接口中定义的每个查找方法,在 bean 类中必须有相应的 ejbFind() 方法。ejbFind() 方法定位数据库中相应的 bean 记录,并将它们的主键返回给容器。容器将主键转换成 bean 引用,并将它们返回给客户机。以下是 CustomerBean_BMP 类中 ejbFindByPrimaryKey() 方法实现的示例,它对应于 CustomerHome 接口中定义的 findByPrimaryKey(): public Integer ejbFindByPrimaryKey(Integer primaryKey) throws ObjectNotFoundException { Connection con; try { con = this.getConnection(); Statement sqlStmt = con.createStatement("SELECT * FROM Customer " + " WHERE customerID = " + primaryKey.intValue()); ResultSet results = sqlStmt.executeQuery(); if (results.next()) return primaryKey; else throw ObjectNotFoundException(); } catch (SQLException sqle) { throw new EJBException(sqle); } finally { if (con!=null) con.close(); }}以上这个单一实体查找方法会返回一个主键,如果没有找到匹配的记录,则它会掷出 ObjectNotFoundException。多实体查找方法返回主键的集合(java.util.Enumeration 或 java.util.Collection)。容器将主键集合转换成远程引用的集合,然后将此集合返回给客户机。以下是如何在 CustomerBean_BMP 类中实现多实体 ejbFindByZipCode() 方法的示例,该方法对应于 CustomerHome 接口中定义的 findByZipCode() 方法: public Enumeration ejbFindByZipCode(int zipCode) { Connection con; try { con = this.getConnection(); Statement sqlStmt = con.createStatement("SELECT id FROM Customer " + " WHERE zip = " +zipCode); ResultSet results = sqlStmt.executeQuery(); Vector keys = new Vector(); while(results.next()){ int id = results.getInt("id"); keys.addElement(new Integer(id)); } return keys.elements(); } catch (SQLException sqle) { throw new EJBException(sqle); } finally { if (con!=null) con.close(); }}如果没有找到匹配的 bean 记录,则会将空集合返回给容器,然后容器将空集合返回给客户机。 实现了所有这些方法并对 bean 的部署描述信息进行了一些较小更改之后,就可以将 CustomerBean_BMP 部署成 BMP 实体了。 求一数据库数据导出excel问题思路........ 老问题,swfupload的中文乱码问题。 关于SSH的问题求解 晕,这个语法是什么意思?没见过? 数据库问题 查询后删除问题 hibernate 单向多对一 问题,请高手指教 自建标签的 标记处理程序类 如何将属性赋给ActionForm 估计CSDN上没有这样的高手....还是问一下吧,不定能天上掉馅饼! 高分求救--关于在jbuilder9下调试程序 请问什么叫servlet?ejb?作什么用? 现在用JAVA 作什么最有前途?EJB &APPLICATION?
能不能给我一个简单的例子:如何做一个BMP ? 或者发一个程序给我看看?
我的邮件[email protected]
谢谢
bean 管理的持续 (BMP) Enterprise Bean 负责将其状态与数据库同步,就象容器管理的持续一样。bean 使用数据库 API(通常是 JDBC)来读取其字段并将字段写入数据库,但容器会告诉它何时执行每个同步操作,并会自动管理 bean 的事务。bean 管理的持续可以让 bean 开发人员灵活地执行对于容器来说太过于复杂的持续操作,或者使用容器不支持的数据源 -- 例如,定制或旧的数据库。 在本屏面中,您将把 CustomerBean 类修改成 BMP bean,而不是 CMP bean。这个修改根本不会影响远程或本地接口。实际上,不会直接修改原始 CustomerBean。事实上,您将通过扩展 bean 并覆盖适当方法来将它更改成 bean 管理的持续。以下是一个类定义,这个类将扩展 Customer bean 类以使它成为 BMP 实体。大多数情况下,不必扩展 bean 以使它成为 BMP,只要直接将 bean 实现成 BMP。执行这种策略(扩展 CMP bean)是出于两个原因:它允许 bean 可以是 CMP 或 BMP;它可以很方便地消减显示所需要的全部代码。以下是随着本屏的继续将要添加的 BMP 类的定义:
public class CustomerBean_BMP extends CustomerBean {
public void ejbLoad() {
// override implementation
}
public void ejbStore() {
// override implementation
}
public void ejbCreate() {
// override implementation
}
public void ejbRemove() {
// override implementation
}
private Connection getConnection() {
// new helper method
}
}对于 BMP bean,它与 CMP bean 的差别在于容器和 bean 使用 ejbLoad() 和 ejbStore() 方法的方式不同。在 BMP 中,ejbLoad() 和 ejbStore() 方法分别包含了用于从数据库读取 bean 的数据和将更改写入数据库的代码。当 EJB 服务器决定要读写数据时,会自动在 bean 上调用这些方法。 CustomerBean_BMP bean 管理它自己的持续。换句话说,ejbLoad() 和 ejbStore() 方法必须包括数据库访问逻辑,只有这样,当 EJB 告诉 bean 要装入和存储数据时,它才能这么做。容器会在适当时自动执行 ejbLoad() 和 ejbStore() 方法。 通常在事务开始时,就在容器将商业方法委托给 bean 之前,容器会调用 ejbLoad() 方法。以下代码显示了如何使用 JDBC 实现 ejbLoad() 方法:
import java.sql.Connection;public class CustomerBean_BMP extends CustomerBean { public void ejbLoad() {
Connection con;
try {
Integer primaryKey = (Integer)ejbContext.getPrimaryKey();
con = this.getConnection();
Statement sqlStmt =
con.createStatement("SELECT * FROM Customer " +
" WHERE customerID = " +
primaryKey.intValue());
ResultSet results = sqlStmt.executeQuery();
if (results.next()) {
// get the name information from the customer table
myName = new Name();
myName.first = results.getString("FIRST_NAME");
myName.last = results.getString("LAST_NAME");
myName.middle = results.getString("MIDDLE_NAME");
// get the address information from the customer table
myAddress = new Address();
myAddress.street = results.getString("STREET");
myAddress.city = results.getString("CITY");
myAddress.state = results.getString("STATE");
myAddress.zip = results.getInt("ZIP");
// get the credit card information from the customer table
myCreditCard = new CreditCard();
myCreditCard.number = results.getString("CREDIT_NUMBER");
myCreditCard.expDate = results.getString("CREDIT_DATE");
myCreditCard.type = results.getString("CREDIT_TYPE");
myAddress.name = results.getInt("CREDIT_NAME");
}
}
catch (SQLException sqle) {
throw new EJBException(sqle);
}
finally {
if (con!=null)
con.close();
}
}
}在 ejbLoad() 方法中,使用对 bean 的 EntityContext 的 ejbContext() 引用来获取实例的主键。这种方法确保对数据库使用了正确的索引。显然,CustomerBean_BMP 需要使用前面所述的继承的 setEntityContext() 和 unsetEntityContext() 方法。 在事务结束时,就在容器试图将所有更改提交给数据库之前,容器会对 bean 调用 ejbStore() 方法。
import java.sql.Connection;public class CustomerBean_BMP extends CustomerBean { public void ejbLoad() {
... read data from database
} public void ejbStore() {
Connection con;
try {
Integer primaryKey = (Integer)ejbContext.getPrimaryKey();
con = this.getConnection();
PreparedStatement sqlPrep =
con.prepareStatement(
"UPDATE customer set " +
"last_name = ?, first_name = ?, middle_name = ?, " +
"street = ?, city = ?, state = ?, zip = ?, " +
"card_number = ?, card_date = ?, " +
"card_name = ?, card_name = ?, " +
"WHERE id = ?"
);
sqlPrep.setString(1,myName.last);
sqlPrep.setString(2,myName.first);
sqlPrep.setString(3,myName.middle);
sqlPrep.setString(4,myAddress.street);
sqlPrep.setString(5,myAddress.city);
sqlPrep.setString(6,myAddress.state);
sqlPrep.setString(7,myAddress.zip);
sqlPrep.setInt(8, myCreditCard.number);
sqlPrep.setString(9, myCreditCard.expDate);
sqlPrep.setString(10, myCreditCard.type);
sqlPrep.setString(11, myCreditCard.name);
sqlPrep.setInt(12,primaryKey.intValue());
sqlPrep.executeUpdate();
}
catch (SQLException sqle) {
throw new EJBException(sqle);
}
finally {
if (con!=null)
con.close();
}
}
}在 ejbLoad() 和 ejbStore() 方法中,bean 都会使用 JDBC 将其自己的状态与数据库同步。如果仔细研究过代码,您也许会发现 bean 从神秘的 this.getConnection() 方法调用中获取它的数据库连接,而此方法尚未实现。getConnection() 方法并不是标准的 EJB 方法;它只是一个私有辅助方法,实现它是为了隐藏获取数据库连接的方法。以下是 getConnection() 方法的定义:
import java.sql.Connection;public class CustomerBean_BMP extends CustomerBean { public void ejbLoad() {
... read data from database
} public void ejbStore() {
... write data to database
} private Connection getConnection() throws SQLException { InitialContext jndiContext = new InitialContext();
DataSource source = (DataSource)
jndiContext.lookup("java:comp/env/jdbc/myDatabase");
return source.getConnection();
}
}通过使用缺省 JNDI 上下文(称作 JNDI 环境命名上下文 (ENC)),从容器中获取数据库连接。ENC 通过标准连接库,javax.sql.DataSource 类型,提供对事务性、合用、JDBC 连接的访问权。 在 BMP 中,容器调用 ejbLoad() 和 ejbStore() 方法使 bean 实例与数据库中的数据同步。为了将实体插入数据库或除去数据库中的实体,使用类似的数据库访问来实现 ejbCreate() 和 ejbRemove() 方法。ejbCreate() 方法将新记录插入数据库,而 ejbRemove() 方法从数据库中删除实体的数据。容器调用 BMP 实体的 ejbCreate() 方法和 ejbRemove() 方法以响应对本地和远程接口中它们相应方法的调用。这些方法的实现显示如下:
public void ejbCreate(Integer id) {
this.customerID = id.intValue();
Connection con;
try {
con = this.getConnection();
Statement sqlStmt =
con.createStatement("INSERT INTO customer id VALUES (" +
customerID + ")");
sqlStmt.executeUpdate();
return id;
}
catch(SQLException sqle) {
throw new EJBException(sqle);
}
finally {
if (con!=null)
con.close();
}
} public void ejbRemove() {
Integer primaryKey = (Integer)ejbContext.getPrimaryKey();
Connection con;
try {
con = this.getConnection();
Statement sqlStmt =
con.createStatement("DELETE FROM customer WHERE id = "
primaryKey.intValue());
sqlStmt.executeUpdate();
}
catch(SQLException sqle) {
throw new EJBException(sqle);
}
finally {
if (con!=null)
con.close();
}
}在 BMP 中,bean 类负责实现在本地接口中定义的查找方法。对于本地接口中定义的每个查找方法,在 bean 类中必须有相应的 ejbFind() 方法。ejbFind() 方法定位数据库中相应的 bean 记录,并将它们的主键返回给容器。容器将主键转换成 bean 引用,并将它们返回给客户机。以下是 CustomerBean_BMP 类中 ejbFindByPrimaryKey() 方法实现的示例,它对应于 CustomerHome 接口中定义的 findByPrimaryKey():
public Integer ejbFindByPrimaryKey(Integer primaryKey)
throws ObjectNotFoundException {
Connection con;
try {
con = this.getConnection();
Statement sqlStmt =
con.createStatement("SELECT * FROM Customer " +
" WHERE customerID = " +
primaryKey.intValue());
ResultSet results = sqlStmt.executeQuery();
if (results.next())
return primaryKey;
else
throw ObjectNotFoundException();
}
catch (SQLException sqle) {
throw new EJBException(sqle);
}
finally {
if (con!=null)
con.close();
}
}以上这个单一实体查找方法会返回一个主键,如果没有找到匹配的记录,则它会掷出 ObjectNotFoundException。多实体查找方法返回主键的集合(java.util.Enumeration 或 java.util.Collection)。容器将主键集合转换成远程引用的集合,然后将此集合返回给客户机。以下是如何在 CustomerBean_BMP 类中实现多实体 ejbFindByZipCode() 方法的示例,该方法对应于 CustomerHome 接口中定义的 findByZipCode() 方法:
public Enumeration ejbFindByZipCode(int zipCode) {
Connection con;
try {
con = this.getConnection();
Statement sqlStmt =
con.createStatement("SELECT id FROM Customer " +
" WHERE zip = " +zipCode);
ResultSet results = sqlStmt.executeQuery();
Vector keys = new Vector();
while(results.next()){
int id = results.getInt("id");
keys.addElement(new Integer(id));
}
return keys.elements();
}
catch (SQLException sqle) {
throw new EJBException(sqle);
}
finally {
if (con!=null)
con.close();
}
}如果没有找到匹配的 bean 记录,则会将空集合返回给容器,然后容器将空集合返回给客户机。 实现了所有这些方法并对 bean 的部署描述信息进行了一些较小更改之后,就可以将 CustomerBean_BMP 部署成 BMP 实体了。