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避免多余查询

    涉及个性化,暂不讨论

  • 相关阅读:
    springmvc返回视图或当api
    springmvc初始注解案例
    @RequestMapping的属性、缩写
    struts初始案例
    2020-3-5所思所想
    使用selenium学习
    spring链接数据库与事务等实际运用再加
    spring的aop
    ubuntu安装docker
    java内存区域和内存溢出异常
  • 原文地址:https://www.cnblogs.com/AI-xiaocai/p/11454827.html
Copyright © 2011-2022 走看看