2009年2月23日星期一

Form开发中常用触发器功能在ADF中的对应实现方法

本文主要描述Form开发中常用触发器功能在ADF中的对应实现方法。

一、验证和默认值

1WHEN-VALIDATE-RECORD

EO的实现类EntityImpl中,添加返回值为boolean类型的public方法,一般名为validateXXX()

如果验证成功,返回true,如果验证失败,则返回false。添加该方法到EO上的实体级验证。并可以

根据需要添加必要的错误提示消息。

2WHEN-VALIDATE-ITEM

EO的实现类EntityImpl中,添加返回值为boolean类型的public方法,一般名为validateXXX()

接收一个类型与要验证属性类型相同的参数。如果验证成功,返回true,如果验证失败,则返回

false。添加该方法到EO的属性级。并可以根据需要添加必要的错误提示消息。

3WHEN-DATEBASE-RECORD

重写EOaddToTransactionManager()方法,添加必要的代码在调用super之后。

4WHEN-CREATE-RECORD

(1)重写EOcreate()方法,在调用super之后使用,根据实际情况使用setAttrName()方法,为必要

的属性设置默认值。

(2)为使用数据库sequence的主键设置sequence值,使用SequenceImpl帮助类调用getSequenceNumber()

方法得到sequence的下一个值,并设置该值到主键属性上。

(3)如果要在一条新记录被保存到数据库时才设置其sequence值,而不使用数据库触发器,则需要重写

EO的实现类中的prepareDML()方法。

(4)如果要使用数据库中的BEFOREINSERTFOREACHROW触发器,则设置该主键属性的数据类型为DBSequence

而非常规的Number类型。

5WHEN-REMOVE-RECORD

重写EOremove()方法,在调用super之前或者之后添加必要的代码。

二、查询

1PRE-QUERY

重写VO实现类中的executeQueryForCollection()方法,在调用super前添加必要的代码。

2ON-COUNT

重写VO实现类中的getQueryHintCount()方法,添加自己的代码,而不调用super

3POST-QUERY

一般情况下,在ADF中很少使用类似于POST-QUERY触发器的功能,即根据当前行的外键关系取其他表中的字段

值,ADF如果需要使用到类似的功能,通常会建立基于多个EOVO。不过,如果要实现类似于POST-QUERY触发器

的功能,也可以通过重写VO实现类中的createInstanceFromResultSet()方法。

4ON-LOCK

重写EO实现类中的lock()方法,添加自己的代码,而不调用super

三、数据库连接

1POST-LOGON

重写客户化的AM实现类中的afterConnect()方法,但是如果想要在AM被不同的用户访问时添加逻辑,可以通过

重写AM中的prepareSession()方法。

2PRE-LOGOUT

重写客户化的AM实现类中的beforeDisconnect()方法。

四、事务“POST”

1PRE-COMMIT

在客户化的DBTransactionImpl类中,重写commit()方法,添加必要的代码在调用super之前。

2PRE-INSERT

重写EO中的doDML()方法,如果operation等于DML_INSERT时,添加必要的代码在调用super之前。

3ON-INSERT

重写EO中的doDML()方法,如果operation等于DML_INSERT时,添加必要的代码,而不调用super

4POST-INSERT

重写EO中的doDML()方法,如果operation等于DML_INSERT时,添加必要的代码在调用super之后。

5PRE-DELETE

重写EO中的doDML()方法,如果operation等于DML_DELETE时,添加必要的代码在调用super之前。

6ON-DELETE

重写EO中的doDML()方法,如果operation等于DML_DELETE时,添加必要的代码,而不调用super

7POST-DELETE

重写EO中的doDML()方法,如果operation等于DML_DELETE时,添加必要的代码在调用super之后。

8PRE-UPDATE

重写EO中的doDML()方法,如果operation等于DML_UPDATE时,添加必要的代码在调用super之前。

9ON-UPDATE

重写EO中的doDML()方法,如果operation等于DML_UPDATE时,添加必要的代码,而不调用super

10POST-UPDATE

