|
|
第7课 现在,J2EE应用范例已经对基本的Cloudscape数据库进行了写入和读取数据的 操作,而无须SQL代码和编写代码。这是因为容器已经代表entity bean对数据存 储和检索进行了处理。container-managed persistence是一个用来描述容器处理 数据存储和检索状况的术语。本课将介绍如何重载默认的container-managed persistence实现bean-managed persistence。 Bean-managed persistence是当你使用你自己的SQL命令实现entity或session 方法时对container-managed persistence的重载。如果你需要提高性能或将多个 bean中的数据映射到数据库表格中的一行时,这种bean-managed persistence便 会发挥出作用。 本课将修改J2EE应用范例中的entity bean,使用bean-可管理的持续性。 Bean 生存周期
第3课中的BonusBean章节介
绍了container-managed BonusBean类。仅有的实现方法就是:返回bonus值的 一个session bean或entity bean由业务方法和生存周期方法组成。在这个例
子中,
修改BonusBean代码
这一节将介绍bean-managed persistence 导入(import)语句
在建立与数据库的连接时, package Beans;
import java.rmi.RemoteException;
import javax.ejb.CreateException;
import javax.ejb.EntityBean;
import javax.ejb.EntityContext;
import javax.naming.InitialContext;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import javax.ejb.FinderException;
import java.sql.SQLException;
实例变量
本课增加的实例变量可以让你建立和关闭与数据库的连接。字符串 然后,你将在 public class BonusBean implements EntityBean {
private EntityContext context;
private Connection con;
private String dbName =
"java:comp/env/jdbc/BonusDB";
private InitialContext ic = null;
private PreparedStatement ps = null;
private double bonus;
private String socsec;
业务方法
本课中,除了对 public double getBonus() {
System.out.println("getBonus");
return this.bonus;
}
public String getSocSec() {
System.out.println("getSocSec");
return this.socsec;
}
生存周期方法
这些方法包括调用 EjbCreate
本课中的 关于这个类需要注意的一点是,它返回一个 public String ejbCreate(double bonus, String socsec)
throws RemoteException,
CreateException,
SQLException {
this.socsec=socsec;
this.bonus=bonus;
System.out.println("Create Method");
try {
//Establish database connection
ic = new InitialContext();
DataSource ds = (DataSource) ic.lookup(dbName);
con = ds.getConnection();
//Use PreparedStatement to form SQL INSERT statement
//to insert into BONUS table
ps = con.prepareStatement(
"INSERT INTO BONUS VALUES (? , ?)");
//Set 1st PreparedStatement value marked by ? , with
//socsec and the 2nd value marked by ?) with bonus
ps.setString(1, socsec);
ps.setDouble(2, bonus);
ps.executeUpdate();
} catch (javax.naming.NamingException ex) {
ex.printStackTrace();
} finally {
//Close database connection
ps.close();
con.close();
}
//Return primary key
return socsec;
}
ejbPostCreate
这个方法与 public void ejbPostCreate(double bonus,
String socsec)
throws RemoteException,
CreateException,
SQLException {
System.out.println("Post Create");
}
ejbFindByPrimaryKey
BonusBean的container-managed版本没有包括ejbFindByPrimaryKey,因为,
如果你在部署期间指定container-managed persistence并提供主关键字域,容器 可以通过它们的主关键字来找到数据库记录的位置。在本课中, 如果利用传递给 关于这个类需要注意的一点是,它返回一个 public String ejbFindByPrimaryKey(String primaryKey)
throws RemoteException,FinderException,
SQLException {
System.out.println("Find by primary key");
try {
//Establish database connection
ic = new InitialContext();
DataSource ds = (DataSource) ic.lookup(dbName);
con = ds.getConnection();
//Use PreparedStatement to form SQL SELECT statement
//to select from BONUS table
ps = con.prepareStatement(
"SELECT socsec FROM BONUS WHERE socsec = ? ");
ps.setString(1, primaryKey);
//Use ResultSet to capture SELECT statement results
ResultSet rs = ps.executeQuery();
//If ResultSet has a value, the find was successful,
//and so initialize and return key
if(rs.next()) {
key = primaryKey;
} else {
System.out.println("Find Error");
}
} catch (javax.naming.NamingException ex) {
ex.printStackTrace();
} finally {
//Close database connection
ps.close();
con.close();
}
//Return primary key
return key;
}
ejbLoad
这个方法是在 public void ejbLoad() {
System.out.println("Load method");
try {
//Establish database connection
ic = new InitialContext();
DataSource ds = (DataSource) ic.lookup(dbName);
con = ds.getConnection();
//Use PreparedStatement to form SQL SELECT statement
//to select from BONUS table
ps = con.prepareStatement(
"SELECT * FROM BONUS WHERE SOCSEC = ?");
ps.setString(1, this.socsec);
//Use ResultSet to capture SELECT statement results
ResultSet rs = ps.executeQuery();
//If ResultSet has a value, the find was successful
if(rs.next()){
this.bonus = rs.getDouble(2);
} else {
System.out.println("Load Error");
}
} catch (java.sql.SQLException ex) {
ex.printStackTrace();
} catch (javax.naming.NamingException ex) {
ex.printStackTrace();
} finally {
try {
//Close database connection
ps.close();
con.close();
} catch (java.sql.SQLException ex) {
ex.printStackTrace();
}
}
}
>ejbStore
当客户在bean中设置或获取数据时对这个方法进行调用,来向数据库发送对象 数据,使bean数据与数据库数据保持同步。 public void ejbStore() {
System.out.println("Store method");
try {
//Establish database connection
DataSource ds = (DataSource)ic.lookup(dbName);
con = ds.getConnection();
//Use PreparedStatement to form SQL UPDATE statement
//to update BONUS table
ps = con.prepareStatement(
"UPDATE BONUS SET BONUS = ? WHERE SOCSEC = ?");
//Set 1st PreparedStatement value marked by ? with
//bonus and the 2nd value marked by ?) with socsec
ps.setDouble(1, bonus);
ps.setString(2, socsec);
int rowCount = ps.executeUpdate();
} catch (javax.naming.NamingException ex) {
ex.printStackTrace();
} catch (java.sql.SQLException ex) {
ex.printStackTrace();
} finally {
try {
//Close database connection
ps.close();
con.close();
} catch (java.sql.SQLException ex) {
ex.printStackTrace();
}
}
}
ejbRemove
当客户在bean的home接口上调用 public void ejbRemove()
throws RemoteException {
System.out.println("Remove method");
try {
DataSource ds = (DataSource)ic.lookup(dbName);
con = ds.getConnection();
ps = con.prepareStatement(
"DELETE FROM BONUS WHERE SOCSEC = ?");
ps.setString(1, socsec);
ps.executeUpdate();
} catch (java.sql.SQLException ex) {
ex.printStackTrace();
} catch (Exception ex) {
ex.printStackTrace();
try {
ps.close();
con.close();
} catch (java.sql.SQLException ex) {
ex.printStackTrace();
}
}
ejbActivate
当一个bean很长时间没有被使用时,容器将钝化该bean或将其转移到临时存储 器中,在这里,容器能够在客户调用一个bean的业务方法时再次激活这个bean。
这个方法调用entity上下文的 public void ejbActivate() {
System.out.println("Activate method");
socsec = (String)context.getPrimaryKey();
}
ejbPassivate
当一个bean很长时间没有被使用时,容器将钝化该bean或将其转移到临时存储 器中,在这里,容器能够在客户调用一个bean的业务方法时再次激活这个bean。 这个方法将主关键字设置为零,以在bean处于消极状态时释放存储空间。 public void ejbPassivate() {
System.out.println("Passivate method");
socsec = null;
}
setEntityContext
这个方法被容器调用,来初始化bean的 public void setEntityContext(
javax.ejb.EntityContext ctx){
System.out.println("setEntityContext method");
this.context = ctx;
}
unsetEntityContext
在调用了 public void unsetEntityContext(){
System.out.println("unsetEntityContext method");
ctx = null;
}
}
修改CalcBean和JbonusBean代码
由于 public class CalcBean implements SessionBean {
BonusHome homebonus;
public Bonus calcBonus(int multiplier,
double bonus, String socsec)
throws RemoteException,
SQLException,
CreateException {
Bonus theBonus = null;
double calc = (multiplier*bonus);
try {
InitialContext ctx = new InitialContext();
Object objref = ctx.lookup("bonus");
homebonus = (BonusHome)
PortableRemoteObject.narrow(
objref, BonusHome.class);
} catch (Exception NamingException) {
NamingException.printStackTrace();
}
//Store data in entity Bean
theBonus=homebonus.create(calc, socsec);
return theBonus;
}
必须修改JbonusBean类,来捕获被 public double getBonusAmt() {
if(strMult != null){
Integer integerMult = new Integer(strMult);
int multiplier = integerMult.intValue();
try {
double bonus = 100.00;
theCalculation = homecalc.create();
Bonus theBonus = theCalculation.calcBonus(
multiplier, bonus, socsec);
Bonus record = theCalculation.getRecord(
socsec);
bonusAmt = record.getBonus();
socsec = record.getSocSec();
} catch (java.sql.SQLException e) {
this.bonusAmt = 0.0;
this.socsec = "000";
this.message = e.getMessage();
} catch (javax.ejb.CreateException e) {
this.bonusAmt = 0.0;
this.socsec = "000";
this.message = e.getMessage();
} catch (java.rmi.RemoteException e) {
this.bonusAmt = 0.0;
this.socsec = "000";
this.message = e.getMessage();
}
genXML();
return this.bonusAmt;
} else {
this.bonusAmt = 0;
this.message = "None.";
return this.bonusAmt;
}
}
创建数据库表
因为本例中使用了bean-managed persistence,因此必须在 为了简便,数据库表采用两种脚本创建: 为了执行该脚本,需要进入 Unix: ../cloudTable.sh
Windows/NT: ..\cloudTable.bat
createTable.sql
在本课下载代码中提供了这个文件。 drop table bonus;
create table bonus
(socsec varchar(9) constraint pk_bonus primary key,
bonus decimal(10,2));
exit;
cloudTable.bat
在本课的下载代码中提供了这个文件。 rem cloudTable.bat
rem Creates BONUS table in CloudscapeDB.
rem
rem Place this script in ~\J2EE
rem To run: cd ~\J2EE\cloudTable.sh
rem
rem Change this next line to point to *your*
rem j2sdkee1.2.1 installation
rem
set J2EE_HOME=\home\monicap\J2EE\j2sdkee1.2.1
rem
rem Everything below goes on one line
java -Dij.connection.CloudscapeDB=
jdbc:rmi://localhost:1099/jdbc:cloudscape:
CloudscapeDB\;create=true -Dcloudscape.system.home=
%J2EE_HOME%\cloudscape -classpath
%J2EE_HOME%iib\cloudscape\client.jar;
%J2EE_HOME%iib\cloudscape\ tools.jar;
%J2EE_HOME%iib\cloudscape\cloudscape.jar;
%J2EE_HOME%iib\cloudscape\RmiJdbc.jar;
%J2EE_HOME%iib\cloudscapeiicense.jar;
%CLASSPATH% -ms16m -mx32m
COM.cloudscape.tools.ij createTable.sql
cloudTable.sh
在本课的下载代码中提供了这个文件。 #!/bin/sh
#
# cloudTable.sh
# Creates BONUS table in CloudscapeDB.
#
# Place this script in ~\J2EE
# To run: cd ~\J2EE\cloudTable.sh
#
# Change this next line to point to *your*
# j2sdkee1.2.1 installation
#
J2EE_HOME=/home/monicap/J2EE/j2sdkee1.2
#
# Everything below goes on one line
java -Dij.connection.CloudscapeDB=jdbc:rmi:
//localhost:1099/jdbc:cloudscape:CloudscapeDB\;
create=true -Dcloudscape.system.home=
$J2EE_HOME/cloudscape -classpath
$J2EE_HOME/lib/cloudscape/client.jar:
$J2EE_HOME/lib/cloudscape/tools.jar:
$J2EE_HOME/lib/cloudscape/cloudscape.jar:
$J2EE_HOME/lib/cloudscape/RmiJdbc.jar:
$J2EE_HOME/lib/cloudscape/license.jar:
${CLASSPATH} -ms16m -mx32m
COM.cloudscape.tools.ij createTable.sql
移除JAR文件
我们必须用新的entity bean编码更新bean JAR文件。 如果两个bean都在一个
JAR文件中,则必须删除2BeansJar并创建一个新的。添加 如果两个bean在不同的JAR文件中,则需要删除带 这些指令就在你把 EJB JAR :
EnterpriseBean JAR类:
EJB JAR :
一般项目 :
Entity 设置:
环境项目:
Enterprise Bean 引用:
资源引用:
安全:
事务管理 :
检查设置:
检查窗口:
验证和部署J2EE应用
在部署应用之前最好能够运行验证器。验证器将挑出应用组件中的错误,如编 译器未曾捕获的丢失的enterprise bean方法。 注 :如果在验证或部署时出现 存储的错误,则需要关闭所有程序,重新启动服务器和工具。 验证:
注: 在Version 1.2.1软件中, 你可能会得到一个 部署:
运行J2EE应用
web 服务器的运行端口默认为8000。 若要打开
在每次试图访问数据库时,J2EE服务 器输出可能会显示出以下的消息。意思是,在访问数据库之前没有提供用户名和 密码。 你可以忽略这个信息,因为在进入Cloudscape数据库时不需要用户名和密 码,无论是否出现这个信息,本范例都能正常运作。
下面是J2EE服务器输出的“清洁”版本(以上的信息已被编辑中删除)。 setEntityContext method
Create Method
Post Create
setEntityContext method
Find by primary key
Load method
getBonus
Store method
Load method
getSocSec
Store method
Find by primary key
Load method
getSocSec
Store method
Load method
getBonus
Store method
<?xml version="1.0"?>
<report>
<bonusCalc ssnum="777777777" bonusAmt="300.0" />
</report>
多信息
你可以进入以下网址获得有关entity beans和bean-managed persistence的更
多信息:
http://java.sun.com/j2ee/j2sdkee/techdocs/guides/ejb/html/Entity.fm.html
[TOP] |
|
||||||||||||||||||||||||||||||||||||