zoukankan      html  css  js  c++  java
  • oaf 动态创建table vo (转)

    原文地址:如何动态创建table

    需求:

    因为系统中有几千个QA plan 但是不能手动创建几千个 质量收集页面
    所有需要根据 不同的plan 动态创建对应的 质量收集页面。

    但是创建tabel 都要绑定一个 具体的vo  而我需要一个动态的
    如果用 select ... from dual 的话 字段的个数如何动态?

    感谢答主sumury

    方案0.1版本

    //用以下的代码可以实现,但是有一点不足,就是当数据量比较多的时候,无法按照指定的行数进行分页显示。
    
    //先在页面上创建一个advancedTable,名字叫“region5”,即可。
    
    public void processRequest(OAPageContext pageContext, OAWebBean webBean)
      {
        super.processRequest(pageContext, webBean);
    
        final String CHILD_DATA_LIST = "childDataList";
        final String TEXT = "text";
        int COLUMN_COUNT = 0;
    
        // write your Personalization SQL in here.
        StringBuffer sbfSQL = new StringBuffer(200);
        // set title in the advancedTable
        sbfSQL.append("SELECT '名' user_name, 'ID' user_id, '開始日'  FROM dual  
    ");
        sbfSQL.append("UNION ALL 
    ");
        sbfSQL.append("SELECT fu.user_name, to_char(fu.user_id), to_char(fu.start_date) FROM fnd_user fu");
    
        ResultSet rs = null;
        Statement s = null;
        Connection con = pageContext.getApplicationModule(webBean).getOADBTransaction().getJdbcConnection();
    
        try
        {
          s = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
          rs = s.executeQuery(sbfSQL.toString());
          ResultSetMetaData rsmd = rs.getMetaData();
          COLUMN_COUNT = rsmd.getColumnCount();
          rs.last();
          int intRowCount = rs.getRow();
          rs.first();
    
          // find the advancedTable
          OAAdvancedTableBean tableBean = (OAAdvancedTableBean)webBean.findChildRecursive("region5");
          tableBean.setViewUsageName("");
    
          for (int i = 1; i <= COLUMN_COUNT; i++)
          {
            // create a column
            OAColumnBean cb = (OAColumnBean)createWebBean(pageContext, COLUMN_BEAN, null, null);
            tableBean.addIndexedChild(cb);
    
            // create MessageStyledText
            OAMessageStyledTextBean mst = (OAMessageStyledTextBean)createWebBean(pageContext, MESSAGE_STYLED_TEXT_BEAN, null, null);
            mst.setTextBinding(TEXT + i);
            cb.addIndexedChild(mst);
    
            // create title
            OASortableHeaderBean shb = (OASortableHeaderBean)createWebBean(pageContext, SORTABLE_HEADER_BEAN, null, null);
            shb.setPrompt(rs.getString(i));
            cb.setColumnHeader(shb);
    
            if (i != 1)
            {
              UINodeList colList = new DataObjectListNodeList(mst, new DataBoundValue(CHILD_DATA_LIST + i)); 
              cb.setIndexedNodeList(colList);
            }
          }
    
          // get row count;
          DictionaryData rowData[] = new DictionaryData[intRowCount - 1];
          int intRowLoop = 2;
          // loop row 
          while (rs.next())
          {
            // setting 1 column cell value
            rowData[intRowLoop - 2] = new DictionaryData(TEXT + "1", rs.getString(1));
    
            // setting 2 to N column cell value
            DictionaryData otherColumn[] = new DictionaryData[COLUMN_COUNT];
            // loop column
            for (int j = 2; j <= COLUMN_COUNT; j++)
            {
              otherColumn[j - 2] = new DictionaryData(TEXT + j, rs.getString(j));
              rowData[intRowLoop - 2].put(CHILD_DATA_LIST + j , new ArrayDataSet(otherColumn));
            }
            intRowLoop++;
          }
          tableBean.setTableData(new ArrayDataSet(rowData));
        }
        catch (SQLException se)
        {
          se.printStackTrace();
        }
        finally
        {
          if (s != null)
          {
            try
            {
              s.close();
            }
            catch (SQLException se)
            {
              se.printStackTrace();
            }
          }
    
          if (rs != null)
          {
            try
            {
              rs.close();
            }
            catch (SQLException se)
            {
              se.printStackTrace();
            }
          }
        }
      }

    方案0.2版本

    /*今天空下来,又研究了一下这个问题,有种比之前的方法更好些的方法。贴出来大家看看。
    1、创建一个DynVO,里面不需要有SQL,而且只需要生成xml,就可以了
    2、把DynVO加到AM中去。
    3、在页面上创建advancedTable,取名region6,并且绑定DynVO1
    4、在CO中追加以下代码:*/
      public void processRequest(OAPageContext pageContext, OAWebBean webBean)
      {
        super.processRequest(pageContext, webBean);
        OAApplicationModule am = pageContext.getApplicationModule(webBean);
        String[][] strTitleAndAttributeName = (String[][])am.invokeMethod("initDynVO");
        OAAdvancedTableBean tableBean = (OAAdvancedTableBean)webBean.findChildRecursive("region6");
        for (int i = 0; i < strTitleAndAttributeName[0].length; i++)
        {
          // create a column
          OAColumnBean cb = (OAColumnBean)createWebBean(pageContext, COLUMN_BEAN, null, null);
          tableBean.addIndexedChild(cb);
          // create MessageStyledText
          OAMessageStyledTextBean mst = (OAMessageStyledTextBean)createWebBean(pageContext, MESSAGE_STYLED_TEXT_BEAN, null, null);
          mst.setViewAttributeName(strTitleAndAttributeName[1][i]);
          cb.addIndexedChild(mst);
          // create title
          OASortableHeaderBean shb = (OASortableHeaderBean)createWebBean(pageContext, SORTABLE_HEADER_BEAN, null, null);
          shb.setPrompt(strTitleAndAttributeName[0][i]);
          cb.setColumnHeader(shb);
        }
      }
    
    //5、在AM中追加以下代码
    
      public String[][] initDynVO()
      {
        StringBuffer sbfSQLTitle = new StringBuffer(200);
        // set title in the advancedTable
        sbfSQLTitle.append("SELECT '名' user_name, 'ID' user_id, '開始日' start_date FROM dual");
        StringBuffer sbfSQLValue = new StringBuffer(200);
        sbfSQLValue.append("SELECT fu.user_name, to_char(fu.user_id), to_char(fu.start_date) FROM fnd_user fu");
        
        OAViewObjectImpl vo = getDynVO1();
        vo.setQuery(sbfSQLTitle.toString());
        vo.executeQuery();
        // set attribute to updateable
        Row row = vo.first();
        AttributeDefImpl[] ad = (AttributeDefImpl[])vo.getViewDefinition().getAttributeDefs();
        int intAttributeCount = ad.length;
        String[] strTitle = new String[intAttributeCount];
        for (int i = 0; i < intAttributeCount; i++)
        {
          ad[i].setUpdateableFlag(AttributeDefImpl.UPDATEABLE);
          // get title from SQL result.
          strTitle[i] = (String)row.getAttribute(i);
        }
        vo.setQuery(sbfSQLValue.toString());
        vo.executeQuery();
        return new String[][]{strTitle, row.getAttributeNames()};
      }
    
    /*完毕。
    
    残留问题:
    虽然在AM的代码中写了ad[i].setUpdateableFlag(AttributeDefImpl.UPDATEABLE);
    发现,对于VO中的数据,我们是可以更新了。
    但是确不能insert和remove数据。
    目前还想不出怎么解决这个问题。*/

    终极版1.0

    /*通过一天的研究,解决了原来的代码中,无法对row进行insert和remove的处理。
    
    原来的代码,对VO进行了2次查询,第一次检索出advancedTable的标题,第二次检索出实际数据。
    
    但是比较好的做法是,使用UNION ALL,将两段查询合并,进行一次查询。
    
    对于查询结果而言,第一行是标题,待我们提取出来以后,再删除它,剩下的就是要在advancedTable中显示的数据了。
    
    然而,使用原来的代码,运行到row.remove()方法的时候,就是抛出错误消息Oracle.jbo.ReadOnlyViewObjectException: JBO-25016.
    
    所以,我们需要跟踪row.remove()方法看看,到底哪里抛出了这个错误消息。
    
    通过反编译 ViewRowImpl.class,发现*/
    void doRemove(int i)
    {
      ArrayList arraylist = null;
      try
      {
        useInner();
        if(mInner.mVO.isReadOnly())
          throw new ReadOnlyViewObjectException(mInner.mVO.getName());
    ......
    }
    
    //然后再查看ViewObjectImpl.class 文件
    public boolean isReadOnly()
    {
      return mViewDef.isReadOnly() && getDynamicAttributeCount() == 0;
    }
    
    /*到这里发现一点苗头了,我们可以通过修改mViewDef.isReadOnly()或getDynamicAttributeCount() == 0;中的任何一个值,来实现我们的目的。
    
    通过进一步的调查发现很难修改mViewDef.isReadOnly()的值,所以,只能将重点放在修改getDynamicAttributeCount()上了。
    
    通过读源代码发现,使用vo.addDynamicAttribute()方法,可以改变getDynamicAttributeCount()的返回值,于是就实验了一把。结果成功了。
    
    以下是修改好的代码,可以对VO中的数据进行insert、remove、update操作了。*/
    
       public String[][] initDynVO()
      {
        StringBuffer sbfSQL = new StringBuffer(200);
        // set title in the advancedTable
        sbfSQL.append("SELECT '名' user_name, 'ID' user_id, '開始日' start_date FROM dual ");
        sbfSQL.append("UNION ALL ");
        sbfSQL.append("SELECT fu.user_name, to_char(fu.user_id), to_char(fu.start_date) FROM fnd_user fu");
        
        OAViewObjectImpl vo = getDynVO1();
        vo.setQuery(sbfSQL.toString());
        vo.executeQuery();
        // set attribute to updateable
        Row row = vo.first();
        AttributeDefImpl[] ad = (AttributeDefImpl[])vo.getViewDefinition().getAttributeDefs();
        int intAttributeCount = ad.length;
        String[] strTitle = new String[intAttributeCount];
        String[] strAttributeNames = row.getAttributeNames();
        for (int i = 0; i < intAttributeCount; i++)
        {
          // for update the attribute
          ad.setUpdateableFlag(AttributeDefImpl.UPDATEABLE);
          
          // get title from SQL result.
          strTitle = (String)row.getAttribute(i);
        }
        // for insert and remove row.
        vo.addDynamicAttribute("DUMMY_ATTRIBUTE");
        row.remove();
        return new String[][]{strTitle, strAttributeNames};
      }

    感谢这些热爱思考且愿意分享代码的人们。

  • 相关阅读:
    telnet命令测试端口连接是否正常, telnet不是内部或外部命令的方案
    Linux常用命令
    nginx的反向代理的优势,特点于原理(一)
    linux操作系统中的常用命令以及快捷键(一)
    Centos网卡名称命名
    Centos第一次使用配置IP地址
    Linux环境下交叉编译器安装及运行
    jupyter更换路径
    python3实现在二叉树中找出和为某一值的所有路径
    使用 SQL 服务器时,"评估期已过期"错误消息
  • 原文地址:https://www.cnblogs.com/huanghongbo/p/4537005.html
Copyright © 2011-2022 走看看