重写EO中的doDML()方法,如果operation等于DML_UPDATE时,添加必要的代码在调用super之后。

11POST-FORMS-COMMIT

(1)如果需要添加对于整个事务的一段代码,可以重写客户化的DBTransactionImpl类中的doCommit()方法,在

调用super之前添加适当的代码。

(2)如果需要对于事务中的Entity添加适当的处理代码,可以重写EO中的beforeCommit()方法,在其中添加适当

的代码。

12POST-DATEBASE-COMMIT

在客户化的DBTransactionImpl类中重写commit()方法,添加必要的代码在调用super之后。

五、错误处理

1ON-ERROR

使用客户化的Error HandlerADF BindingContext中。

2009年2月19日星期四

基于视图EO的增删改

概述

在使用Form进行EBS二次开发的过程中,经常会创建基于View(视图)的数据块,而在ADF中可以创建和应用基于ViewEntity Object。对于该EO,可以通过添加和更改必要的代码,从而调用数据库中的PL/SQL程序包,完成相应EO的插入、更新、删除等操作。本技巧主要介绍了如何基于View创建EO,并为该EO添加插入、更新和删除操作。

下面我们以基于countries_regions_v视图的EO为例,为该EO添加增、删、改操作。

实现

1创建Countries_Regions_v视图,代码如下:

CREATE OR REPLACE VIEW COUNTRIES_REGIONS_V AS

SELECT C.COUNTRY_ID, C.COUNTRY_NAME, R.REGION_ID, R.REGION_NAME

FROM COUNTRIES C, REGIONS R

WHERE C.REGION_ID = R.REGION_ID;

2编写PL/SQL程序包COUNTRIES_REGIONS_PKG,包含insert_rowupdate_rowdelete_row分别完成增、改、删操作,代码如下:

声明部分:

CREATE OR REPLACE PACKAGE COUNTRIES_REGIONS_PKG IS

-- Author : Eleven.Xu

-- Created : 2009-1-12 17:33:16

-- Purpose : Howto_基于ViewEO的增删改

PROCEDURE INSERT_ROW(P_COUNTRY_ID VARCHAR2,

P_COUNTRY_NAME VARCHAR2,

P_REGION_ID NUMBER,

P_REGION_NAME VARCHAR2);

PROCEDURE UPDATE_ROW(P_COUNTRY_ID VARCHAR2,

P_COUNTRY_NAME VARCHAR2,

P_REGION_ID NUMBER,

P_REGION_NAME VARCHAR2);

PROCEDURE DELETE_ROW(P_COUNTRY_ID VARCHAR2);

END COUNTRIES_REGIONS_PKG;

主体部分:

CREATE OR REPLACE PACKAGE BODY COUNTRIES_REGIONS_PKG IS

PROCEDURE INSERT_ROW(P_COUNTRY_ID VARCHAR2,

P_COUNTRY_NAME VARCHAR2,

P_REGION_ID NUMBER,

P_REGION_NAME VARCHAR2) IS

BEGIN

INSERT INTO REGIONS

(REGION_ID, REGION_NAME)

VALUES

(P_REGION_ID, P_REGION_NAME);

INSERT INTO COUNTRIES

(COUNTRY_ID, COUNTRY_NAME, REGION_ID)

VALUES

(P_COUNTRY_ID, P_COUNTRY_NAME, P_REGION_ID);

END INSERT_ROW;

PROCEDURE UPDATE_ROW(P_COUNTRY_ID VARCHAR2,

P_COUNTRY_NAME VARCHAR2,

P_REGION_ID NUMBER,

P_REGION_NAME VARCHAR2) IS

BEGIN

UPDATE REGIONS R

SET R.REGION_NAME = P_REGION_NAME

WHERE R.REGION_ID = P_REGION_ID;

UPDATE COUNTRIES C

SET C.COUNTRY_NAME = P_COUNTRY_NAME

WHERE C.COUNTRY_ID = P_COUNTRY_ID;

END UPDATE_ROW;

PROCEDURE DELETE_ROW(P_COUNTRY_ID VARCHAR2) IS

