| |
5.3 容器管理持久性实体EJB |
| 2008-8-12 文章来源:培训网
责任编辑:zsol 字体: [ ] |
|
|
|
5.3 容器管理持久性实体EJB
5.3.1实例说明
本示例演示容器管理持久性实体EJB实例的开发过程,内容包括: (1)实体EJB主接口、远程接口定义和实现类编写; (2)EJB说明文件和部署文件的编写; (3)EJB属性与数据表字段映射文件的编写: (4)如何定义连接池; (5)如何编译EJB程序; (6)测试EJB程序。 示例文件包括: AccountHome.java,Account.java,AccountBean.java,ProcessingErrorException.java,Client.java,ejb-jar.xml,weblogic-cmp-rdbms-jar.xml,weblogic-ejb-jar.xml。
5.3.2编写源文件
1.编写主接口程序 编辑文件AccountHome.java并保存到C:\work\src\examples\ejb\basic\containerManaged目录下(或从附带光盘的src\examples\ejb\basic\containerManaged目录拷贝)。AccountHome.java源文件如下:
//AccountHome.java //定义本接口在包examples.ejb.basic.containerManaged中 package examples.ejb.basic.containerManaged; //本接口用到的其他类 //javax.ejb.*中定义了实现EJBean的接口。 import javax.ejb.CreateException; import javax.ejb.EJBHome; import javax.ejb.FinderException; import java.rmi.RemoteException; import java.util.Enumeration;
/** * 这是AccontBean的主接口定义,这个接口是被EJB容器产生的类AccontBeanC实现的。 * 在这里只需定义EJB创建的方法,这些方法要和EJBean中的"ejbCreate"方法对应。 */
//EJBean主接口必须继承javax.ejb.EJBHome接口 public interface AccountHome extends EJBHome {
/** * 这个方法和"AccountBean.java"中定义的的Bean的"ejbCreate"方法相对应 * 这两个方法的参数应该相同。当客户端调用"TraderHome.create()"方法时,EJB容器 * 会找到EJBean的实例,并调用它的"ejbCreate()"方法。 * 对容器管理的ejb,ejbCreate方法返回为null,而bean管理的ejb,返回的是主键类。 * @参数 accountID String 账号ID * @参数 initialBalance double 初始化结算值 * @参数 type String 账号类型 * @返回 Account 远程对象 * @异常 javax.ejb.CreateException * 创建bean错误时抛出的异常 * @异常 RemoteException 当系统通讯发生故障时抛出 * @参看 examples.ejb.basic.containerManaged.AccountBean */ public Account create(String accountId, double initialBalance, String type) throws CreateException, RemoteException;
/** * 根据主键对象,返回账号对象 * * @参数 primaryKey 主键 * @返回 Account 账号 * @异常 javax.ejb.FinderException * 访问数据库错误抛出的异常 * @异常 RemoteException 当系统通讯发生故障时抛出 * @参看 examples.ejb.basic.containerManaged.AccountBean */ public Account findByPrimaryKey(String primaryKey) throws FinderException, RemoteException; /** * 找到所有结算值等于balanceEqual的账号 * * @返回 Account 账号 * @参数 double balanceEqual,给定的结算值 * @异常 javax.ejb.FinderException * 访问数据库错误抛出的异常 * @异常 RemoteException 当系统通讯发生故障时抛出 * @参看 examples.ejb.basic.containerManaged.AccountBean */ public Account findAccount(double balanceEqual) throws FinderException, RemoteException;
/** * 找到所有结算值大于balanceGreaterThan的账号 * * @返回 Enumeration 所有账号枚举 * @参数 double balanceGreaterThan,给定的结算值 * @异常 javax.ejb.FinderException * 访问数据库错误抛出的异常 * @异常 RemoteException 当系统通讯发生故障时抛出 * @参看 examples.ejb.basic.containerManaged.AccountBean */ public Enumeration findBigAccounts(double balanceGreaterThan) throws FinderException, RemoteException;
/** * 找到所有类型为’null’的EJBeans。 * * @返回 Enumeration 所有账号枚举 * @异常 javax.ejb.FinderException * 访问数据库错误抛出的异常 * @异常 RemoteException 当系统通讯发生故障时抛出 * @参看 examples.ejb.basic.containerManaged.AccountBean */ public Enumeration findNullAccounts() throws FinderException, RemoteException;
}
2.编写远程接口程序
编辑文件Account.java并保存到C:\work\src\examples\ejb\basic\containerManaged目录下(或从附带光盘的src\examples\ejb\basic\containerManaged目录拷贝)。Account.java源文件如下:
//Account.java //定义本接口在包examples.ejb.basic.containerManaged中 package examples.ejb.basic.containerManaged; //本接口用到的其他类 //javax.ejb.*中定义了实现EJBean的接口。 import java.rmi.RemoteException; import javax.ejb.*;
/** * 这是AccontBean的远程接口定义。远程接口中定义了客户端能远程调用EJBean的方法。这些方法除了 * 要抛出异常java.rmi.RemoteException之外,和EJBean中的定义是一致的。但并不是EJBean来实 * 现这个接口,而是由容器自动产生的类AccontBeanE实现的。 */ //这个接口必须继承javax.ejb.EJBObject接口 public interface Account extends EJBObject {
/** * 远程方法:存入一定数目的金额 * * @参数 amount 存入金额的数量 * @返回 double 操作实际结果 * @异常 RemoteException 当系统通讯发生故障时抛出 */ public double deposit(double amount) throws RemoteException;
/** * 远程方法:提取一定数目的金额 * * @参数 amount 提取金额的数量 * @返回 double 操作实际结果 * @异常 RemoteException 当系统通讯发生故障时抛出 * @异常 ProcessingErrorException * 购买操作出错时抛出的异常 */ public double withdraw(double amount) throws ProcessingErrorException, RemoteException;
/** * 远程方法:结算 * @返回 double 结算值 * @异常 RemoteException 当系统通讯发生故障时抛出 */ public double balance() throws RemoteException;
/** * 返回账号类型 * * @返回 String 账号类型 * @异常 RemoteException 当系统通讯发生故障时抛出 */ public String accountType() throws RemoteException;
}
3.编写实现类程序
编辑文件AccountBean.java并保存到C:\work\src\examples\ejb\basic\containerManaged目录下(或从附带光盘的src\examples\ejb\basic\containerManaged目录拷贝)。AccountBean.java源文件如下:
//AccountBean.java //定义本接口在包examples.ejb.basic.containerManaged中 package examples.ejb.basic.containerManaged; //本类用到的其他类。javax.ejb.*是开发EJB应用需要的类库。javax.naming.*是实现JNDI服务需要的类库。 import java.io.Serializable; import java.util.Enumeration; import java.util.Vector;
import javax.ejb.CreateException; import javax.ejb.DuplicateKeyException; import javax.ejb.EJBException; import javax.ejb.EntityBean; import javax.ejb.EntityContext; import javax.ejb.FinderException; import javax.ejb.NoSuchEntityException; import javax.ejb.ObjectNotFoundException; import javax.ejb.RemoveException; import javax.naming.InitialContext; import javax.naming.NamingException; import javax.sql.DataSource;
/** * AccountBean是实体EJB,它演示了: * 容器管理的JDBC持续性管理和事务管理; * 在这个文件中的代码并没有直接访问数据库; * 用户定义的异常; * 使用isModified方法,这个方法改变容器管理的字段,通过设置isDirty */ //这个类是实体Bean,必须实现接口 EntityBean public class AccountBean implements EntityBean { //设置是否打印控制台 final static boolean VERBOSE = true; //声明实体上下文变量 private EntityContext ctx; //声明实体EJB属性变量 public String accountId; // 这也是主键类 public double balance; public String accountType; private transient boolean isDirty; // 决定bean是否谢数据库的标志
/** * 为EJBean设置实体EJB上下文 * * @参数 ctx EntityContext */ public void setEntityContext(EntityContext ctx) { log("setEntityContext called (" + id() + ")"); this.ctx = ctx; }
/** * 取消实体上下文设置 * */ public void unsetEntityContext() { log("AccountBean.unsetEntityContext (" + id() + ")"); this.ctx = null; }
/** * 返回EJBean是否被改变 * * 这个方法必须为public 以使被容器调用 * * @返回 boolean isDirty */ public boolean isModified() { log("isModified(): isDirty = " + (isDirty ? "true" : "false")); return isDirty; }
/** * 设置EJBean的改变标志 * * @参数 flag 改变标志 */ public void setModified(boolean flag) { isDirty = flag; log("setModified(): " + id() + (String) (flag ? ": requires saving" : ": saving not required")); }
/** * 返回标识这个EJBean的主键 * * @返回 String 标志 */ private String id() { return "" + System.identityHashCode(this) + ", PK = " + (String) ((ctx == null) ? "nullctx" : ((ctx.getPrimaryKey() == null ? "null" : ctx.getPrimaryKey().toString()))) + "; isDirty = " + isDirty; }
/** * 这是本类必须实现的方法,在本例中没有用到 * */ public void ejbActivate() { log("AccountBean.ejbActivate (" + id() + ")"); }
/** * 这是本类必须实现的方法,在本例中没有用到 * */ public void ejbPassivate() { log("AccountBean.ejbPassivate (" + id() + ")"); }
/** * 这是本类必须实现的方法,在本例中没有用到 * */ public void ejbLoad() { log("AccountBean.ejbLoad (" + id() + ")"); }
/** * 设置EJBean的改变标记为false * */ public void ejbStore() { log("AccountBean.ejbStore (" + id() + ")");
setModified(false); }
/** * 这是本类必须实现的方法,在本例中没有用到 * */ public void ejbRemove() throws RemoveException { log("AccountBean.ejbRemove (" + id() + ")"); } /** * 这个方法和"AccountBean.java"中定义的的Bean的"ejbCreate"方法相对应 * 这两个方法的参数应该相同。当客户端调用"TraderHome.create()"方法时,EJB容器 * 会找到EJBean的实例,并调用它的"ejbCreate()"方法。 * 对容器管理的ejb,ejbCreate方法返回为null,而bean管理的ejb,返回的是主键类。 * @参数 accountID String 账号ID * @参数 initialBalance double 初始化结算值 * @参数 type String 账号类型 * @异常 javax.ejb.CreateException * 创建bean错误时抛出的异常 * @参看 examples.ejb.basic.containerManaged.AccountHome */ public String ejbCreate(String accountId, double initialBalance, String type) throws CreateException { log("AccountBean.ejbCreate( id = " + System.identityHashCode(this) + ", PK = " + accountId + ", " + "initial balance = $ " + initialBalance + ")"); this.accountId = accountId; this.balance = initialBalance; this.accountType = type; return null; // See 9.4.2 of the EJB 1.1 specification }
/** * 这是本类必须实现的方法,在本例中没有用到 */ public void ejbPostCreate(String accountId, double initialBalance, String type) { log("AccountBean.ejbPostCreate (" + id() + ")"); }
// 应用程序定义的方法
/** * 存入一定金额 * * @参数 amount double 数量 * @返回 double 结算 */ public double deposit(double amount) { log("AccountBean.deposit: Depositing $" + amount + " into ’" + accountId + "’"); //业务逻辑计算 balance += amount; //设置改变标记 setModified(true); return balance; }
/** * 提取一定数量的金额 * * @参数 amount double 数量 * @返回 double 结算 * @exception ProcessingErrorException * 如果提取的数量大于结算值 */ public double withdraw(double amount) throws ProcessingErrorException { log("AccountBean.withdraw: Withdrawing $" + amount + " from ’" + accountId + "’"); if (amount > balance) { //抛出用户定义异常 throw new ProcessingErrorException("Request to withdraw $" + amount + "; is more than balance $" + balance + " in account " + accountId); } //业务逻辑计算 balance -= amount; //设置改变标记 setModified(true); return balance; } /** * 返回当前的结算 * * @返回 double 结算 */ public double balance() { log("AccountBean.balance (" + id() + ")");
return balance; } /** * 返回账号类型 * * @返回 String 账号类型 */ public String accountType() { log("AccountBean.accountType (" + id() + ")");
return accountType; } //控制台输出 private void log(String s) { if (VERBOSE) System.out.println(s); } }
4.编写处理异常程序
用文本编辑器编辑文件ProcessingErrorException.java并将它保存到C:\work\src\examples\ejb\basic\containerManaged目录下(或从附带光盘的src\examples\ejb\basic\containerManaged目录拷贝)。其源文件如下:
//ProcessingErrorException.java //定义本类在包examples.ejb.basic.containerManaged 中 package examples.ejb.basic.containerManaged;
/** * 这是用户定义的异常类 */ //用户定义的异常类必须继承Exception public class ProcessingErrorException extends Exception {
/** * 获取没有字符串参数的异常 * */ public ProcessingErrorException() {}
/** * 用特定的字符串构造异常 * * @参数 message Exception 消息 */ public ProcessingErrorException(String message) {super(message);} }
5.编写客户端测试程序
编辑文件Client.java并将它保存到C:\work\src\examples\ejb\basic\containerManaged目录下(或从附带光盘的src\examples\ejb\basic\containerManaged目录拷贝)。其源文件如下:
//Client.java //定义本类在包examples.ejb.basic.containerManaged 中 package examples.ejb.basic.containerManaged; //本类用到的其他类 import java.rmi.RemoteException; import java.util.Enumeration; import java.util.Hashtable; import java.util.Properties; import java.util.Vector; //本类用到的EJB类 import javax.ejb.CreateException; import javax.ejb.DuplicateKeyException; import javax.ejb.FinderException; import javax.ejb.ObjectNotFoundException; import javax.ejb.RemoveException; //本类用到的名称服务类 import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NamingException; import javax.rmi.PortableRemoteObject; /** * 这个类演示了如何调用一个实体EJB,并进行如下操作: * A:创建一个Account远程对象,存入一些钱。然后试图提取超过当前结算的金额。或抛出用户定义的异常, * 最后,清除Account远程对象。 * B:创建一些新的账号,它们有不同的结算值。找到所有计算值大于给定数值的账号。找到结算职为0的账号。 * 试图查找账号类型为null的账号。最后,删除所有新创立的账号。 * 这个例子同时演示了怎样在JNDI树查找EJB主接口。 */ public class Client { //声明变量 private String url; private String accountId; private AccountHome home; //构造方法 public Client(String url, String accountId) throws NamingException {
this.url = url; this.accountId = accountId; //找找主接口,lookupHome是本例自定义方法。 home = lookupHome(); }
/** * 在命令行运行这个实例: * java examples.ejb.basic.containerManaged.Client "t3://localhost:7001" * 参数是可选的 * @参数 url URL such as "t3://localhost:7001" of Server * @参数 accountID String Account ID to test, default "10020" */ public static void main(String[] args) { System.out.println("\nBeginning containerManaged.Client...\n");
String url = "t3://localhost:7001"; String accountId = "10020";
// Parse the argument list switch(args.length) { case 2: accountId = args[1]; // fall through case 1: url = args[0]; break; }
Client client = null;
try { //实例化本类 client = new Client(url, accountId); } catch (NamingException ne) { //异常处理 log("Unable to look up the beans home: " + ne.getMessage()); System.exit(1); }
try { //运行实例A client.runExamplePartA(); //运行实例B client.runExamplePartB(); } catch (Exception e) { //异常处理 log("There was an exception while creating and using the Accounts."); log("This indicates that there was a problem communicating with the server: "+e); }
System.out.println("\nEnd containerManaged.Client...\n"); }
/** * 执行实例A * * A: 存入一定数量的金额,并试图提取超过结算的金额,会抛出应用定义的异常 */ public void runExamplePartA() { log("Starting Part A of the example...\n"); //初始化变量 double initialBalance = 3000; String accountType = "Savings"; Account ac = null; try { //创建账号,createAccount是本类定义的方法 ac = createAccount(accountId, initialBalance, accountType); } catch(DuplicateKeyException dke) { //异常处理 log("An account with id " + accountId + " already exists!"); } catch(Exception e) { //异常处理 log("Error creating account: " + e.getMessage()); System.exit(1); } //设置初始化变量 int amount = 2000; double balance = 0; log("\nPart A: Depositing $" + amount ); try { //存入一定数量的金额,deposit是EJB远程方法 balance = ac.deposit(amount); log("Current balance is $" + balance); } catch (Exception e) { log("Error during deposit: "+e.getMessage()); }
try { log("Attempting to withdraw an amount greater than current balance. Expecting an exception...\n"); //试图提取超过结算的金额 balance = ac.withdraw(balance+1); log("Error: expected an exception."); } catch (ProcessingErrorException pe) { //异常处理 log("Received expected Processing Error:\n" + pe); } catch(Exception e) { //异常处理 log("Error during withdraw: "+e.getMessage()); }
log("Removing account...\n"); try { //清除账号ac,remove 是远程EJB方法 ac.remove(); } catch(Exception e) { log("Error removing account: "+e.getMessage()); }
log("End Part A of the example...\n"); }
/** * 例B * * B: 创建20个不同结算值的新账号。 * 找到所有结算值大于给定值的账号 * 结束时,清除账号 */ public void runExamplePartB() throws CreateException, RemoteException, FinderException, RemoveException { log("Starting Part B of the example...\n"); //声明变量 int numBeans = 20; //声明远程对象数组 Account [] accounts = new Account [numBeans];
// 创建20个有不同初值的账号 for (int i=0; i<numBeans; i++) { // if (Math.IEEEremainder(i, 5) == 0) if (i % 5 == 0) { // 创建一些账号类型为null的账号。 // (仅仅是为了下面的查找) accounts [i] = findOrCreateAccount("ID: "+i, i * 1000, null); } else { accounts [i] = findOrCreateAccount("ID: "+i, i * 1000, "Savings"); } }
// 打印账号结算值 for (int i=0; i<numBeans; i++) { log("Account: :"+accounts[i].getPrimaryKey()+ " has a balance of "+accounts[i].balance()); }
// 查找所有结算大于5000的账号 findBigAccounts(5000.0); // 查找第一个结算值为0的账号 findAccountWithZeroBalance(); // 查找所有账号类型为null的账号 findNullAccounts();
// 清除所有账号
log("Removing beans..."); for (int i=0; i<numBeans; i++) { accounts[i].remove(); } log("End Part B of the example...\n"); }
/** * 列出第一个结算值为0的账号 * 这个finder方法演示了只返回一个纪录的方法。 */ private void findAccountWithZeroBalance() throws FinderException, RemoteException { log("\nQuerying for an account with zero balance..."); try { // 创建账号远程对象 Account zeroBalance = (Account) PortableRemoteObject.narrow(home.findAccount(0), Account.class); // Account zeroBalance = home.findAccount(0); log("Account " + zeroBalance.getPrimaryKey() + "; balance is zero"); } catch(ObjectNotFoundException onfe) { //异常处理 log("No Account was found with a balance of zero"); } }
/** * 列出所有账号类型为null的账号 * 这个finder方法演示返回账号枚举 */ private void findNullAccounts() throws RemoteException, FinderException { log("\nQuerying for accounts with a null account type"); //账号枚举 Enumeration enum = home.findNullAccounts();
if(! enum.hasMoreElements()) { log("No accounts were found with a null account type"); } //创建账号远程对象 while (enum.hasMoreElements()) { Account nullAccount= (Account) PortableRemoteObject.narrow(enum.nextElement(), Account.class); log("Account " + nullAccount.getPrimaryKey() + "; account type is " + nullAccount.accountType()); } }
/** * 列出所有结算大于给定值的账号 * 这个finder方法演示返回枚举账号 */ private void findBigAccounts(double balanceGreaterThan) throws RemoteException, FinderException { log("\nQuerying for accounts with a balance greater than " + balanceGreaterThan + "..."); //调用主接口创建账号方法findBigAccounts,返回账号枚举 Enumeration enum = home.findBigAccounts(balanceGreaterThan);
if(! enum.hasMoreElements()) { log("No accounts were found!"); }
while (enum.hasMoreElements()) { Account bigAccount= (Account) //创建远程对象 PortableRemoteObject.narrow(enum.nextElement(), Account.class);
log("Account " + bigAccount.getPrimaryKey() + "; balance is $" + bigAccount.balance()); } }
/** * 如果对应id的账号以存在,则返回这个id,否则创建它 */ private Account findOrCreateAccount(String id, double balance, String accountType) throws CreateException, FinderException, RemoteException { Account remote = null; try { remote = (Account) PortableRemoteObject.narrow(home.findByPrimaryKey(id),Account.class); // remote = home.findByPrimaryKey(id); } catch (ObjectNotFoundException onfe) { // 账号不存在,创建它 remote = createAccount(id, balance, accountType); } return remote; }
/** * 给定id和结算创建一个新的账号 */ private Account createAccount(String id, double balance, String accountType) throws CreateException, RemoteException { log ("Creating account " + id + " with a balance of " + balance + " account type " + accountType + "..."); //创建远程账号对象 Account ac = (Account) PortableRemoteObject.narrow( home.create(id, balance, accountType), Account.class);
log("Account " + id + " successfully created");
return ac; }
/** * 使用JNDI查找bean的主接口 */ private AccountHome lookupHome() throws NamingException { Context ctx = getInitialContext();
try { //查找主接口 Object home = (AccountHome) ctx.lookup("containerManaged.AccountHome"); return (AccountHome) PortableRemoteObject.narrow(home, AccountHome.class);
} catch (NamingException ne) { //异常处理 log("The client was unable to lookup the EJBHome. Please make sure " + "that you have deployed the ejb with the JNDI name " + "containerManaged.AccountHome on the WebLogic server at "+url);
throw ne; } }
/** * 获取初始化上下文 */ private Context getInitialContext() throws NamingException {
try { // 设置属性对象 Properties h = new Properties(); h.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory"); h.put(Context.PROVIDER_URL, url); //创建初始化上下文 return new InitialContext(h); } catch (NamingException ne) { //异常处理 log("We were unable to get a connection to the WebLogic server at "+url); log("Please make sure that the server is running."); throw ne; } } //控制台输出 private static void log(String s) { System.out.println(s); } }
6.编写EJB描述文件
编辑文件ejb-jar.xml并将它保存到C:\work\src\examples\ejb\basic\containerManaged目录下(或从附带光盘的src\examples\ejb\basic\containerManaged目录拷贝)。其源文件如下:
<?xml version="1.0"?>
<!DOCTYPE ejb-jar PUBLIC ’-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 1.1//EN’ ’http://java.sun.com/j2ee/dtds/ejb-jar_1_1.dtd’>
<ejb-jar> <enterprise-beans> <entity> <ejb-name>containerManaged</ejb-name> <home>examples.ejb.basic.containerManaged.AccountHome</home> <remote>examples.ejb.basic.containerManaged.Account</remote> <ejb-class>examples.ejb.basic.containerManaged.AccountBean</ejb-class> <persistence-type>Container</persistence-type> <prim-key-class>java.lang.String</prim-key-class> <reentrant>False</reentrant> <cmp-field> <field-name>accountId</field-name> </cmp-field> <cmp-field> <field-name>balance</field-name> </cmp-field> <cmp-field> <field-name>accountType</field-name> </cmp-field> <primkey-field>accountId</primkey-field> </entity> </enterprise-beans> <assembly-descriptor> <container-transaction> <method> <ejb-name>containerManaged</ejb-name> <method-intf>Remote</method-intf> <method-name>*</method-name> </method> <trans-attribute>Required</trans-attribute> </container-transaction> </assembly-descriptor> </ejb-jar>
7.编写CMP映射文件
编辑weblogic-cmp-rdbms-jar.xml,保存到C:\work\src\examples\ejb\basic\containerManaged目录下(或从附带光盘的src\examples\ejb\basic\containerManaged目录拷贝)。其源文件如下:
<!DOCTYPE weblogic-rdbms-bean PUBLIC ’-//BEA Systems, Inc.//DTD WebLogic 5.1.0 EJB RDBMS Persistence//EN’ ’http://www.bea.com/servers/wls510/dtd/weblogic-rdbms-persistence.dtd’> <weblogic-rdbms-bean> <pool-name>demoPool</pool-name> <table-name>ejbAccounts</table-name> <attribute-map> <object-link> <bean-field>accountId</bean-field> <dbms-column>id</dbms-column> </object-link> <object-link> <bean-field>balance</bean-field> <dbms-column>bal</dbms-column> </object-link> <object-link> <bean-field>accountType</bean-field> <dbms-column>type</dbms-column> </object-link> </attribute-map> <finder-list> <finder> <method-name>findBigAccounts</method-name> <method-params> <method-param>double</method-param> </method-params> <finder-query><![CDATA[(> balance $0)]]></finder-query> </finder> <finder> <method-name>findAccount</method-name> <method-params> <method-param>double</method-param> </method-params> <finder-query><![CDATA[(= balance $0)]]></finder-query> </finder> <finder> <method-name>findNullAccounts</method-name> <method-params> </method-params> <finder-query><![CDATA[(isNull accountType)]]></finder-query> </finder> </finder-list> <options> <use-quoted-names>false</use-quoted-names> </options> </weblogic-rdbms-bean>
8.编写ejb部署文件
编辑文件weblogic-ejb-jar.xml并保存到C:\work\src\examples\ejb\basic\containerManaged目录下(或从附带光盘的src\examples\ejb\basic\containerManaged目录拷贝)。其源文件如下:
<?xml version="1.0"?> <!DOCTYPE weblogic-ejb-jar PUBLIC ’-//BEA Systems, Inc.//DTD WebLogic 5.1.0 EJB//EN’ ’http://www.bea.com/servers/wls510/dtd/weblogic-ejb-jar.dtd’>
<weblogic-ejb-jar> <weblogic-enterprise-bean> <ejb-name>containerManaged</ejb-name> <caching-descriptor> <max-beans-in-cache>1000</max-beans-in-cache> </caching-descriptor> <persistence-descriptor> <is-modified-method-name>isModified</is-modified-method-name> <persistence-type> <type-identifier>WebLogic_CMP_RDBMS</type-identifier> <type-version>5.1.0</type-version> <type-storage>META-INF/weblogic-cmp-rdbms-jar.xml</type-storage> </persistence-type> <persistence-use> <type-identifier>WebLogic_CMP_RDBMS</type-identifier> <type-version>5.1.0</type-version> </persistence-use> </persistence-descriptor> <jndi-name>containerManaged.AccountHome</jndi-name> </weblogic-enterprise-bean> </weblogic-ejb-jar>
5.3.3 编译
本例中包括服务器端程序和客户端程序,把客户端程序放在一个目录下,这里用C:\bea\wlserver6.0\config\mydomain\clientclasses。如果没有子目录clientclasses,则创建它。 ·打开命令窗口,进入C:\work\src\examples\ejb\basic\containerManaged目录。 ·运行设置环境变量命令脚本setEnv.cmd: C:\work\src\examples\ejb\basic\containerManaged>c:\work\setEnv ·运行编译脚本build.cmd: C:\work\src\examples\ejb\basic\containerManaged>build 其中build.cmd代码如下:
@REM Copyright (c) 2000 BEA Systems, Inc. All Rights Reserved. @REM You must set your environment by running the setExamplesEnv shell script @REM prior to executing this script.
@REM Create the build directory, and copy the deployment descriptors into it mkdir build build\META-INF copy *.xml build\META-INF
@REM Compile EJB classes into the build directory (jar preparation) javac -d build Account.java AccountHome.java ProcessingErrorException.java AccountBean.java
@REM Make a EJB jar file, including XML deployment descriptors cd build jar cv0f std_ejb_basic_containerManaged.jar META-INF examples cd ..
@REM Run EJBC on jar file java -classpath %WL_HOME%/lib/weblogic_sp.jar;%WL_HOME%/lib/weblogic.jar weblogic.ejbc -compiler javac build\std_ejb_basic_containerManaged.jar %WL_HOME%\config\%DOMAIN_NAME%\applications\ejb_basic_containerManaged.jar
@REM Compile servlets and EJB interfaces into WEB-INF/classes directory of the Examples Web App @REM This ensures that the EJB can be accessed by JSPs and servlets of the Examples Web App javac -d %EX_WEBAPP_CLASSES% Account.java AccountHome.java ProcessingErrorException.java
@REM Compile EJB interfaces & client app into the clientclasses directory javac -d %CLIENT_CLASSES% Account.java AccountHome.java ProcessingErrorException.java Client.java
5.3.4 定义连接池
本示例用到连接池demoPool,下面演示如何通过系统管理工具Console为数据库demo定义连接池demoPool。 (1)启动WebLogic服务器。 (2)启动系统管理控制台程序console(在浏览器URL中输入http://127:0.0.1:7001/console/,回车) (3)点出console控制台左面板的Services/JDBC/Connection Pools,如图5-3所示。 (4)接下来是一个主要的步骤,点击控制台右面板的“Create a new JDBC ConnectionPool...”,创建新的连接池。进入图5-4的操作界面。定义新的连接池名称Name为demoPool,定义URL为“jdbc:cloudscape:demo”,定义驱动类“Driver ClassName”为“COM.cloudscape.core.JDBCDriver”,义属性Properties为“user=none password=none srver=none”,然后点击“Create”创建。 (5)预定义连接池的连接数。点击图5-4所示的Connection页,进入图5-5所示的页面,预定义连接“Initial Capacity:”改为:1,“Maximum Capacity:”改为2,“Capacity Increment:”改为1,其余设置不变。点击“Apply”按钮。 (6)下面就是创建完连接池后,还要把它部署到系统管理的服务器myserve中,点击图5-4的Targets页,在Avaliable栏中选中myserver,点击向右的箭头,点击“Apply”,如图5-6所示。
5.3.5 修改启动脚本
本示例使用WebLogic Server 6.0 自带的小型关系型数据库cloudscape。因此在WebLogic Server启动的时候,要对启动脚本文件startWebLogic.cmd进行修改。如果还没有修改,则修改如下两个地方:
1.修改CLASSPATH环境变量
打开C:\bea\wlserver6.0\config\mydomain目录下的startWebLogic.cmd文件,找到set CLASSPATH=.;.\lib\weblogic_sp.jar;.\lib\weblogic.jar行。把下面的设置加入这行的下一行。设置后,显示如下: ... set CLASSPATH=.;.\lib\weblogic_sp.jar;.\lib\weblogic.jar set CLASSPATH=%CLASSPATH%;.\samples\eval\cloudscape\lib\cloudscape.jar; ...
2.修改启动命令 找到“%JAVA_HOME%\bin\java”开头的一行,修改这行,增加一个属性项,修改后显示如下: "%JAVA_HOME%\bin\java" -hotspot -ms64m -mx64m -classpath %CLASSPATH% -Dweblogic.Domain=mydomain -Dweblogic.Name=myserver "-Dbea.home=c:\bea" -Dcloudscape.system.home=./samples/eval/cloudscape/data "-Djava.security.policy==c:\bea\wlserver6.0/lib/weblogic.policy" -Dweblogic.management.password=%WLS_PW% weblogic.Server 书写的时候注意文字的有效性。保存startWebLogic.cmd,重新启动WebLogic Server。
5.3.6 运行测试
首先,启动Weblogic Server 6.0的缺省服务器。 运行测试程序。继续使用前几个步骤使用的命令窗口,执行: C:\work\src\examples\ejb\basic\containerManaged>java examples.ejb.basic.containerManaged.Client t3://127.0.0.2:7001/ 观察命令窗口的运行情况,如图5-7所示。
|
|
|
| |
 |
热门院校推荐 |
 |
|
|
|
|
|
|
 |
| |
| |
| |
|
|
|