开发环境:JDeveloper 11.1.2.1.0。
完成《Build a Web Application with JDeveloper 11g Using EJB, JPA, and JavaServer Faces》。
学习要点:
1. 从数据库表创建JPA Entities,生成相应的java文件,主要包括Entities的属性和CRUD方法。
以后可以根据需要,手工添加一些方法。
关于JPA的详细信息,可以参考《JPA是个啥东东?》。



2. 创建EJB Session Bean,选择Persistence Type=JPA,选择暴露哪些Entities上的方法。
Entity如果增加了新的方法想要通过Session Bean 调用,右键点击EJB Session Bean,选择Edit Session Facade,把新方法加进来即可,然后重新生成Data Control。
创建SessionFacade Bean用来访问EJB或Entities的,其它Java Client不能直接访问Entities,而只能通过SessionFacade Bean,这是一种很好的设计模式。
这样设计的好处是:
(1)“面向接口”设计。
Client端无需依赖业务对象(其它EJB或Entities)的实现,即使接口改变,也可以做到Client不变,修改SessionFacade Bean相对来说比修改Client要容易很多。
(2)减少远程通信。
因为其它EJB或Entities都是部署在Server端的,如果Client端直接访问EJB或Entities,将会有大量的远程通讯,网络负担很重。
而SessionFacade Bean也是部署在Server端的,这样就避免了不必要的网络传输,当然这里有一个粒度设计的问题。
关于SessionFacade设计模式,请参考《门面模式 Facade》。
指定SessionFacade Bean要实现的接口:
(1)Remote Interface:客户端程序与SessionFacade Bean运行在不同的JVM中,比如Java Standalone Client。
(2)Local Interface:客户端程序与SessionFacade Bean运行在同一个的JVM中,比如Web Client。
3. 右键SessionFacade Bean,生成Data Control
这时,所有暴露在Local Interface的方法,将会出现在Data Control中。
4. 测试Session Bean
测试Session Bean非常简单 ,右键点击EJB Session Bean,选择New Sample Java Client,就会帮你生成测试代码,你只需要传一些必要的参数即可。
测试前,先要运行Session Bean(把Session Bean 发布到WLS上,并启动),然后右键点击Java Client,选择Run。

5. 在Java EE Container外部创建JPA Entities
JPA Entities 也可以不在Java EE Container中运行,在Java SE Container中也可以调用。
你需要创建一个新的persistence unit,右键点击persistence.xml选择New Java Service Facade,选择Persistence Type=JPA,选择暴露哪些Entities上的方法。
右键persistence.xml,创建Client。
在main函数中,可以增加你的测试代码,并直接运行——不需要先运行Session Bean。

6. 创建页面时,拖放persist方法提交数据
这里有两个提交数据库方法:persist和merge。
注意,persist实际上做的操作是Insert,因此只能用于新建一个对象,然后调用persist提交。
如果主键重复,会报错。
而merge会检查主键是否存在,如果存在,执行Update操作;否则执行Insert操作,然后提交。
参数设置如下:
7. 创建Taskflow时,使用PageflowScope在两个页面之间传递数据
Find按钮上使用Set Action Listener传递参数。
其中,From参数来自bindings中的参数;To参数指定到pageFlowScope.sal中。
注意,To参数可以直接这样写,无需提前在其它地方定义,即表明在PageFlowScope中有一个变量sal。

这是一个非常典型的在两个页面之间传递参数的方式:
(1)首先有一个带返回值和输入参数的方法:比如List
(2)在Data Control 中拖放该方法名称到第1个页面,生成查询表单。
(3)在查询按钮上,增加SetPropertyListener,把参数传递到PageFlowScope中。
(4)在Data Control中拖放该方法的返回值名称到第2个页面,生成查询结构列表。
因为该方法有输入参数,所以拖放时会提示你定义输入参数来自哪里,这里设置成pageFlowScope.sal。
即在第1个页面中保存的PageFlowScope变量sal。
参考文献:
1. http://blogs.oracle.com/adf/entry/difference_between_ejb_persist_merge_operation
2. http://blogs.oracle.com/shay/entry/insert_update_for_jpaejb_30_wi
Project 下载:HR_EJB_JPA.7z。
没有评论:
发表评论