T_REGION_ID NUMBER;

BEGIN

SELECT C.REGION_ID

INTO T_REGION_ID

FROM COUNTRIES C

WHERE C.COUNTRY_ID = P_COUNTRY_ID;

DELETE FROM COUNTRIES C WHERE C.COUNTRY_ID = P_COUNTRY_ID;

DELETE FROM REGIONS R WHERE R.REGION_ID = T_REGION_ID;

END;

END COUNTRIES_REGIONS_PKG;

3、新建EO,基于视图Countries_Regions_v,名为CountriesRegionsEO,设置CountryId为主键,并设置四个属性的updatable属性分别为:

CountryId

While New

CountryName

Always

RegionId

While New

Region Name

Always

4、新建类,名为PLSQLEntityImpl.java,继承于EntityImpl类,重写方法doDML,并分别添加callInsertProcedurecallUpdateProcedurecallDeleteProcedure方法。

@Override

protected void doDML(int operation, TransactionEvent transactionEvent) {

//super.doDML(operation, transactionEvent);

if (operation == DML_INSERT)

callInsertProcedure(transactionEvent);

else if (operation == DML_UPDATE)

callUpdateProcedure(transactionEvent);

else if (operation == DML_DELETE)

callDeleteProcedure(transactionEvent);

}

/* Override in a subclass to perform non-default processing */

protected void callInsertProcedure(TransactionEvent e) {

super.doDML(DML_INSERT, e);

}

/* Override in a subclass to perform non-default processing */

protected void callUpdateProcedure(TransactionEvent e) {

super.doDML(DML_UPDATE, e);

}

/* Override in a subclass to perform non-default processing */

protected void callDeleteProcedure(TransactionEvent e) {

super.doDML(DML_DELETE, e);

}

5、生成CountriesRegionsEO的实现类,并使该类(CountriesRegionsEOImpl.java)继承于PLSQLEntityImpl.java类。重写callInsertProcedurecallUpdateProcedurecallDeleteProcedure方法,分别在三个方法内调用在步骤2中创建的PL/SQL程序包中的过程,添加帮助方法callStoredProcedure,完成对于程序包中过程的调用。

@Override

protected void callInsertProcedure(TransactionEvent e) {

callStoredProcedure("COUNTRIES_REGIONS_PKG.INSERT_ROW(?,?,?,?)",

new Object[] { this.getCountryId(),

this.getCountryName(),

this.getRegionId(),

this.getRegionName() });

}

@Override

protected void callUpdateProcedure(TransactionEvent e) {

callStoredProcedure("COUNTRIES_REGIONS_PKG.UPDATE_ROW(?,?,?,?)",

new Object[] { this.getCountryId(),

this.getCountryName(),

this.getRegionId(),

this.getRegionName() });

}

@Override

protected void callDeleteProcedure(TransactionEvent e) {

callStoredProcedure("COUNTRIES_REGIONS_PKG.DELETE_ROW(?)",

new Object[] { this.getCountryId() });

}

protected void callStoredProcedure(String stmt, Object[] bindVars) {

PreparedStatement st = null;

try {

// 1. Create a JDBC PreparedStatement for

st =getDBTransaction().createPreparedStatement("begin " + stmt + ";end;", 0);

if (bindVars != null) {

// 2. Loop over values for the bind variables passed in, if any

for (int z = 0; z <>

// 3. Set the value of each bind variable in the statement

st.setObject(z + 1, bindVars[z]);

}

}

// 4. Execute the statement

st.executeUpdate();

} catch (SQLException e) {

throw new JboException(e);

} finally {

if (st != null) {

try {

// 5. Close the statement

st.close();

} catch (SQLException e) {

}

}

}

6、生成该EOVO,并添加到AM,运行该AM,使用业务组件浏览器进行测试。这里添加新记录,点击保存后成功。(修改、删除均测试通过)

7、在完成了对于业务组件浏览器的测试后,新建页面,使用页面进行测试。

最终运行结果:


相关代码、程序包及脚本请查看:

howtoeoonview.rar