zoukankan      html  css  js  c++  java
  • OAF VO初始化分析

    目录

    第一部分 插入新行前的初始化

    1 仅插入型VO的初始化

    2 插入查询VO的初始化

    第二部分 执行查询前的初始化

    1 避免无条件查询

    2 避免多余的查询

    正文

    第一部分 插入新行前的初始化

    在处理插入初始化之前,我们必须确定一件事情,就是当前我们要处理的这个VO,它是只用作插入操作呢,还是即用作插入又用作查询操作。比如一个EmployeeCreateVO,这个VO仅仅在创建新员工的页面使用,不用做其他用途,那么我们认为它是一个只做插入操作的VO,反之,它就是一个即查询又插入的VO.理清楚这一点,对合理初始化VO很重要。

    1仅插入型的VO的初始化

    我们可以利用如下代码:

    //检查VO是否有行,如果有行了,我们就不用执行括号里的语句了。vo.getFetchedRowCount()是检查当前缓存中VO的行数,包括新插入的行,它不执行数据库查询,仅仅检查内存中已经取出来的行。如VO已经被插入过行了,那么getFetchedRowCount肯定大于0,就无需再调用setMaxFetchSize了

    if (vo.getFetchedRowCount() == 0) {

    //此方法是设置VO的每次查询行数的上限,但是如果参数为0的话,此方法会设置mPreparedForExecution标识为TRUE。这个标识是OAViewObjectImpl的一个成员变量,表示VO是否准备好执行查询,初始值是FALSE。当VO执行了executeQuery()之后,该标识值也会被设为TRUE。

    vo.setMaxFetchSize(0);

    }

    // 执行插入操作

    Row row = vo.createRow();

    vo.insertRow(row);

    //遵循代码标准M69,在所有新插入的行后立即将起设置为STATUS_INITIALIZED状态,让此行处于脱管状态,不参与事务提交,不参与验证,直到在页面上对这行数据进行更新,然后OA框架自动把状态设回为STATUS_NEW,以重新参与事务和验证。

    row.setNewRowState(Row.STATUS_INITIALIZED);

    有时候我们会遇到这个错误:“违反了 OA 钝化结构编码标准。未正确准备全名为EmployeeAM.EmployeeFullVO1 的视图对象以供插入行。必须先调用视图对象中的setMaxFetchSize(0) 或executeQuery()(或最终执行视图对象查询的任何等效方法),然后才能插入新行。”

    我估计是OAF框架在遇到插入行的时候,会检查当前VO有没有行,如果没有行,会检查在这句代码前面是否执行了executeQuery()或setMaxFetchedSize(0)语句(而不是检查mPreparedForExecution的值是否为TRUE),如果没有执行这样的语句,那么就报告违反钝化编码标准。当然这只是我的个人猜测,仅供参考。

    对于只包含瞬时属性的VO,为了避免OAF中的一些已知的BUG,我们在对其进行初始化的时候最好像下面这样编写代码:

    if (vo.getFetchedRowCount() == 0) {

    vo.setMaxFetchSize(0);

    vo.executeQuery();

    ... // Insert rows into the view object.

    }

    2带数据库查询的VO的初始化

    首先,我们必须注意,在这种既用于查询又用于插入的VO情况下,我们必须先执行executeQuery(),然后再insertRow(),否则会导致一些钝化上的问题。

    提示1:

    总的来说,尽量为“创建**”或“插入**”型页面单独创建一个VO,比如单独创建一个创建员工的VO,EmployeeCreateVO.

    提示2:

    如果实在需要插入和查询或更新都公用一个VO,那么在插入前,应该给executeQuery加上条件。

    if (!vo.isExecuted()){

    vo.executeQuery();

    // 或者调用vo.initQuery(..),以便根据你自己WHERE条件进行查询。

    }

    Row row=vo.createRow()

    …其他初始化操作

    注意:根据我个人经验,由于mPreparedForExecution标识变量并不会在rollback()后变为false,会造成未执行executeQuery()就进行insertRow()操作,那么OA框架就会报告“违反了OA 钝化结构编码标准。未正确准备全名为 EmployeeAM.EmployeeFullVO1的视图对象以供插入行。必须先调用视图对象中的 setMaxFetchSize(0) 或executeQuery()(或最终执行视图对象查询的任何等效方法),然后才能插入新行。”,所以在进行插入操作前,通过vo.isPreparedForExecution来作为判断条件不是最好的选择,可以选择用vo.isExecuted来代替。

    第二部分 执行查询前的初始化

    1避免无条件查询

    一般情况下,我们可以使用下面的方法来避免无条件执行查询操作

    if (!vo.isPreparedForExecution()) {//带条件执行查询操作

    vo.executeQuery();

    // 或者调用vo.initQuery(..),以便根据你自己WHERE条件进行查询。

    }

    无条件执行查询操作会导致一些事务状态的丢失,比如,对瞬时属性(transient view objectattributes)数据的更新会丢失,VO的current Row和currentRange会被重设。这也就从一定解释了“翻页后在有删除确认对话框的页面中无法删除行的案例”,具体参考我的另一篇文章《翻页后在有删除确认对话框的页面中无法删除行的案例》。

    但是,有几种情况你不应该给查询加上条件:

    1.你的页面是只读的,你不在乎VO的事务状态,你只希望每次渲染页面的时候都能看到数据库中的最新数据。

    2.如果这个查询是在processFormRequest中调用的,例如,页面上有一个“GO”按钮,希望点击的时候查询出满足我需要的数据,那么这个时候也不要给他加上面的条件。因此,我们可以这样理解,上面的“带条件执行查询操作”仅用于在processRequest中对页面包含的VO的数据进行初始化操作。

    3.加了这个条件后,在保持同一个AM的范围内,这个vo只被查询一次,以后不会再被查询,如果想重新执行查询,得到最新的数据,那么需要释放AM。

    对于下钻页面(Drilldown TargetPage),比如搜索结果页面中点击员工姓名下钻到员工的详细信息,我们也不能依赖于isPreparedForExecution的判断,它太容易返回true了,以至于我们的查询得不到执行,我们更喜欢用vo.findByKey()这个方法,这个方法是根据VO下面的EO主键来查询,首先会检查缓存中有没有这条数据,没有才去执行数据库查询。注意,下钻页面的VO和搜索页面的VO最好不要使用同一个,以免下钻后,影响搜索页面的状态。

    public void initDetails(Number employeeNumber){

    EmployeeFullVOImpl vo = getEmployeeFullVO1();

    Number[] keys = { employeeNumber};

    Row[] rows = vo.findByKey(new Key(keys), 1);

    // findByKey不会改变currentRow指针,所以需要我们手动去更改,否则页面上不会显示值。

    if ((rows != null) &&(rows.length > 0)) {

    vo.setCurrentRow(rows[0]);

    } } // end initDetails()

    2避免多余查询

    涉及个性化,暂不讨论

  • 相关阅读:
    spark 读取mongodb失败,报executor time out 和GC overhead limit exceeded 异常
    在zepplin 使用spark sql 查询mongodb的数据
    Unable to query from Mongodb from Zeppelin using spark
    spark 与zepplin 版本兼容
    kafka 新旧消费者的区别
    kafka 新生产者发送消息流程
    spark ui acl 不生效的问题分析
    python中if __name__ == '__main__': 的解析
    深入C++的new
    NSSplitView
  • 原文地址:https://www.cnblogs.com/AI-xiaocai/p/11454827.html
Copyright © 2011-2022 走看看