使用表中的数组数据类型

在这篇文章中,我想跟进我以前关于Oracle集合数据类型的文章 ,并且我将集中精力使用af:table组件中的oracle.jbo.domain.Array属性。

因此,在我的数据库中,我具有以下SQL类型:



create or replace type varchar2_array_type as table of varchar2(200)

我有下表:

create table testarray (
SomeField Number,
ArrValue VARCHAR2_ARRAY_TYPE)
nested table ArrValue store as arrvalue_tab return as value;

ADF BC模型中有一个基于testarray表的实体:

屏幕截图2014-04-25 at 5.06.18 PM

属性Arrvalue的数据类型为oracle.jbo.domain.Array。

绑定容器中有一个相应的属性绑定:

<attributeValues IterBinding="VTestarrayIterator" id="Arrvalue">
      <AttrNames>
        <Item Value="Arrvalue"/>
      </AttrNames>
    </attributeValues>

显示此属性值的最简单方法如下:

<af:table value="#{bindings.Arrvalue.inputValue.array}" var="row" 
          id="t1">
   <af:column sortable="false" headerText="Array Values" id="c1">
      <af:inputText value="#{row}" id="ot3"/>             
   </af:column>
</af:table>

结果看起来非常不错:

屏幕截图2014年4月25日下午5.35.38

这种方法的唯一问题是该表不可更新。 它是只读的。

EL表达式“#{bindings.Arrvalue.inputValue.array}”将调用方法oracle.jbo.domain.Array.getArray() ,该方法返回一个不变的Object []数组,并且对该数组的所有修改都将丢失。

如果我们需要能够更新表中的数据,则必须执行以下操作:

  1. 制作bindings.Arrvalue.inputValue.array的副本
  2. 将此副本设置为表的值
  3. 在“更新模型值”阶段,将副本包装回oracle.jbo.domain.Array,并将其放入Arrvalue.inputValue。

因此,我们将制作一个副本并将其保留在请求范围托管的bean中:

private Object[] array = null;

private Object[] createArray() {
  JUCtrlValueBinding dcb = getArrayCtrlBinding();
  if (dcb!=null){
      Array arr = (Array) dcb.getInputValue();
      if (arr!=null) {
          array = arr.getArray();
      }          
  }
  return array;
}


public void setArray(Object[] array) {
    this.array = array;
}

public Object[] getArray() {
    return (array == null ? createArray() : array);
}

    
private JUCtrlValueBinding getArrayCtrlBinding() {
  BindingContext bc = BindingContext.getCurrent();
  DCBindingContainer binding = (DCBindingContainer) bc.getCurrentBindingsEntry();
  return (JUCtrlValueBinding ) binding.findCtrlBinding("Arrvalue");
}

当使用此副本作为表的值时,我们可以执行以下操作:

<af:table value="#{TheBean.array}" var="row" 
            id="t1"
            varStatus="status">
    <af:column sortable="false" headerText="Array Values" id="c1">
       <af:inputText value="#{TheBean.array[status.index]}" id="ot3"/>             
    </af:column>
  </af:table>

请注意,我们不仅使用#{row}作为inputText的值。 这将不起作用,因为#{row}只会返回一个不变的String。 取而代之的是,我们使用了varStatus表属性。 EL表达式#{TheBean.array [status.index]}使框架能够在“更新模型值”阶段调用相应的setter方法,因此表中所做的所有修改都将保存到TheBean.array中

最后一步是在“更新模型值”阶段将TheBean.array放回属性值。 为此,我们可以使用伪造的不可见的inputText

<af:inputText value="#{TheBean.dummy}" 
              visible="false" 
              converter="EmptyConverter"
              id="it2"/>

此输入文本应放在页面上表格的下方。 这种方法的优点在于,框架将尝试在每个请求上更新inputText值。 因此,将表值保存到TheBean.array之后,将在更新模型值阶段对每个请求调用setter方法TheBean.setDummy(String dummy) 。 现在,我们将把数组包装到oracle.jbo.domain.Array中 ,然后放回Arrvalue.inputValue

public void setDummy(String dummy) {
  getArrayCtrlBinding().setInputValue(new Array(array));   
  array = null;
}

虚拟 inputText的秘密隐藏在EmptyConverter中:

public class EmptyConverter implements Converter {
 public Object getAsObject(FacesContext facesContext,
                           UIComponent uIComponent, String string) {
     return null;
 }

 public String getAsString(FacesContext facesContext,
                           UIComponent uIComponent, Object object) {
     return null;
 }
}

它模拟已随请求为此组件提交了值。 另一方面, 伪获取器总是返回一个非空值:

public String getDummy() {
    return DUMMY;
 }

因此,该框架别无选择,只能在“更新模型值”阶段调用setDummy方法。

本文的示例应用程序需要JDeveloper 11.1.1.7。

而已!

翻译自: https://www.javacodegeeks.com/2014/04/working-with-the-array-data-type-in-a-table.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值