如何定制EO的增加、修改、删除操作?

187 篇文章 2 订阅
开发环境:JDeveloper 11.1.2.2.0 + Oracle XE Database 10gR2。

本实验基于《 使用ADF实现基于Form的CRUD (3)

ADF-BC中的EO对象写入数据库的操作本来不需要我们关心,不用写任何代码,这是使用ADF-BC的好处之一。
但在实际开发中,有时需要在EO入库前做一些其它操作,比如设置默认属性值、设置Sequence值;有时需要在插入某个EO后做一些其它事情,比如再插入另一个EO对象。
这时,就需要定制EO的增加、修改、删除操作,以及定制提交入库前后的代码。

ADF-BC为定制化提供了优美的解决方案:
1. 定制EO的增加、修改、删除操作
(1)选中需要定制的EO,为其生成对应的Entity Object Java Class,勾上“Create”、“Remove”、“Data Manipulation Methods"。

(2)定制create、remove、doDML方法
 protected void create(AttributeList attributeList) {
        System.out.println("################### before create:");
        super.create(attributeList);
        System.out.println("################### after create:");
   }

   public void remove() {
        System.out.println("################### before remove:");
        super.remove();
        System.out.println("################### after remove:");
    }
    
   protected void doDML(int operation, TransactionEvent e) {
        if (operation == DML_INSERT) {
            System.out.println("################### doDML before insert:");
            super.doDML(operation, e);
            System.out.println("################### doDML after insert:");
        } else if (operation == DML_UPDATE) {
            System.out.println("################### doDML before update:");
            super.doDML(operation, e);
            System.out.println("################### doDML after update:");
        } else if (operation == DML_DELETE) {
            System.out.println("################### doDML before delete:");
            super.doDML(operation, e);
            System.out.println("################### doDML after delete:");
        }
    }

doDML方法说明:
(1)根据不同的操作(增加、修改、删除),选择不同的逻辑分支。
super.doDML(operation, e); 就是EO自身的入库操作代码,除非你要彻底修改它的逻辑,否则不要修改。
(2)入库前的代码,写在super.doDML(operation, e);之前。
(3)入库后的代码,写在super.doDML(operation, e);之后。
(4)关于EO常用操作代码请参考《 ADF-BC中EO常用操作代码之一:查询 》系列文章。


2. 定制EO提交入库前后的代码
EO提交入库分为前后两个阶段:Post Phase和Commit Phase。
(1)Post Phase
验证标记为”invalid“的EO,所有新建的和修改的EO都被标记为”invalid“的EO。
验证定义在EO上的所有验证规则,包括定制的验证规则。
由于验证规则可能会修改EO数据,因此验证过程将反复执行多次,最多执行10次,直到EO被标记为”valid"。
最后,把标记为”valid"的EO提交到数据库。
(2)Commit Phase
提交事务,将EO改变的数据写入数据库。

public void postChanges(TransactionEvent transactionEvent) {
        System.out.println("################### before postChanges:");
        super.postChanges(transactionEvent);
        System.out.println("################### after postChanges:");
    }

    public void beforeCommit(TransactionEvent transactionEvent) {
        System.out.println("################### before commit:");
        super.beforeCommit(transactionEvent);
    }

    public void beforeRollback(TransactionEvent transactionEvent) {
        System.out.println("################### before rollback:");
        super.beforeRollback(transactionEvent);
    }

    public void afterCommit(TransactionEvent transactionEvent) {
        super.afterCommit(transactionEvent);
        System.out.println("################### after commit:");
    }

    public void afterRollback(TransactionEvent transactionEvent) {
        super.afterRollback(transactionEvent);
        System.out.println("################### after rollback:");
    }


3. 运行AM
(1)点击Insert

Console输出如下:
################### before create:
################### after create:
[67] **** refreshControl() for BindingContainer :AppModule_JobsView1_0PageDef
(2)成功Insert后,点击Commit

Console输出如下:
[68] INFO: No app _def_ in BindingContext for: adfFacesContext
[69] INFO: mDCRefMap lookup failed. Does the cpx have a dataControlUsages 'dc' entry? adfFacesContext
[70] INFO: No app _def_ in BindingContext for: adfFacesContext
[71] INFO: mDCRefMap lookup failed. Does the cpx have a dataControlUsages 'dc' entry? adfFacesContext
[72] OracleSQLBuilder: SAVEPOINT 'BO_SP'
################### before postChanges:
################### doDML before insert:
[73] OracleSQLBuilder Executing, Lock 2 DML on: JOBS (Insert)
[74] INSERT buf Jobs>#i SQLStmtBufLen: 300, actual=77
[75] INSERT INTO JOBS(JOB_ID,JOB_TITLE,MIN_SALARY,MAX_SALARY) VALUES (:1,:2,:3,:4)
[76] Insert binding param 1: 3344
[77] Insert binding param 2: 4444
[78] Insert binding param 3: 1
[79] Insert binding param 4: 2
################### doDML after insert:
################### after postChanges:
################### before commit:
################### after commit:
[80] JobsView1 notify COMMIT ... 
(3)修改EO数据,并点击Commit
Console输出如下:
[81] OracleSQLBuilder: SAVEPOINT 'BO_SP'
################### before postChanges:
[82] OracleSQLBuilder Executing doEntitySelect on: JOBS (true)
[83] Built select: 'SELECT JOB_ID, JOB_TITLE, MIN_SALARY, MAX_SALARY FROM JOBS Jobs'
[84] Executing LOCK...SELECT JOB_ID, JOB_TITLE, MIN_SALARY, MAX_SALARY FROM JOBS Jobs WHERE JOB_ID=:1 FOR UPDATE NOWAIT
[85] Where binding param 1: 3344
################### doDML before update:
[86] OracleSQLBuilder Executing, Lock 2 DML on: JOBS (Update)
[87] UPDATE buf Jobs>#u SQLStmtBufLen: 255, actual=64
[88] UPDATE JOBS Jobs SET MIN_SALARY=:1,MAX_SALARY=:2 WHERE JOB_ID=:3
[89] Update binding param 1: 3
[90] Update binding param 2: 4
[91] Where binding param 3: 3344
################### doDML after update:
################### after postChanges:
################### before commit:
################### after commit:
[92] JobsView1 notify COMMIT ... 
[93] EntityCache close prepared statement
(4)点击Delete

