EJB tutorial (推荐)

类别:Java 点击:0 评论:0 推荐:
我直接粘贴过来的,不知道格式有没有变坏,如果看起来不整齐,可以到我的blog去看看吧:)那里还有源文件的下载。 环境设定为:weblogic 6.1 + Jbuilder 9;
数据表为tmp_emp,要求用EJB的方式对这个表进行操作。字段为:

SQL> desc tmp_emp; Name Type Nullable Default Comments -------- ------------ -------- ------- ------------------------------------ ID VARCHAR2(10) 职员ID NAME VARCHAR2(20) Y 职员名称 JOB VARCHAR2(20) Y 职员的工作名称 HIREDATE DATE Y 职员入职时间 SAL NUMBER(7,2) Y 职员薪水 COMM VARCHAR2(20) Y 备注 DEPTID VARCHAR2(10) Y 职员所属部门ID;和tmp_dept表的ID关联
预备:编码基本pattern:
包名全部用小写字母,如ejbsample.session
类名用大小写结合的方法,且首字母大写,如EmployeeAction
变量名用大小写结合的方法,且首字母小写,如strName
模块级变量前面加上下划线,如_strName 数据库的设置:
安装好Oracle的客户端,保证与数据库服务器正确建立了连接。
JBuilder9的设置:
可以参考以前的文章。要点:oracle的库文件设定好;"Enterprise setup"设定好
WebLogic的设置:
启动Weblogic
打开控制台: http://localhost:7001/console
从JDBC的connection pools里面,"Configure a new JDBC connection pool",参数可以参考下面:

**Name: ejbDemo (说明:这个可以任意取) **URL: jdbc:oracle:thin:@172.16.3.100:1521:dev3 (说明:这个URL就是JDBC连接时的URL,格式可以参考JDBC的文档;dev3是数据库服务器172.16.3.100上的SID) **Driver classname: oracle.jdbc.driver.OracleDriver **Properties: user=pm password=pm dll=ocijdbc8 protocol=thin (说明:用户名和密码换成自己的) **Initial capacity 3 **Maximum capacity 10 (说明:最后别忘了将"Targets"里面"Available" apply到"Chosen"里面去) 配置一个"Tx Data Sources":

**Name: ejbDS **JNDI Name: ejbDS (说明:这就是在EJB设计的时候,要指定的数据源名称) **Pool Name: ejbDemo (说明:这就是前面建立的connection pool的名称) 在JBuilder中建立"EJB module":
建议将.jar文件的保存位置可以放到weblogic的applications目录下:C:\bea\wlserver6.1\config\mydomain\applications 建好一个空的module之后,首先配置它的"DataSources"。右击"DataSources",选择"Import Schema from Database"。
首先选择"Driver"为"oracle.jdbc.driver.OracleDriver",然后URL填入"jdbc:oracle:thin:@172.16.3.100:1521:dev3","Username"和"Password"填入正确的(我这里分别填入"pm"、"pm"),"JNDI name"填入前面设定的"ejbDS". ok之后,JBuilder就自动开始从数据库里面"Importing Schema"。如果没有出现这样的动作,就说明以前数据库的配置没有正确,再检查一遍。 在JBuilder的ejb设计器中设计实体bean:
从JBuilder自动得到的数据表中,找到我们要操作的tmp_emp表。右击它,选择"Creat CMP 2.0 Entity Bean",JBuilder就会自动根据表的结构生成实体bean。如果对JBuilder自动生成的参数不满意,可以自己修改。我改动如下:

**Bean name: EbnEmployee (说明:改动Bean name之后,Abstract schema name会自动改成一样的名字) **Interfaces: local **Classes and packages: ejbsample.employee.entity (说明:a)包名全部用小写 b)在JBuilder的Classes and packages定义页面,只需要输入default package为ejbsample.employee.entity, 其它的项JBuilder会自动填好) **增加3个方法(当然,你如果需要添加方法,可以随时到JBuilder的EJB设计器里面来添加): void setModel ( EmployeeModel model ) 方法(interface:local) EmployeeModel getModel () 方法 (interface :local ) ejbCreate( EmployeeModel model ) 方法 (interface :local home ) (说明:EmployeeModel类后面马上建立) 在JBuilder的ejb设计器中设计session bean:
在JBuilder的EJB设计容器中右击,选择新建session bean。修改参数如下:

**Bean name: SbnEmployee **Session type: stateless **interfaces: remote **class--default package: ejbsample.employee.session **增加如下方法(当然,你如果需要添加方法,可以随时到JBuilder的EJB设计器里面来添加): EmployeeModel insert ( EmployeeModel model ) 方法 (interfaces: remote ) EmployeeModel update ( EmployeeModel model ) 方法 (interfaces: remote ) boolean del ( String pk ) 方法 ( interfaces: remote ) EmployeeModel findByPk ( String pk ) 方法 ( interfaces: remote ) boolean delBatch ( String[] sid ) 方法 ( interfaces:remote ) java.util.ArrayList queryBySql ( String strSql ) 方法 ( interfaces:remote ) (说明:我们可以看到EmployeeModel类的使用是无处不在的。事实上,EmployeeModel里面包装了所有的页面显示元素, 在与jsp页面打交道的时候,它要发挥重要作用。) 下面就开始建立EmployeeModel类:
新建一个class,命名为EmployeeModel,package定义为ejbsample.employee,基类选择为java.io.Serializable.内容如下:

package ejbsample.employee; import java.io.Serializable; /** * Title: (no title) * Description: 一般来说,xxModel类可以看作对jsp页面所有显示元素的包装。它将是主要与jsp页面打交道的类 * Copyright: Copyright (c) 2003 * Company: Ebuilds * @author Alex * @version 1.0 */ public class EmployeeModel implements Serializable { private String _strID; //职员ID private String _strName; //职员名称 private String _strJob; //职员的工作名称 private java.sql.Date _dtHireDate; //职员入职时间 private double _dSal; //职员薪水 private String _strComm; //备注 private String _strDeptID; //职员所属部门ID;和tmp_dept表的ID关联 //设定属性、读取属性 开始 public String getID () { return _strID; } public void setID ( String in ) { _strID = in; } public String getName () { return _strName; } public void setName ( String in ) { _strName = in; } public String getJob () { return _strJob; } public void setJob ( String in ) { _strJob = in; } public java.sql.Date getHireDate () { return _dtHireDate; } public void setHireDate ( java.sql.Date in ) { _dtHireDate = in; } public double getSal () { return _dSal; } public void setSal ( double in ) { _dSal = in; } public String getComm () { return _strComm; } public void setComm ( String in ) { _strComm = in; } public String getDeptID () { return _strDeptID; } public void setDeptID ( String in ) { _strDeptID = in; } //设定属性、读取属性 结束 public void setModel ( EmployeeModel in ) { _strID = in.getID(); _strName = in.getName(); _strJob = in.getJob(); _dtHireDate = in.getHireDate(); _dSal = in.getSal(); _strComm = in.getComm(); _strDeptID = in.getDeptID(); } public EmployeeModel() { } public static void main(String[] args) { EmployeeModel employeeModel1 = new EmployeeModel(); } } 写一个EJB的公共类:EjbCommon.java。非常重要的代码!

package ejbsample; /** * Title: (no title) * Description: 这是写ejb的时候需要用到的公共类,比如JNDI名称、取home接口。当进行大型开发,有很多ejb的时候,这个类是很有必要的 * Copyright: Copyright (c) 2003 * Company: Ebuilds * @author Alex * @version 1.0 */ import java.util.*; import javax.naming.*; import javax.ejb.*; import javax.rmi.PortableRemoteObject; import javax.naming.InitialContext; import javax.naming.NamingException; import weblogic.jndi.Environment; import javax.sql.*; import java.sql.*; public class EjbCommon { //这里存放所有的JNDI名。如果JNDI名很多,建议可以将它们单独放到一个文件中去。 //说明:JNDI名在这里找到:JB的"project content"中,双击"EbnEmployee",可以看到"Local Home JNDI Name",就是了。 public static final String E_EMPLOYEE_JNDI = "EbnEmployee"; public static final String S_EMPLOYEE_JNDI = "SbnEmployee"; public static final String DATASOURCE_JNDI = "ejbDS"; //以下是取home接口相关的函数 private static Context context = null; /** * 取得InitialContext,供后面的取home接口使用 * @return * @throws NamingException */ protected static Context getInitialContext() throws NamingException { String user = null; String password = null; Properties properties = null; try { properties = new Properties(); properties.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory"); if (user != null) { properties.put(Context.SECURITY_PRINCIPAL, user); properties.put(Context.SECURITY_CREDENTIALS, password == null ? "" : password); } return new InitialContext(properties); } catch(NamingException e) { throw e; } } /** *用于取得远程home接口。一般来说,session bean的接口是远程的(不是local),所以,取得session bean的home接口要用到这个函数 * @param lookupName * @param homeClass * @return */ public static Object getRemoteEJBHome(String lookupName, Class homeClass) throws NamingException { try { if (context==null) { context = getInitialContext(); } Object home = PortableRemoteObject.narrow( context.lookup(lookupName), homeClass); return home; } catch (NamingException ne) { //throw new EJBException(ne.getMessage()); throw ne; } } /** * 用于取得本地home接口。一般来说,实体bean的接口是本地(local)的,所以,取得实体bean的home接口要用到这个函数。 * @param lookupName * @return */ public static Object getLocalEJBHome(String lookupName) throws NamingException{ try { if (context==null) { context = getInitialContext(); } Object home = context.lookup(lookupName); return home; } catch (NamingException ne) { //throw new EJBException(ne.getMessage()); throw ne; } } //下面的是关于数据库的操作。一个重要的,用完了getConnection()之后,记得释放connection! /** * 从定义好的datasource里面取出一个connection * @return */ public static Connection getConnection() throws NamingException, SQLException{ Connection con=null; try { if ( context == null ){ context = getInitialContext(); } DataSource datasource=(DataSource)context.lookup( DATASOURCE_JNDI ); con = datasource.getConnection(); } catch (NamingException ex) { throw ex; } catch (SQLException ex) { throw ex; } return con; } /** * 这是取连接的远程版本。但是好像不需要用它。 * @return */ public static Connection getConnection_remote() throws NamingException, SQLException{ try { if (context==null) { context = getInitialContext(); } DataSource ds = (DataSource)PortableRemoteObject.narrow( context.lookup(DATASOURCE_JNDI), DataSource.class); return ds.getConnection(); } catch (NamingException ne) { //throw new EJBException(ne.getMessage()); throw ne; } catch (SQLException e) { //throw new EJBException(e.getMessage()); throw e; } } /** * 作用:用html格式将strmsg输入到c:\strlogfile文件中去 * 将会输出类似这样的语句: *

[2003-四月-29 04:44:03] 被调试文件:vwDetail.jsp 被调试函数:(开始设置projectID) 调试描述:
取得的projectID为ERPPM200212110000000658310000E8E7FF69

* * Added by daihua 2003-4-29 11:16 * @param strMsg */ public static void logOneLineToFile ( String strLogFile, String strDebugFileName, String strDebugFuncName, String strDebugMsg ){ //如果不需要debug输出的话,直接返回 /*if ( ! debuggingOn ) return; */ java.io.File fd = new java.io.File ( "c:\\debug" ); if ( !fd.exists() ) { fd.mkdirs(); } //根据当前的日期自动生成debug的文件名,比如:c:\20030506debug.html /*SimpleDateFormat sdfF = new SimpleDateFormat ( "yyyyMMdd" ); String strLogFileName = "c:\\debug\\" + sdfF.format( new Date() ) + "debug.html" ; */ String strLogFileName = "c:\\debug\\" + strLogFile; //还是由程序指定debug的文件名 java.text.SimpleDateFormat bartDateFormat = new java.text.SimpleDateFormat("yyyy-MMMM-dd hh:mm:ss"); java.util.Date date = new java.util.Date(); java.io.FileWriter out = null; try { java.io.File f = new java.io.File ( strLogFileName ); if ( !f.exists() ){ f.createNewFile(); } //out = new RandomAccessFile ( f, "rw" ); out = new java.io.FileWriter ( strLogFileName, true ); //To be ready for append //out.seek( out.length() ); String str1 = "<p style=\"font-size:10.5pt; line-height:15pt\">" + "<font color=\"#999999\">[" + bartDateFormat.format(date) + "] 被调试文件:</font>"; String str2 = "<font color=\"#3333FF\">" + strDebugFileName + "</font>"; String str3 = "<font color=\"#999999\"> 被调试函数:</font><font color=\"#3333FF\">" + strDebugFuncName + "</font>"; String str4 = "<font color=\"#999999\"> 调试描述:</font><br>\r\n"; strDebugMsg = "<font color=red>" + strDebugMsg + "</font></p>\r\n"; strDebugMsg = str1 + str2 + str3 + str4 + strDebugMsg; //out.writeChars( "[" + bartDateFormat.format(date) + "] " + strMsg + "\r\n"); out.write( strDebugMsg ); }catch ( Exception e ) { e.printStackTrace(); } finally{ try{ if ( out != null ) out.close(); }catch ( Exception ex ){ ex.printStackTrace(); } } } public EjbCommon() { } public static void main(String[] args) { EjbCommon ejbCommon1 = new EjbCommon(); } } 编辑完成实体bean
打开EbnEmployee、EbnEmployeeHome、EbnEmployeeBean,首先import一下:
import ejbsample.employee.EmployeeModel; 然后开始编辑EbnEmployeeBean,完成EJB设计器里面设计的函数
void setModel(EmployeeModel model)函数:

public void setModel(EmployeeModel model) { this.setId ( model.getID() ); this.setName ( model.getName() ); this.setJob ( model.getJob() ); this.setHiredate ( model.getHireDate() ); this.setSal ( model.getSal() ); this.setComm ( model.getComm() ); this.setDeptid ( model.getDeptID() ); } EmployeeModel getModel()函数

public EmployeeModel getModel() { EmployeeModel data = new EmployeeModel(); data.setID( this.getId()); data.setName( this.getName()); data.setJob( this.getJob() ); data.setHireDate( this.getHiredate() ); data.setSal( this.getSal() ); data.setComm( this.getComm() ); data.setDeptID( this.getDeptid() ); return data; } java.lang.String ejbCreate(EmployeeModel model)

public java.lang.String ejbCreate(EmployeeModel model) throws CreateException { //说明:这个函数非常重要,每次创建实体bean的时候,都会自动调用ejbCreate,所以如果没有完成这个函数的话,实体bean中将无法赋值 setModel ( model ); return null; } 编辑完成session bean类SbnEmployeeBean.java,如下

package ejbsample.employee.session; import javax.ejb.*; import ejbsample.employee.EmployeeModel; import ejbsample.EjbCommon; import java.util.ArrayList; import ejbsample.employee.entity.*; import javax.naming.NamingException; import java.sql.*; import java.rmi.*; public class SbnEmployeeBean implements SessionBean { SessionContext sessionContext; public void ejbCreate() throws CreateException { /**@todo Complete this method*/ } public void ejbRemove() { /**@todo Complete this method*/ } public void ejbActivate() { /**@todo Complete this method*/ } public void ejbPassivate() { /**@todo Complete this method*/ } public void setSessionContext(SessionContext sessionContext) { this.sessionContext = sessionContext; } public EmployeeModel insert(EmployeeModel model) throws CreateException,NamingException,RemoteException{ try { //利用EjbCommon类得到实体bean的home接口 EbnEmployeeHome objHome = (EbnEmployeeHome) EjbCommon.getLocalEJBHome( EjbCommon.E_EMPLOYEE_JNDI ); EbnEmployee objRemote=objHome.create(model); return model; } catch(CreateException e) { throw e; } catch(NamingException e) { throw e; } } public EmployeeModel update(EmployeeModel model) throws FinderException, NamingException, RemoteException { try { //利用EjbCommon类得到实体bean的home接口 EbnEmployeeHome objHome = (EbnEmployeeHome) EjbCommon.getLocalEJBHome(EjbCommon.E_EMPLOYEE_JNDI); EbnEmployee objLocal = objHome.findByPrimaryKey(model.getID()); //调用model的取属性函数,将实体bean更新 //objLocal.setModel(model); //不能这么写。具体为什么,我也不知道。好像没有道理啊 objLocal.setName( model.getName() ); objLocal.setJob( model.getJob() ); objLocal.setHiredate( model.getHireDate() ); objLocal.setSal( model.getSal() ); objLocal.setComm( model.getComm() ); objLocal.setDeptid( model.getDeptID() ); return model; } catch (FinderException e) { throw e; } catch (NamingException e) { throw e; } } public boolean del(String pk) throws RemoveException,FinderException,EJBException,NamingException ,RemoteException { try { //利用EjbCommon类得到实体bean的home接口 EbnEmployeeHome objHome = (EbnEmployeeHome) EjbCommon.getLocalEJBHome( EjbCommon.E_EMPLOYEE_JNDI); EbnEmployee objLocal = objHome.findByPrimaryKey(pk); objLocal.remove(); return true; } catch (RemoveException e) { throw e; } catch (FinderException e) { throw e; } catch (EJBException e) { throw e; } catch (NamingException e) { throw e; } } public EmployeeModel findByPk(String pk) throws FinderException, NamingException, RemoteException { try { //利用EjbCommon类得到实体bean的home接口 EbnEmployeeHome objHome = (EbnEmployeeHome) EjbCommon.getLocalEJBHome(EjbCommon.E_EMPLOYEE_JNDI); EmployeeModel model = new EmployeeModel(); EbnEmployee objLocal = objHome.findByPrimaryKey(pk); model = objLocal.getModel(); return model; } catch (FinderException e) { throw e; } catch (NamingException e) { throw e; } } public boolean delBatch(String[] sid) throws NamingException, SQLException,RemoteException{ String[] sID = null; sID = sid; String sql = "delete FROM tmp_emp WHERE ID='" ; //Note: statmachine is the table name connected with our work String id = new String(); Connection conn = null; Statement st = null; boolean b = false; try { conn = EjbCommon.getConnection(); conn.setAutoCommit(false); st = conn.createStatement(); for(int i = 1;i <= sID.length ;i++ ){ id = sID[i-1]; st.execute(sql + id + "'"); } conn.commit(); b = true; return b; }catch ( NamingException e ){ throw e; }catch(SQLException e){ System.err.print( "delBatch() function error: concerning with database"); try { conn.rollback(); }catch(SQLException sqle){ throw sqle; } throw e; }finally{ try { st.close(); conn.close(); }catch(SQLException e){ throw e; } //return b; //说明:不要在finally里面return,否则,捕捉到的错误不会throw出去!!! } } public java.util.ArrayList queryBySql(String strSql) throws NamingException, SQLException,RemoteException{ ArrayList arrayList = null; EmployeeModel item; Connection conn = null; Statement st = null; ResultSet rs = null; try { conn=EjbCommon.getConnection(); st=conn.createStatement(); rs=st.executeQuery("SELECT * FROM tmp_emp WHERE " + strSql); //Of course, you can change the sql statement according your condition System.out.println("queryBySql函数的sql=" + "SELECT * FROM tmp_emp WHERE " + strSql); arrayList = new ArrayList(); while (rs.next()) { item=new EmployeeModel(); //从数据库里面读取值 item.setID( rs.getString( "ID" )); item.setName( rs.getString( "NAME" )); item.setJob( rs.getString( "JOB" )); item.setHireDate( rs.getDate( "HIREDATE" )); item.setSal( rs.getDouble( "SAL" )); item.setComm( rs.getString( "COMM" )); item.setDeptID( rs.getString( "DEPTID" )); arrayList.add(item); } if ( arrayList.size() <= 0 ){ return null; }else{ return arrayList; } }catch(SQLException e){ System.out.println("queryBySql函数出现了SQL错误:" + e.toString() + ",将返回的ArrayList设置为Null"); throw e; }catch(NamingException e1){ throw e1; } finally{ System.out.println("queryBySql函数进入finally子块,关闭连接"); try { if (rs!=null) rs.close(); }catch(SQLException e){ throw e; } try { if (st!=null) st.close(); }catch(SQLException e){ throw e; } try { if (conn!=null) conn.close(); }catch(SQLException e){ throw e; } //return arrayList; //说明:不要在finally里面return,否则,捕捉到的错误不会throw出去!!! } } } 编制EmployeeAction.java。这个类包装了EJB,是与jsp页面打交道的类。(这个action类,以及前面的model类,是两个主要和jsp页面打交道的类;而action类包装了EJB,model类包装了jsp页面显示元素)
新建一个class,命名为EmployeeAction,package定义为ejbsample.employee。内容如下:

package ejbsample.employee; /** * Title: (no title) * Description: xxAction类基本上是EJB的包装。 * Copyright: Copyright (c) 2003 * Company: Ebuilds * @author Alex * @version 1.0 */ import ejbsample.SequenceUtil; import ejbsample.EjbCommon; import ejbsample.employee.EmployeeModel; import ejbsample.employee.entity.*; import ejbsample.employee.session.*; import javax.ejb.*; import javax.naming.NamingException; import java.rmi.RemoteException; import java.util.ArrayList; import java.sql.*; public class EmployeeAction { /** * 传入一个model(没有ID这个属性),自动加一个唯一的ID,然后往数据库里面加一条记录 * @param model * @return * @throws NamingException * @throws RemoteException * @throws CreateException */ public EmployeeModel add( EmployeeModel model ) throws NamingException, RemoteException, CreateException { model.setID(SequenceUtil.getUniteCode()); //getUniteCode()的作用是:得到一个唯一的ID号。可以随便怎么写这个函数,比如可以用当前的时间作为ID:getTime();或者用网卡物理地址加上当前时间等等 try { SbnEmployeeHome objHome = (SbnEmployeeHome) EjbCommon. getRemoteEJBHome(EjbCommon. S_EMPLOYEE_JNDI, SbnEmployeeHome.class); SbnEmployee objRemote = objHome.create(); //从上面的两行代码可以看出session bean编码的格式:首先得到home接口;然后调用create()函数得到接口 return objRemote.insert(model); } //关于错误处理:千万不要在catch里面什么都不做,要么把catch到的错误throw出去,要么显示一些信息出来;否则的话,程序将会无法调试! catch (NamingException e) { throw e; } catch (RemoteException e) { throw e; } catch (CreateException e) { throw e; } } /** * 根据传入的主键,删除数据库里面的一条记录。 * @param strPk * @return * @throws NamingException * @throws RemoteException * @throws CreateException */ public boolean delete(String strPk) throws NamingException, RemoteException, CreateException,RemoveException,FinderException { try { SbnEmployeeHome objHome = (SbnEmployeeHome) EjbCommon. getRemoteEJBHome(EjbCommon. S_EMPLOYEE_JNDI, SbnEmployeeHome.class); SbnEmployee objRemote = objHome.create(); boolean b = objRemote.del(strPk); return b; } //关于错误处理:必须这么一个一个地catch错误,然后throw出去! catch (NamingException e) { throw e; } catch (RemoteException e) { throw e; } catch (CreateException e) { throw e; } catch (RemoveException e) { throw e; } catch (FinderException e) { throw e; } } /** * 根据传入的model,更新数据库里面的一条记录 * @param model * @return * @throws NamingException * @throws RemoteException * @throws CreateException */ public EmployeeModel update(EmployeeModel model) throws NamingException, RemoteException, CreateException,FinderException { try { SbnEmployeeHome objHome = (SbnEmployeeHome) EjbCommon. getRemoteEJBHome(EjbCommon. S_EMPLOYEE_JNDI, SbnEmployeeHome.class); SbnEmployee objRemote = objHome.create(); return objRemote.update(model); } catch (NamingException e) { throw e; } catch (RemoteException e) { throw e; } catch (CreateException e) { throw e; } catch (FinderException e) { throw e; } } /** * 根据传入的主键,返回一个model * @param strPk * @return * @throws NamingException * @throws RemoteException * @throws CreateException */ public EmployeeModel findByPk(String strPk) throws NamingException, RemoteException, CreateException,FinderException { try { SbnEmployeeHome objHome = (SbnEmployeeHome) EjbCommon. getRemoteEJBHome(EjbCommon. S_EMPLOYEE_JNDI, SbnEmployeeHome.class); SbnEmployee objRemote = objHome.create(); return objRemote.findByPk(strPk ); } catch (NamingException e) { throw e; } catch (RemoteException e) { throw e; } catch (CreateException e) { throw e; } catch (FinderException e) { throw e; } } /** * 根据传入的sql(注意不是完整的sql语句),得到所有满足条件的model,放到一个ArrayList里面返回 * @param sql * @return * @throws NamingException * @throws RemoteException * @throws CreateException */ public ArrayList queryBySql(String sql) throws NamingException, RemoteException, CreateException,SQLException { try { SbnEmployeeHome objHome = (SbnEmployeeHome) EjbCommon. getRemoteEJBHome(EjbCommon. S_EMPLOYEE_JNDI, SbnEmployeeHome.class); SbnEmployee objRemote = objHome.create(); return objRemote.queryBySql(sql); } catch (NamingException e) { throw e; } catch (RemoteException e) { throw e; } catch (CreateException e) { throw e; } catch (SQLException e) { throw e; } } /** * 根据传入的主键数组,批量删除记录 * @param sId * @return * @throws NamingException * @throws RemoteException * @throws CreateException */ public boolean deleteBatch(String[] sId) throws NamingException, RemoteException, CreateException{ boolean b = false; try { SbnEmployeeHome objHome = (SbnEmployeeHome) EjbCommon. getRemoteEJBHome(EjbCommon. S_EMPLOYEE_JNDI, SbnEmployeeHome.class); SbnEmployee objRemote = objHome.create(); b = objRemote.delBatch(sId); } catch (NamingException e) { throw e; } catch (RemoteException e) { throw e; } catch (CreateException e) { throw e; } finally{ return b; } } public EmployeeAction() { } public static void main(String[] args) { EmployeeAction action = new EmployeeAction(); //以下是调试代码。注意:最好在EJB发布到weblogic之前,将session bean里面的所有方法调试一遍, //确保不会有比较低级的错误。否则,如果到了jsp页面再去调试,无疑是nightmare EmployeeModel data = new EmployeeModel(); //说明:1)要调试的话,只要将“测试xx方法”前面加上/就可以了。 // 2)有时候EJB运行比较慢,JBuilder里面半天没有反应。这是可以在前面的方法里面加一些 // 输出语句,让你知道程序是在正确运行。 //*测试add()方法 for (int i = 0; i < 6; i++) { data.setName("name" + i); data.setJob("job1"); data.setHireDate(java.sql.Date.valueOf( "2003-07-21") ); try { action.add(data); } catch (Exception e) { e.printStackTrace(); } } //**/ /*测试delete()方法 try { action.delete("ID_2003072504CB077B81059114950140"); //这个主键的值是都数据库里面找的。 } catch (Exception e) { e.printStackTrace(); } //*/ /*测试deleteBatch()方法 String[] strSID = { "ID_2003072504CB077B81059116383421", "ID_2003072504CB077B81059116474625", "ID_2003072504CB077B81059116477218" }; try { action.deleteBatch( strSID ); } catch ( Exception e ) { e.printStackTrace(); } //*/ /*测试findByPk()方法 String strPK = "ID_2003072504CB077B81059116477328"; try{ data = action.findByPk( strPK ); System.out.println("找到的name=" + data.getName()); } catch ( Exception e ) { e.printStackTrace(); } //*/ /*测试queryBySql()方法 String strSql = "job1='job1'"; ArrayList alRet = null; try{ alRet = action.queryBySql( strSql ); if ( alRet != null && alRet.size() > 0) { for ( int i = 0; i < alRet.size(); i ++ ){ data = ( EmployeeModel ) alRet.get( i ); System.out.println("找到符合条件的第" + (i+1) + "个记录,name=" + data.getName()); } }else{ System.out.println("没有找到记录"); } } catch ( Exception e ) { e.printStackTrace(); } //*/ /*调试update()函数 String strPK1 = "ID_2003072504CB077B81059118072859"; try{ data = action.findByPk( strPK1 ); System.out.println("找到的旧的name=" + data.getName()); data.setName( "new name" ); action.update( data ); } catch ( Exception e ) { e.printStackTrace(); } //*/ System.out.println("*********Final!"); } } 调试EJB:
调试方法是运行EmployeeAction。注意在运行之前,必须启动weblogic,并且保证EJB已经正确发布了。事实上,EJB的发布也要调试很长时间的。调试注意事项:
调试EJB是很麻烦的,而且非常耗费内存。如果内存不是512M以上,就等着痛苦降临吧:)我现在就是这样,简直有砸电脑的欲望。 有时候,所有的步骤都正确,但是总是有一些奇怪的错误。(比如我写这个例子的时候)这时,一般先shutdown weblogic,然后将weblogic目录下的所有临时目录(一般以TMP开头)全部删掉,然后重启一下weblogic。问题往往能够得到解决。不要问为什么,估计bea公司的人也不知道。 在JBuilder中,最好把EJB module的"Always creating JAR when building the project"去掉。免得每次都要重复编译ejb的.jar文件。 有时候编译出来的.jar文件很大(比如1M、2M;一般几十、几百KB是比较正常的),就要看EJB module的属性设置是否正确。主要是content是否包含所有的类,一般应该选择只包含用到的类。 用JBuilder发布的时候,有时候可能会碰到它提示“超过4分钟,时间超时,发布不成功”等等之类的提示。但是事实证明发布却是成功的,如果碰到这种情况,不理它就是了。 FAQ:
Q:得到这样的错误javax.naming.NameNotFoundException: Unable to resolve 'SbnEmployee' Resolved: '' Unresolved:'SbnEmployee' ; remaining name 'SbnEmployee'
A:没有正确发布EJB。请先启动weblogic,然后在JBuilder中右击ejb module,选择deploy。 Q:调试老通不过
A:重启weblogic,然后再试试吧。 Q:我改动了session bean,为什么没有效果?
A:修改EJB的任何一个部分,都要重新发布EJB才能生效。这个问题的症结很可能在这里。不过要记住,在JBuilder里面,此时要用Reploy这个选项,不要用Deploy。 Q:我在EJB里面System.out.println了一下,为什么看不到输出?
A:EJB的输出在weblogic里面。要注意的是,System.out.println的输出,有时候在JBuilder里面,有时候又在weblogic里面,有时候还可能到java的控制台里面(比如applet的输出,不过这是题外话了)。 Q:我的EJB写的都是正确的啊,为什么老是出现发布的错误?
A:试试:打开EJB module的属性,将“discriptors in module”里面的weblogic-ejb-jar.xml删除掉,然后重新发布。问题往往可能会在这里,特别是你用来调试的weblogic的版本变化的时候。
说明:这个条目可以放心删除,JBuilder在编译EJB的时候,会自动根据当前的设置加上这个条目。


本文地址:http://com.8s8s.com/it/it17530.htm