JBuilder9+Weblogic7实战篇
ENTITY BEAN的运用(一)
作者:黄 凯
E_mail:hk_sz@163.com
一、Entity Bean 的基础理论
1.1 什么是Entity Bean
Entity Bean(实体Bean)是持久数据组件,代表存储在外部介质中的持久(Persistence)对象或者已有的企业应用系统资源。简单地讲,一个Entity Bean可以代表数据库中的一行记录,多个客户端应用能够以共享方式访问表示该数据库记录的Entity Bean。
那么什么是持久数据组件呢?为什么要使用持久数据组件?理解了这两个问题,也就清楚了Entity Bean的性质及用途。
持久数据组件指的是这样一种对象,它们知道如何将自身放入持久存储的空间中。它们使用一些持久机制,比如序列化、O/R映射。这种对象代表数据,例如使用持久数据组件代表下面这些信息:
● 银行帐号信息,例如帐号、密码和余额;
● 员工信息,例如姓名、部门和工资。
为什么要把这些数据以对象的方式进行处理而不是直接处理数据库中的原始数据,比如相关的记录呢?答案是将数据视为对象是非常便利的,因为能够方便地操作和管理对象,并且它们表现为一个紧凑的形式,此外,通过组件所在的应用服务器,可以获得事务、安全性等服务。
Entity Bean就是这种持久数据组件。Entity Bean知道怎样在一个诸如数据库的存储空间中永久保存自己。Entity Bean以域(field)的方式存储数据,例如银行帐号、密码和余额。
依赖于EJB容器提供的事务服务,多个客户端应用能够在保持数据库记录的一致性和完整性前提下实现对数据资源的共享。Entity Bean的生命期相对较长并且其状态是持续的。只要Entity Bean代表的数据库记录存在,该组件对象实例就一直存在,即使EJB容器崩溃,Entity Bean仍然具有生命力。
1.2 Entity Bean的子类型
按照Entity Bean持久性的实现形式,可以将Entity Bean分为容器管理持久性(CMP Container-Managed Persistence)和组件管理持久性(BMP Bean-Managed Persistence)两种模型。在CMP类型EJB组件的实现代码中,组件开发人员不需要为组件的持久性控制方法编写任何数据库操作的代码,而是在组件组装和部署过程中由部署工具自动创建;如果要创建BMP类型EJB组件,则组件程序设计人员需要为所有持久性方法编写控制代码。
1.3 Entity Bean的特点
与数据库中的数据记录相对应,每个实体类型EJB组件包含一个主键(Primary Key)标识,该标识与组件代表的数据库记录主键相同。客户端应用可以利用该主键定位EJB容器中的Entity Bean对象实例,进而定位组件代表的数据库记录。
实体类型EJB组件的主要特点包括:
● Entity Bean提供数据库中记录的视图;
● Entity Bean具有无限制生命期,EJB服务器崩溃也不会影响Entity Bean的存在;
● 多个Entity Bean可以对应同一数据库记录;
● EJB服务器可以利用Entity Bean的passivate方法将Entity Bean缓存到临时存储空间中,同样可以利用activate方法将缓存的Entity Bean重新读入EJB容器并恢复组件对象实例;
● 客户端应用可以利用在Entity Bean的Home接口中定义的创建、删除和查询等方法对组件进行管理。
二、创建Entity Bean
2.1 准备
首先在Oracle9i数据库建立表student和locker,建表的SQL脚本如下:
★ student表的脚本:
create table student(stuid integer primary key,stuname varchar(50),lockerid integer);
insert into student(stuid,stuname,lockerid) values(1,'student1',1);
insert into student(stuid,stuname,lockerid) values(2,'student2',2);
insert into student(stuid,stuname,lockerid) values(3,'student3',3);
★ locker表的脚本:
create table locker(id integer primary key,lockername varchar(50));
insert into locker(id,lockername) values(1, 'locker1');
insert into locker(id,lockername) values(2, 'locker2');
insert into locker(id,lockername) values(3, 'locker3');
在此之前请参照《JBuilder9+Weblogic7实战篇之工具篇(JDBC 1)》配置好数据库的连接池和Tx数据源。
2.2 创建Entity Bean
2.2.1 启动Jbuilder9,新建一个工程cmpSample;
2.2.2 单击Enterprise子页;
2.2.3选择EJB Module然后单击OK,出现EJB Module窗口;
2.2.4在Name后输入Cmp;
2.2.5 将Version更改为EJB 2.0 compliant;
2.2.6 单击OK。 EJB 的设计在文档窗口中进行。
2.2.7 通过从数据库中引入模式(Schema)的方式建立与student表对应的Entity Bean。在文档窗口按鼠标右键,单击Import Schema From Database菜单项;
2.2.8 在“Database Schema Provider”界面中设置数据库连接信息。各项设置如下:
★ Driver: 在下拉列表中选择oracle.jdbc.driver.OracleDriver;
★ URL: jdbc:oracle:thin:@localhost:1521:kkdb
★ Username: TEST
★ Password: TEST
★ Database name: kkdb
★ JNDI name: jdbc/testTxDataSource
完成后可以在左侧“DataSources”窗口中看见数据库中所有表的视图。
2.2.9 在STUDENT上按右键,单击Create CMP 2.0 Entity Bean菜单项,建立与student表相对应的CMP。
2.2.10 设置Entity Bean的信息
在EJB Designer窗口中单击Student项,进行设置。
在这里,只需设置接口类型(Interfaces)为local/remote(表示同时生成两种接口),其他各项均使用默认值即可。各项含义如下:
● Bean name: Entity Bean的名字;
● Abstract schema name: 抽象模式名;
● Interfaces: 对外接口类型,选择local、remote或local/remote;
● Always wrap primary key: 是否总是保护主键;
● Class and packages按钮: 设置产生类名和包名
○ 单击某一属性,可以设置该属性的信息。例如设置属性的名称、数据类型、是否为主键、是否作为ejbCreate方法的参数等。这里我们默认值。
2.2.11 在工程窗口cmpSample.jpx/Cmp按右键,单击Make菜单项,生成Cmp.jar文件。
2.2.12 启动Weblogic Server。
2.2.13 工程窗口cmpSample.jpx/Cmp/Cmp.jar按右键,单击Deploy Options for Cmp.jar/Deploy菜单项进行部署。
三、Entity Bean的组成
Entity Bean是由Bean类和接口文件组成。接口文件包括对外和Home接口。对外接口有两种:远程接口(Remote Interface)和本地接口(Local Interface)。Home接口是与对外接口保持一致的,即每一种对外接口对应一种Home接口。结合刚才我们创建的Entity Bean(CMP类型)的实例讲解各个组成部分。
3.1 Bean类
与Session Bean一样,Bean类中封装业务逻辑。在Session Bean中通常封装的是操作,Entity Bean是代表数据的,所以Entity Bean应该封装的是数据(或对数据的存取操作)。以Student这个CMP为例,Bean类中除了几个EJB都要有控制EJB生命周期的方法(如ejbCreate()、ejbRemote()、ejbPostCreate())外,与具体应用相关的方法主要是一组get/set方法。每一对get/set方法对应于数据表中的一个字段,例如student表中有一个stuid字段,在Entity Bean中对应有一组方法setStuid()和getStuid()。
还有一点要注意的是CMP类型的Entity Bean,其Bean类是一个实现了EntityBean接口的抽象类。里面的方法不用开发人员自己编写,原因是CMP的持久性操作(例如对数据库字段的存取)是由容器实现的。如果开发BMP,那么Bean类就不是这种结构了,Bean类应该是实现EntityBean接口的具体类,而且要加入访问持久性数据的代码(例如JDBC代码)。
CMP student的Bean类的定义参见StudentBean.java。
3.2 本地接口(Local Interface)
本地接口是对外接口的一种,在Entity Bean中本地接口是比较常用的。因为在一个J2EE应用系统中,通常由Session Bean访问Entity Bean,对于运行于同一应用服务器中的EJB,使用本地化接口可以大大提高访问效率。该接口定义了EJB的业务方法。
CMP student的本地接口的定义参见Student.java。
3.3 远程接口(Remote Interface)
远程接口是EJB的对外接口,定义了EJB的业务方法,远程客户端程序对EJB的访问是通过该接口完成的。
CMP student的远程接口定义参见StudentRemote.java。
3.4 Home接口
Entity Bean的Home接口定义了Entity Bean的生成及查询操作。该接口必须定义的两个方法是create()方法和findByPrimaryKey()方法。Create()方法定义了生成Entity Bean的操作,findByPrimaryKey()方法定义了按照主键查询Entity Bean的操作。严格地讲,这些方法仅仅定义了这些操作的一种规则,例如生成Entity Bean时的参数个数、具体实现是由容器来完成的。
以student的Home接口为例,create()方法的定义如下:
public Student create(BigDecimal stuid) throws CreateException;
create()方法的参数是与student数据表的主键stuid对应的,因为调用create()方法会建立一个新的Entity Bean,相应要在数据库中建立与Entity Bean相对应的一条记录,记录的stuid字段是不可缺少的。所以create()方法其实定义了一种操作规则,即建立Entity Bean时必须含有数据表的主键对应的参数。
再看一下findByPrimaryKey()方法,该方法的定义如下:
public Student findByPrimaryKey(BigDecimal stuid) throws FinderException;
该方法定义的是按照主键查询Entity Bean的操作。如同数据库操作中有条件查询语句,Home接口中必须定义一个查询操作,按照主键做查询是最常用的一种查询方式。除了findByPrimaryKey()方法,EJB开发者还可以定义其他的查询方法,例如通过stuName进行查询,不过findByPrimaryKey()方法是必须定义的。
CMP student的本地Home接口参见StudentHome.java。
四、测试Entity Bean
4.1单击Enterprise子页,选择EJB Test Client然后单击OK,
4.2通过“EJB Test Client Wizard”建立测试用的客户端程序。采用默认设置即可。
4.3 将private Context getInitialContext()方法中的
String url = "t3://hostname:7001";
替换为:
String url = "t3://localhost:7001";
4.4 在public static void main(String[] args)方法中添加以下代码,完成查找stuid为1的Student Entity Bean,然后输出相应的stuid,stuName和Lockerid:
public static void main(String[] args)
{
StudentTestClient1 client = new StudentTestClient1();
client.findByPrimaryKey(new BigDecimal(1));
System.out.println("stuid = " + client.getStuid());
System.out.println("Stuname = " + client.getStuname());
System.out.println("Lockerid = " + client.getLockerid());
}
4.5 运行查看结果。
4.6 用以下语句替换public static void main(String[] args)方法中刚才添加的代码,完成新建一个Student Bean的操作。
public static void main(String[] args)
{
StudentTestClient1 client = new StudentTestClient1();
client.create(new BigDecimal(4));
client.setStuname("student4");
client.setLockerid(new BigDecimal(4));
}
4.7 运行查看结果。
附录
电子工业出版社 《J2EE应用开发(Jbuilder+Weblogic)》
我的文章首发牛耳论坛(www.newer.com.cn/bbs)和程序员论坛(www.csdn.net),欢迎转载,不过,请保留作者以及修订者的名字,谢谢。