免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1079 | 回复: 0
打印 上一主题 下一主题

EJB bmp实体bean [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-03-17 20:13 |只看该作者 |倒序浏览

EJB bmp-1
public interface javax.ejb.EnterpriseBean implements java.io.Serializable
{
}
EJB bmp-2
public interface javax.ejb.EntityBean implements javax.ejb.EnterpriseBean
{
    public void setEntityContext(javax.ejb.EntityContext);
    public void unsetEntityContext();
    public void ejbRemove();
    public void ejbActivate();
    public void ejbPassivate();
    public void ejbLoad();
    public void ejbStore();
}
EJB bmp-3
package examples;
import javax.ejb.*;
import java.rmi.RemoteException;
/**
* 这是AccountBean 的远程接口。
*
* 客户端跟Bean交互时操作这个接口。
* 容器将实现此接口;实现对象称作EJB对象,
* 它向实际的Bean委托调用。
*/
public interface Account extends EJBObject
{
    /**
     * 存款到账户中,数目为amt。
     */
    public void deposit(double amt) throws AccountException, RemoteException;
        
    /**
     * 从银行账户中取款,数目为amt 。
     * @throw AccountException 当amt小于可用余额时,抛掷异常。
     */
    public void withdraw(double amt) throws AccountException, RemoteException;
    // 实体Bean域的Getter/setter方法。
    public double getBalance() throws RemoteException;
    public String getOwnerName() throws RemoteException;
    public void setOwnerName(String name) throws RemoteException;
    public String getAccountID() throws RemoteException;
    public void setAccountID(String id) throws RemoteException;
}
EJB bmp-4
package examples;
import javax.ejb.*;
/**
* 这是AccountBean 的本地接口。
*
* 客户端跟Bean交互时操作这个接口。
* 容器将实现此接口;该实现对象称作本地对象,
* 它向实际的Bean委托调用。
*/
public interface AccountLocal extends EJBLocalObject
{
    /**
     * 存款到账户中,数目为amt。
     */
    public void deposit(double amt) throws AccountException;
        
    /**
     * 从银行账户中取款,数目为amt
     * @throw AccountException 当amt小于可用余额时,抛掷异常
     */
    public void withdraw(double amt) throws AccountException;
    // 实体Bean域的Getter/setter方法
    public double getBalance();
    public String getOwnerName();
    public void setOwnerName(String name);
    public String getAccountID();
    public void setAccountID(String id);
}
EJB bmp-5
package examples;
import javax.ejb.*;
import java.util.Collection;
import java.rmi.RemoteException;
/**
* 这是Account的Home接口。
* 该接口由EJB容器的工具来实现。
* 该实现对象称作Home 对象,它是EJB对象工厂。
*/
public interface AccountHome extends EJBHome
{
   /**
    * 在此Home接口内定义了一个单独的create()方法,
    * 它对应AccountBean 中的ejbCreate()方法。
    * 该方法创建了本地EJB对象。
    *
    * 注意本地Home接口返回一个本地接口,
    * 但Bean返回一个主键。
    *
    * 注意没有抛出RemoteExceptions异常,因为它是本地的。
    *
    * @param accountID account (unique)的编号。
    * @param ownerName 账户拥有人的名字。
    * @return 最新创建的本地对象。
    */
   Account create(String accountID, String ownerName) throws CreateException, RemoteException;
   /**
    * 通过主键(Account ID)查找Account。
    */
   public Account findByPrimaryKey(AccountPK key) throws FinderException, RemoteException;
   /**
    * 通过拥有者名字(假设名字惟一)查找Account 。
    */
   public Collection findByOwnerName(String name) throws FinderException, RemoteException;
   /**
    * 这个Home业务方法独立于任何特定的账户。
    * 它返回银行内所有账户的总额。
    */
   public double getTotalBankValue() throws AccountException, RemoteException;
}
EJB bmp-6
package examples;
import javax.ejb.*;
import java.util.Collection;
/**
* 这是Account的本地Home接口。
* 该接口由EJB容器的工具实现。
* 实现对象称做本地Home对象,它是一个本地EJB对象工厂。
*/
public interface AccountLocalHome extends EJBLocalHome
{
   /**
    * 在这个Home接口定义了一个单独的create()方法,
    * 它对应AccountBean中的ejbCreate()方法。
    * 这个方法创建一个本地EJB对象。
    *
    * 注意本地Home接口返回一个本地接口,
    * 而Bean类返回一个主键。
    *
    * 注意没有抛出RemoteExceptions异常,因为我们是本地的而非远程。
    *
    * @param accountID account (unique)的编号。
    * @param ownerName 账户拥有者的名字。
    * @return 最新创建的本地对象。
    */
   AccountLocal create(String accountID, String ownerName) throws CreateException;
   /**
    * 通过主键(Account ID)查找一个Account。
    */
   public AccountLocal findByPrimaryKey(AccountPK key) throws FinderException;
   /**
    * 通过自身的名字(假定名字惟一)查找一个Account。
    */
   public Collection findByOwnerName(String name) throws FinderException;
   /**
    * Home业务方法独立于任何特定的账户实例。
    * 它返回银行内所有银行账户的总额。
    */
   public double getTotalBankValue() throws AccountException;
}
EJB bmp-7
package examples;
import java.io.Serializable;
/**
* Account的主键类
*/
public class AccountPK implements java.io.Serializable
{
  public String accountID;
  public AccountPK(String id)
{
    this.accountID = id;
  }
  public AccountPK()
{
  }
  public String toString()
{
    return accountID;
  }
  public int hashCode()
{
      return accountID.hashCode();
  }
  
  public boolean equals(Object account)
{
      return ((AccountPK)account).accountID.equals(accountID);
  }  
}
EJB bmp-8
package examples;
import java.sql.*;
import javax.naming.*;
import javax.ejb.*;
import java.util.*;
import java.rmi.RemoteException;
/**
* 示范Bean管理的持久化实体Bean。
* 这个实体Bean代表一个银行账户。
*/
public class AccountBean implements EntityBean
{
    protected EntityContext ctx;
    // Bean管理的状态域。
    private String accountID;    // 主键类
    private String ownerName;
    private double balance;
    public AccountBean()
{
        System.out.println("New Bank Account Entity Bean Java Object created by EJB Container.");
    }
    ... 方法继续 ...
EJB bmp-9
... 继续 ...
    // 业务逻辑方法。
    /**
     * 存款到账户,数目为amt 。
     */
    public void deposit(double amt) throws AccountException
{
        System.out.println("deposit(" + amt + ") called.");
        balance += amt;
    }
    /**
     * 从银行账户取款,数目为amt。
     * @throw AccountException 当amt小于可用的余额时抛出。
     */
    public void withdraw(double amt) throws AccountException
{
        System.out.println("withdraw(" + amt + ") called.");
        if (amt > balanc) {
            throw new AccountException("Your balance is " + balance + "!  You cannot withdraw " + amt + "!");
        }
        balance -= amt;
    }
    // 实体Bean域的Getter/setter方法。
    public double getBalance() {
        System.out.println("getBalance() called.");
        return balance;
    }
    public void setOwnerName(String name) {
        System.out.println("setOwnerName() called.");
        ownerName = name;
    }
    public String getOwnerName() {
        System.out.println("getOwnerName() called.");
        return ownerName;
    }
    public String getAccountID() {
        System.out.println("getAccountID() called.");
        return accountID;
    }
    public void setAccountID(String id)
{
        System.out.println("setAccountID() called.");
        this.accountID = id;
    }
    /**
     * Home逻辑方法是跟特定账户实例无关的。
     * 它返回所有银行账户的总额。
     */
    public double ejbHomeGetTotalBankValue() throws AccountException
{
        PreparedStatement pstmt = null;
        Connection conn = null;
        try {
            System.out.println("ejbHomeGetTotalBankValue()");
            /*
             * 获得数据库连接。
             */
            conn = getConnection();
            /*
             * 得到所有账号的总额。
             */
            pstmt = conn.prepareStatement("select sum(balance) as total from accounts");
            ResultSet rs = pstmt.executeQuery();
            /*
             * 返回总和。
             */
            if (rs.next()) {
                return rs.getDouble("total");
            }
        }
        catch (Exception e) {
          e.printStackTrace();
          throw new AccountException(e);
        }
        finally {
            /*
             * 释放数据库连接给其他的Bean。
             */
            try { if (pstmt != null) pstmt.close(); }
            catch (Exception e) {}
            try { if (conn != null) conn.close(); }
            catch (Exception e) {}
        }
        throw new AccountException("Error!");
    }
    /**
     * 从连接池获取JDBC连接。
     *
     * @return The JDBC connection
     */
    public Connection getConnection() throws Exception
{
        try {
            Context ctx = new InitialContext();
            javax.sql.DataSource ds = (javax.sql.DataSource) ctx.lookup("java:comp/env/jdbc/ ejbPool");
            return ds.getConnection();
        }
        catch (Exception e) {
            System.err.println("Could not locate datasource!  Reason:");
            e.printStackTrace();
            throw e;
        }
    }
}
EJB bmp-10
    ... 继续 ...
    //
    // EJB要求的方法。
    //
    /**
     * 被容器调用。执行能够获得所需的资源。
     */
    public void ejbActivate()
{
        System.out.println("ejbActivate() called.");
    }
    /**
     * 从数据库中删除实体Bean数据。
     * 相应地,客户端调用Home.remove()。
     */
    public void ejbRemove()
{
        System.out.println("ejbRemove() called.");
        /*
         * 记住一个实体Bean类能够用来代表不同的
         * 数据实例。所以,这个方法怎样晓得数据库内
* 哪一个实例将被删除?
         *
         * 回答是调用实体上下文对象来查询容器。
         * 通过从实体上下文获得主键,我们就能
         * 知晓是按照主键索引的哪一个数据实例
* 应该从数据库中删除。
         */
        AccountPK pk = (AccountPK) ctx.getPrimaryKey();
        String id = pk.accountID;
        PreparedStatement pstmt = null;
        Connection conn = null;
        try
{
            /*
             * 1) 获得一个新的JDBC连接。
             */
            conn = getConnection();
            /*
             * 2) 从数据库中删除账户。
             */
            pstmt = conn.prepareStatement("delete from accounts where id = ?");
            pstmt.setString(1, id);
            /*
             * 3) 严重的问题发生时,抛掷一个系统级的异常。
             */
            if (pstmt.executeUpdate() == 0) {
                throw new RemoteException("Account " + pk + " failed to be removed from the database");
            }
        }
        catch (Exception ex) {
            throw new EJBException(ex.toString());
        }
        finally {
            /*
             * 4) 释放数据库连接。
             */
            try { if (pstmt != null) pstmt.close(); }
            catch (Exception e) {}
            try { if (conn != null) conn.close(); }
            catch (Exception e) {}
        }
    }
    /**
     * 被容器调用。释放为钝化而保持的资源。
     */
    public void ejbPassivate()
{
        System.out.println("ejbPassivate () called.");
    }
    /**
     * 被容器调用。更新内存中的实体Bean对象
* 以反射储存在数据库内的当前值。
     */
    public void ejbLoad()
{
        System.out.println("ejbLoad() called.");
        /*
         * 再次查询实体上下文以获得当前主键,
* 这样我们能知晓加载了哪一个实例。
         */
        AccountPK pk = (AccountPK) ctx.getPrimaryKey();
        String id = pk.accountID;
        PreparedStatement pstmt = null;
        Connection conn = null;
        try {
            /*
             * 1) 获取一个新的数据库连接。
             */
            conn = getConnection();
            /*
             * 2) 根据accountID从数据库内获得账号。
             */
            pstmt = conn.prepareStatement("select ownerName, balance from accounts where id = ?");
            pstmt.setString(1, id);
            ResultSet rs = pstmt.executeQuery();
            rs.next();
            ownerName = rs.getString("ownerName");
            balance = rs.getDouble("balance");
        }
        catch (Exception ex) {
            throw new EJBException("Account " + pk + " failed to load from database", ex);
        }
        finally {
            /*
             * 3) 释放数据库连接。
             */
            try { if (pstmt != null) pstmt.close(); }
            catch (Exception e) {}
            try { if (conn != null) conn.close(); }
            catch (Exception e) {}
        }
    }
    /**
     * 从容器调用。更新数据库以反射内存中的
     *实体Bean实例的当前值。
     */
    public void ejbStore()
{
        System.out.println("ejbStore() called.");
        PreparedStatement pstmt = null;
        Connection conn = null;
        try {
            /*
             * 1) 获得一个新的数据库连接。
             */
            conn = getConnection();
            /*
             * 2) 存储账号到数据库内。
             */
            pstmt = conn.prepareStatement("update accounts set ownerName = ?, balance = ? where id = ?");
            pstmt.setString(1, ownerName);
            pstmt.setDouble(2, balance);
            pstmt.setString(3, accountID);
            pstmt.executeUpdate();
        }
        catch (Exception ex) {
            throw new EJBException("Account " + accountID + " failed to save to database", ex);
        }
        finally {
            /*
             * 3) 释放数据库连接。
             */
            try { if (pstmt != null) pstmt.close(); }
            catch (Exception e) {}
            try { if (conn != null) conn.close(); }
            catch (Exception e) {}
        }
    }
    /**
     * 被容器调用。将此Bean跟一个特定的上下文关联起来。
     * 我们能够查询Bean的定制属性。
     */
    public void setEntityContext(EntityContext ctx)
{
        System.out.println("setEntityContext called");
        this.ctx = ctx;
            }
    /**
     * 被容器调用。断开Bean实例跟一个特定的上下文环境
     * 的联系。
     */
    public void unsetEntityContext()
{
        System.out.println("unsetEntityContext called");
        this.ctx = null;
}
    /**
     * 在执行ejbCreate()之后调用。现在,Bean能够从上下文
     * 获得它的EJBObject,并传递它作为一个“this”参数。
     */
    public void ejbPostCreate(String accountID, String ownerName) { }
    /**
     * 这是对应Home接口中create()方法的初始化方法。
     *
     * 当客户端调用Home对象的create()方法时,
     * Home对象随之调用这个ejbCreate()方法。
     *
     * @return 账户的主键。
     */
    public AccountPK ejbCreate(String accountID, String ownerName)
throws CreateException
{
        PreparedStatement pstmt = null;
        Connection conn = null;
        try {
            System.out.println("ejbCreate() called.");
            this.accountID = accountID;
            this.ownerName = ownerName;
            this.balance = 0;
            /*
             * 获得数据库连接。
             */
            conn = getConnection();
            /*
             * 插入账户到数据库。
             */
            pstmt = conn.prepareStatement("insert into accounts (id, ownerName, balance) values (?, ?, ?)");
            pstmt.setString(1, accountID);
            pstmt.setString(2, ownerName);
            pstmt.setDouble(3, balance);
            pstmt.executeUpdate();
            /*
             * 生成主键并返回。
             */
            return new AccountPK(accountID);
        }
        catch (Exception e) {
            throw new CreateException(e.toString());
        }
        finally {
            /*
             * 为别的Bean释放数据库连接。
             */
            try { if (pstmt != null) pstmt.close(); }
            catch (Exception e) {}
            try { if (conn != null) conn.close(); }
            catch (Exception e) {}
        }
    }
    /**
     * 通过主键查找账户。
     */
    public AccountPK ejbFindByPrimaryKey(AccountPK key) throws FinderException
{
        PreparedStatement pstmt = null;
        Connection conn = null;
        try {
            System.out.println("ejbFindByPrimaryKey(" + key + ") called");
            /*
             * 获得数据库连接
             */
            conn = getConnection();
            /*
             * 在数据库内查找实体
             */
            pstmt = conn.prepareStatement("select id from accounts where id = ?");
            pstmt.setString(1, key.toString());
            ResultSet rs = pstmt.executeQuery();
            rs.next();
            /*
             * 没有错误发生,因此返回主键
             */
            return key;
        }
        catch (Exception e) {
            throw new FinderException(e.toString());
        }
        finally {
            /*
             * 释放数据库连接供别的Bean使用。
             */
            try { if (pstmt != null) pstmt.close(); }
            catch (Exception e) {}
            try { if (conn != null) conn.close(); }
            catch (Exception e) {}
        }
    }
    /**
     * 通过名字查找账户。
     */
    public Collection ejbFindByOwnerName(String name) throws FinderException
{
        PreparedStatement pstmt = null;
        Connection conn = null;
        Vector v = new Vector();
        try {
            System.out.println("ejbFindByOwnerName(" + name + ") called");
            /*
             * 或别的数据库连接。
             */
            conn = getConnection();
            /*
             * 查找数据库内的主键。
             */
            pstmt = conn.prepareStatement("select id from accounts where ownerName = ?");
            pstmt.setString(1, name);
            ResultSet rs = pstmt.executeQuery();
            /*
             * 插入每个找到的主键到一个vector中
             */
            while (rs.next()) {
                String id = rs.getString("id");
                v.addElement(new AccountPK(id));
            }
            /*
             * 返回主键的vector
             */
            return v;
        }
        catch (Exception e) {
            throw new FinderException(e.toString());
        }
        finally {
            /*
             * 释放数据库连接给别的Bean
             */
            try { if (pstmt != null) pstmt.close(); }
            catch (Exception e) {}
            try { if (conn != null) conn.close(); }
            catch (Exception e) {}
        }
    }
}
EJB bmp-11
package examples;
/**
* Accounts所抛掷的异常。
*/
public class AccountException extends Exception
{
    public AccountException()
{
        super();
    }
    public AccountException(Exception e)
{
        super(e.toString());
    }
    public AccountException(String s)
{
        super(s);
    }
}
EJB bmp-12
package examples;
import javax.ejb.*;
import javax.naming.*;
import java.rmi.*;
import javax.rmi.*;
import java.util.*;
/**
* 示例客户端代码,它操纵一个银行账户实体Bean。
*/
public class AccountClient
{
    public static void main(String[] args) throws Exception
{
        Account account = null;
        try {
            /*
             * 获得账户Home对象的引用。
             * ——账户EJB对象工厂。
                         */
            Context ctx = new InitialContext(System.getProperties());
            
            Object obj = ctx.lookup("AccountHome");
            AccountHome Home = (AccountHome) javax.rmi.PortableRemoteObject.narrow(obj, AccountHome.class);
            System.err.println("Total of all accounts in bank initially = " + Home.getTotalBank-Value());
            /*
             * 使用工厂创建账户EJB对象。
             */
            Home.create("123-456-7890", "John Smith");
            /*
             * 查找一个账户。
             */
            Iterator i = Home.findByOwnerName("John Smith").iterator();
            if (i.hasNext()) {
                account = (Account) i.next();
            }
            else {
                throw new Exception("Could not find account");
            }
            /*
             * 调用balance()方法并输出结果。
             */
            System.out.println("Initial Balance = " + account.getBalance());
            /*
             * 将$100存入账户。
             */
            account.deposit(100);
            /*
             * 随后取出余额。
             */
            System.out.println("After depositing 100, account balance = " + account.getBalance());
            System.out.println("Total of all accounts in bank now = " + Home.getTotalBankValue());
            /*
             * 从EJB对象获得主键。
             */
            AccountPK pk = (AccountPK) account.getPrimaryKey();
            /*
             * 释放旧的EJB对象引用。再次调用find(),
             * 这次根据账户ID(比如主键)进行查询。
             */
            account = null;
            account = Home.findByPrimaryKey(pk);
            /*
             * 输出当前的余额。
             */
            System.out.println("Found account with ID " + pk + ".  Balance = " + account.getBalance());
            /*
             * 试图取出$150。
             */
            System.out.println("Now trying to withdraw $150, which is more than is currently available.  This should generate an exception..");
            account.withdraw(150);
        }
        catch (Exception e) {
            System.out.println("Caught exception!");
            e.printStackTrace();
        }
        finally {
            /*
             * 永久地销毁实体。
             */
            try
{
                System.out.println("Destroying account..");
                if (account != null)
{
                    account.remove();
                }
            }
            catch (Exception e)
{
                e.printStackTrace();
            }
        }
    }
}
EJB bmp-13

  
   Account
   examples.AccountHome
   examples.Account
   examples.AccountLocalHome
   examples.AccountLocal
   examples.AccountBean
   Bean
   examples.AccountPK
   False
   
    jdbc/ejbPool
    javax.sql.DataSource
    Container
   
  

   

  
   
    Account
    Local
    *
   
   
    Account
    Remote
    *
   
   Required
  

               
               
               

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/16182/showart_260637.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP