EJB tutorial (推荐)

我直接粘贴过来的,不知道格式有没有变坏,如果看起来不整齐,可以到 我的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关联 

  1. 预备:编码基本pattern:
    包名全部用小写字母,如ejbsample.session
    类名用大小写结合的方法,且首字母大写,如EmployeeAction
    变量名用大小写结合的方法,且首字母小写,如strName
    模块级变量前面加上下划线,如_strName
  2. 数据库的设置:
    安装好Oracle的客户端,保证与数据库服务器正确建立了连接。
  3. JBuilder9的设置:
    可以参考以前的文章。要点:oracle的库文件设定好;"Enterprise setup"设定好
  4. WebLogic的设置:
    1. 启动Weblogic
    2. 打开控制台: http://localhost:7001/console
    3. 从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"里面去)
    4. 配置一个"Tx Data Sources":
      **Name:
      ejbDS
      **JNDI Name:
      ejbDS
      (说明:这就是在EJB设计的时候,要指定的数据源名称)
      **Pool Name:
      ejbDemo
      (说明:这就是前面建立的connection pool的名称)
  5. 在JBuilder中建立"EJB module":
    建议将.jar文件的保存位置可以放到weblogic的applications目录下:C:/bea/wlserver6.1/config/mydomain/applications
    1. 建好一个空的module之后,首先配置它的"DataSources"。右击"DataSources",选择"Import Schema from Database"。
    2. 首先选择"Driver"为"oracle.jdbc.driver.OracleDriver",然后URL填入"jdbc:oracle:thin:@172.16.3.100:1521:dev3","Username"和"Password"填入正确的(我这里分别填入"pm"、"pm"),"JNDI name"填入前面设定的"ejbDS".
    3. ok之后,JBuilder就自动开始从数据库里面"Importing Schema"。如果没有出现这样的动作,就说明以前数据库的配置没有正确,再检查一遍。
  6. 在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类后面马上建立)
    
  7. 在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页面打交道的时候,它要发挥重要作用。)
    
  8. 下面就开始建立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();
        }
    }
    
  9. 写一个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(); } }
  10. 编辑完成实体bean
    1. 打开EbnEmployee、EbnEmployeeHome、EbnEmployeeBean,首先import一下:
      import ejbsample.employee.EmployeeModel;
    2. 然后开始编辑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;
            }
        
  11. 编辑完成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出去!!!
            }
        }
    }
    
  12. 编制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!");
        }
    }
    
  13. 调试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分钟,时间超时,发布不成功”等等之类的提示。但是事实证明发布却是成功的,如果碰到这种情况,不理它就是了。
  14. FAQ:
    1. Q:得到这样的错误javax.naming.NameNotFoundException: Unable to resolve 'SbnEmployee' Resolved: '' Unresolved:'SbnEmployee' ; remaining name 'SbnEmployee'
      A:没有正确发布EJB。请先启动weblogic,然后在JBuilder中右击ejb module,选择deploy。
    2. Q:调试老通不过
      A:重启weblogic,然后再试试吧。
    3. Q:我改动了session bean,为什么没有效果?
      A:修改EJB的任何一个部分,都要重新发布EJB才能生效。这个问题的症结很可能在这里。不过要记住,在JBuilder里面,此时要用Reploy这个选项,不要用Deploy。
    4. Q:我在EJB里面System.out.println了一下,为什么看不到输出?
      A:EJB的输出在weblogic里面。要注意的是,System.out.println的输出,有时候在JBuilder里面,有时候又在weblogic里面,有时候还可能到java的控制台里面(比如applet的输出,不过这是题外话了)。
    5. Q:我的EJB写的都是正确的啊,为什么老是出现发布的错误?
      A:试试:打开EJB module的属性,将“discriptors in module”里面的weblogic-ejb-jar.xml删除掉,然后重新发布。问题往往可能会在这里,特别是你用来调试的weblogic的版本变化的时候。
      说明:这个条目可以放心删除,JBuilder在编译EJB的时候,会自动根据当前的设置加上这个条目。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值