Console输出如下:
################### before remove:
[94] QueryCollection: afterRemove(0)
[95] ViewRowCache: removeReference, vr id = 3
################### after remove:
(5)成功Delete后,点击Commit

Console输出如下:
[96] OracleSQLBuilder: SAVEPOINT 'BO_SP'
################### before postChanges:
[97] OracleSQLBuilder Executing doEntitySelect on: JOBS (true)
[98] Built select: 'SELECT JOB_ID, JOB_TITLE, MIN_SALARY, MAX_SALARY FROM JOBS Jobs'
[99] Executing LOCK...SELECT JOB_ID, JOB_TITLE, MIN_SALARY, MAX_SALARY FROM JOBS Jobs WHERE JOB_ID=:1 FOR UPDATE NOWAIT
[100] Where binding param 1: 3344
################### doDML before delete:
[101] OracleSQLBuilder Executing, Lock 2 DML on: JOBS (Delete)
[102] DELETE buf Jobs>#u SQLStmtBufLen: 105, actual=37
[103] DELETE FROM JOBS Jobs WHERE JOB_ID=:1
[104] Where binding param 1: 3344
################### doDML after delete:
################### after postChanges:
################### before commit:
################### after commit:
[105] JobsView1 notify COMMIT ... 
[106] EntityCache close prepared statement

4. 把删除操作变为修改操作
(1)重写remove方法和doDML方法
    public void remove() {
        setMinSalary(new Integer(-1));
        setMaxSalary(new Integer(-1));
        super.remove();
    }

    protected void doDML(int operation, TransactionEvent e) {
        if (operation == DML_INSERT) {
            System.out.println("################### doDML before insert:");
            super.doDML(operation, e);
            System.out.println("################### doDML after insert:");
        } else if (operation == DML_UPDATE) {
            System.out.println("################### doDML before update:");
            super.doDML(operation, e);
            System.out.println("################### doDML after update:");
        } else if (operation == DML_DELETE) {
            if (operation == DML_DELETE) {
                operation = DML_UPDATE;
            }
            super.doDML(operation, e);         
        }
    }

remove方法说明:这里必须把设置字段值的操作放到 super.remove();前面,否则运行时会抛出异常:“Attempt to access dead entity in Jobs, key=oracle.jbo.Key[123 ]"。
(2)运行AM,删除一条记录,并Commit
Console输出如下:
[81] QueryCollection: afterRemove(0)
[82] ViewRowCache: removeReference, vr id = 3
[83] OracleSQLBuilder: SAVEPOINT 'BO_SP'
################### before postChanges:
[84] OracleSQLBuilder Executing doEntitySelect on: JOBS (true)
[85] Built select: 'SELECT JOB_ID, JOB_TITLE, MIN_SALARY, MAX_SALARY FROM JOBS Jobs'
[86] Executing LOCK...SELECT JOB_ID, JOB_TITLE, MIN_SALARY, MAX_SALARY FROM JOBS Jobs WHERE JOB_ID=:1 FOR UPDATE NOWAIT
[87] Where binding param 1: 2232
[88] OracleSQLBuilder Executing, Lock 2 DML on: JOBS (Update)
[89] UPDATE buf Jobs>#u SQLStmtBufLen: 255, actual=64
[90] UPDATE JOBS Jobs SET MIN_SALARY=:1,MAX_SALARY=:2 WHERE JOB_ID=:3
[91] Update binding param 1: -1
[92] Update binding param 2: -1
[93] Where binding param 3: 2232
################### after postChanges:
################### before commit:
################### after commit:
[94] JobsView1 notify COMMIT ... 
[95] EntityCache close prepared statement
查看数据库,被Delete的记录依然存在,只是MinSalary和MaxSalary字段的值为-1。

5. 运行页面form_crud.jsf
点击Delete,并确认提交后,发现数据被真的删除了,说明Delete Opertaion并没有调用remove方法。
从Console输出也能够看出来,因为没有打印出来自定义的语句,这不符合我的本来想法。
如果执行Delete Opertaion时没有调用remove方法,那remove方法就失去其意义了。
难道说,如果想调用remove方法,就必须通过程序明确调用EO的remove方法?比如:
    public void deleteJob(String jobId) {
        JobsImpl job = retrieveJobById(jobId);
        if (job != null) {
            job.remove();
            try {
                getTransaction().commit();
            } catch (JboException ex) {
                getTransaction().rollback();
                throw ex;
            }
        }
    }


Project 下载:ADF_Form_CRUD(CustomEO).7z

http://maping930883.blogspot.com/2010/04/adf058eo_03.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值