天天看点

ADF开发中一些技术介绍

   问题1:

  //JAVA代码里面取得SEQUENCE

    DBTransaction trans = getDBTransaction();

    SequenceImpl seq =

      new SequenceImpl("exp_spe_actreq_vol_line_s", trans); //exp_spe_actreq_vol_line_s是数据库里面的序列

 问题2:

 //在页面的table中光标换行就刷新一次table的情况

   方法一:检查各个组件中的partialTriggers如果删除所有的partialTriggers还是会出现刷新的情况的话那就用第二种情况

   方法二:这个方法是找到这个页面对应的PageDef.xml这个文件,在此文件中查找是否有ChangeEventPolicy="ppr"的语句,

           如果有的话就尽可能的将它删掉要不然页面肯定会刷新。

 问题3:       

 //JAVA代码中获取日期中各个部分如月,日,年的方法

      DateFormat df = new SimpleDateFormat("yyyy-MM-dd");  //格式中月份的格式必须要写成MM不能为mm,JAVA中没有mm格式

      java.util.Date da = new java.util.Date();

      try {

        da = df.parse(month);

      } catch (ParseException e) {

      }

      Calendar cal = Calendar.getInstance();

      cal.setTime(da);

      int month2 = cal.get(Calendar.MONTH) + 1;    //获取月份的方法

 问题4:

 //此处是创建一个子查询并且可以解决模糊查询的问题

   public void createNewBraYearBudgetHead(Hashtable result) {

    CustomViewImpl yearbudgethead = this.getExpsBraYearBudgetHeadVO1();

      ViewCriteria vc = yearbudgethead.createViewCriteria();

      ViewCriteriaRow vcr = vc.createViewCriteriaRow();

      yearbudgethead.setNamedWhereClauseParam("p_region_id", pregionId);   //给VO邦定变量设置值

      Enumeration enu1;

      enu1 = result.keys();

      Object value;

      while (enu1.hasMoreElements()) {

        String key = (String)enu1.nextElement();

            value = result.get(key);

            vcr.setAttribute(key, value);         //此处是给VO中的字段设置值,并且这设置的值查询时还支持带'%'

      }

      vc.addElement(vcr);

      yearbudgethead.applyViewCriteria(vc);

      yearbudgethead.executeQuery();

  }

  问题5:

      点击页面保存按钮时报JBO-25014: Another user has changed的错误的解决方法

      错误原因:

         产生这个错误的原因可能是因为我这里面是在AM里面调用了存储过程对表中的数据进行了更改,而改完数据后没有把数据库更改的数据及时的刷新到对应的VO里面

         这样我再见次点击保存按钮时它就会报这样的错误。

      方法一:

        在对应的数据表加上OBJECT_VERSION_NUMBER字段数据类型为NUMBER,同时将这个字段引入到对应的EO中,在EO中找到

        这个字段将它的"Change Indicato","History Column"属性勾选上,同时"History Column"属性值选上"version number"

        设置并保存好再次运行应该就不会再有这个错误了。

      方法二:

        如果你不加那个字段你就可以找到对应EO的JAVA实现类,在这个实现类里默认有一个JAVA方法如下

          public void lock() {

             super.lock();

           }

        你只要将这个方法改为它是通过什么原理实现的我也不知道

             public void lock()

           {

               try {

                   super.lock();

               } catch (RowInconsistentException e) {

                 refresh(REFRESH_WITH_DB_ONLY_IF_UNCHANGED | REFRESH_CONTAINEES);

                  super.lock();       }

           }

        有个英文网站讲得比较详细

        http://www.avromroyfaderman.com/2008/05/bring-back-the-hobgoblin-dealing-with-rowinconsistentexception/

        对于方法二的解决办法不推荐这是一种把ADF本身正确的机制给强行屏蔽掉了;还有对于凡是对于Master-Detail要在AM里面调用存储过程对表中的数据进行更改的都应

        该尽量把这个方法放到EO实现类的beforeCommit方法里面去,这个方法就是在同一个session还没有COMMIT数据之前去进行数据操作,如果操作失败它的回滚

        机制会去将所有数据操作回滚掉这样就会避免脏数据的产生。

 问题6:

     ADF实现条件传参跳转到新的窗口输出结果(这个在报表中会用到)

     例如我目前有这么一张报表在当前页面把查询条件输入完毕后点击查询按钮它就会把这些条件传到另外一个新的页面同时打开一个新的窗口来输出结果

     步骤一:按钮为gobutton按钮,在这个按钮中拖入一个子组件叫clientListener,在这个组件上邦定好一个javascript,type设为click

     javascript代码如下:

       function doBudgetPayoffPaymentEvent(evt){

          var url = "report/ExpsProBudgetPayoffPayMentReport.jspx";    //此处为页面跳转时初始的URL

          var obj = evt.getSource();

          var objClientId = obj.getClientId();                         //获得当前按钮的clientId

          var Express = objClientId.substring(0,objClientId.lastIndexOf("doEventId"));    //获得按钮所在的层次

          var year = AdfPage.PAGE.findComponent(Express+"realYear") ;        //通过层次获得页面上的查询条件的值

          if(year !=null&&year.getValue()!=null){

              url = url+"?PERIODYEAR="+year.getValue();

           }

           var month = AdfPage.PAGE.findComponent(Express+"realMonthId") ;

           if(month !=null&&month.getValue()!=null){

               if(url.lastIndexOf("?")>0)

                  url = url+"&PERIODNUM="+month.getValue();

                else

                  url = url+"?PERIODNUM="+month.getValue();

            }

            var status = AdfPage.PAGE.findComponent(Express+"realStatusId") ;

            if(status !=null&&status.getValue()!=null){

               if(url.lastIndexOf("?")>0)

                  url = url+"&EXPENSESTATUS="+status.getValue();

                else

                  url = url+"?EXPENSESTATUS="+status.getValue();

              }

             var inputComponet = AdfPage.PAGE.findComponent(Express+"codeId") ;

              if(inputComponet !=null&&inputComponet.getValue()!=null){

                if(url.lastIndexOf("?")>0)

                  url = url+"&PMBUDGETCODE="+inputComponet.getValue();

                else

                  url = url+"?PMBUDGETCODE="+inputComponet.getValue();

              }

            var region = AdfPage.PAGE.findComponent(Express+"treeLov1:returnKey") ;

            if(region !=null && region.getValue()!=null){

             if(url.lastIndexOf("?")>0)

                url = url+"&PREGIONID="+region.getValue();

             else

                url = url+"?PREGIONID="+region.getValue();

            }

            window.open(url);

        }

        步骤二:

             在下一个页面的Bindings中邦定一个AM里面的方法这个方法的目的是在初始化页面的时候就执行的方法,它获得前一个页面的传过来的参数,

             通过这些参数执行条件查询这样这个页面一运行出来就得到了自己想要的结果

    //获得前一个页面传过来的参数值的部分代码

    FacesContext facesContext = FacesContext.getCurrentInstance();

    ExternalContext externalContext = facesContext.getExternalContext();

    HttpServletRequest request = (HttpServletRequest)externalContext.getRequest();

    //get status

    Object status = request.getParameter("EXPENSESTATUS");

    //get month

    Object periodMonth = request.getParameter("PERIODNUM");

    //get region Id

    Object vRegion = request.getParameter("PREGIONID");

    //get year

    Object periodYear = request.getParameter("PERIODYEAR");

    //get mbudgetcode

    Object mcode = request.getParameter("PMBUDGETCODE");

    注意:

    1.  在Bindings中的Bindings中邦定AM里面的方法,要想页面初始的时候就去调用这个方法那得在Executables中去创建一个执行步骤,

    让这个执行步骤去调用AM中的那个业务方法。

    2.   这个问题涉及到报表打印,即在显示数据的页面布局中直接将主要的主件拖放到af:form下面就行了而不要把那些装载数据的组件再

    放到如af:panelGroupLayout(panelCollection)组件中这样会导致显示出来的数据在你想用IE浏览器自带的打印去打印的时候不会分页从而致使数据

    不能完全打印出来因它会将所有数据显示在一页上大数据量的时候这显然是不对的。

 问题7:ADF中用JAVA设置数据回滚点并用这些设置执行指定的回滚操作

    步骤一:如下代码是在触发某个事件的时候执行如下代码去设置一个数据回滚点

      public void createAmfSavePoint(ClientEvent clientEvent) {

    RequestContext rctx = RequestContext.getCurrentInstance();

    DCBindingContainer binding = ADFUtils.getDCBindingContainer();

    DCDataControl dcDataControl = binding.getDataControl();

    String sph = (String)dcDataControl.createSavepoint();

    rctx.getPageFlowScope().put("SavePoint", sph); 

  }            //SavePoint为回滚点的名字随便起

  步骤二:下面的代码是触发某个事件时获得上面设置的回滚点让数据回滚到指定的区间

    public String restore_action() {

    RequestContext rctx = RequestContext.getCurrentInstance();

    String sph = (String)rctx.getPageFlowScope().get("SavePoint");

    DCBindingContainer binding = ADFUtils.getDCBindingContainer();

    DCDataControl dcDataControl = binding.getDataControl();

    if (sph != null)

      dcDataControl.restoreSavepoint(sph);

    return null;

  }

  rctx.getPageFlowScope().put("SavePoint", sph)此代码是设置此变量在整个task_flow有效,如果进入另一个task_flow这个值就无效。