问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

如何动态创建table-OAF开发

发布网友 发布时间:2022-04-14 12:26

我来回答

2个回答

懂视网 时间:2022-04-14 16:47

我们知道 MDS 是 MetaData Service 的缩写; 我们也知道 MDS 跟 OAF 框架中页面显示有某种关系. 让我们来理解一下 MDS 的基础知识. Meta: 在技术领域里面, meta 表示字典. 想象一下, 一个网页被分解成许多很小的单元( 单元格, 按钮, 选项框...). 这些小单元被

我们知道 "MDS" 是 "MetaData Service" 的缩写; 我们也知道 MDS 跟 OAF 框架中页面显示有某种关系. 让我们来理解一下 MDS 的基础知识.


Meta: 在技术领域里面, meta 表示"字典". 想象一下, 一个网页被分解成许多很小的单元( 单元格, 按钮, 选项框...). 这些小单元被存储在数据库中的一个字典( 表 )里面. 当把这些单元组合起来, 就变成一个在浏览器中显示的网页.

Data: 那些字典碎片( meta pieces) 并不是以二进制文件的方式存储的, 而是存储在数据库表中. 这些表的前缀是 "jdr", 比如 JDR_ATTRIBUTES, JDR_ATTRIBUTES_TRANS, JDR_COMPONENTS 和 JDR_PATHS. 所有的字段/区域/组件( field/region/component) 的定义和关系, 都存储在这些 JDR 的表中. 当你请求一个页面的时候, OAF 框架就会从数据库里面读取这些数据. 页面的结构就是从这些 MetaData 重构出来的.

Service: MetaData 可以作为一个服务使用. 所有的数据都存在 JDR 表中, 但是所有的这些数据都必须重新连接, 所有的字段, 区域, 按钮都必须以有意义的方式组成页面. 所以可以说, MDS 提供了一项服务, 来存储/重构网页页面. MDS 服务重新把零碎的页面组件组合成有意义的页面.

在 jDeveloper 中, 当我们在创建一个页面和区域, 看起来似乎是在创建一个 XML 文件. 在OAF 框架中, 页面定义是用 XML 文件来保存的吗?

实际上页面定义是存储在 JDR 表中的, 并不是以 XML 文件存储. 但是 MDS 提供了一个 API 接口, 用来把 JDR 表数据转化成 XML 描述性文件.

因此这里有两种形式:

1. 当我们设计页面的时候, 我们把页面的定义以 XML 格式保存在文件系统里面. 当我们部署服务器/系统的时候, 我们就需要把这些 XML 格式的文件导入到 JDR 表中. OAF 框架提供了导入工具 import:

例如用下面的的命令把 RcvBarCodeLovRN.xml 导入到数据库

C:Oraclep9879989jdevbinoaextinimport C:Oraclep17888411jdevhomejdevmyprojectsoracleappspo
cvlovwebuiRcvBarCodeLovRN.xml -rootdir C:Oraclep17888411jdevhomejdevmyprojects -username apps -password apps -dbconnection erik-lnx.oracle.com:1522:VID

select * from JDR_COMPONENTS where comp_id = 'SecTxnQtyColRN';

2. 当用户要显示一个页面的时候, OAF 框架做了下面的事情:

第一步. OAF 框架向 MDS 请求页面定义, 这会被缓存( 第一次打开页面会比较慢, 以后会比较快).
第二步. MDS 引擎向 OAF 框架返回一个 XML 文件
第三步. XML 文件中的每一个节点/组件( mode/component) 会被转化成一个 webBean 对象.

比方说有个页面, 结构如下:
Region-Main
field1
Region-Child
Button

在这个示例中, OAF 框架将会实例化4 个 webBean 对象, 每一个对象都代表了一个组件(field/button/region...). 每一个 webBean 对象都有一些方法比如: setRendered(), setRequired(), getRequired() 等等.
第四步. 这些 webBean 对象不仅被一个个创建出来, 而且他们之间是相互嵌套的, 嵌套的顺序跟页面定义时一样. 因此页面组件的父-子关系被保留下来.
第五步. 页面准备好之后, OAF 框架会调用 MDS 页面的控制器 controller( CO.class). 当 CO 中的processRequest() 方法执行完毕之后, 用户就可以看到页面了.

到现在为止, OAF 已经显示了 web page, 下面会发生什么呢?

在回答这个问题之前, 我们先回顾一下之前的步骤. 让我们回顾一下怎样定义这个页面的. 在OAF 中, 当我们定义一个页面的时候, 有两个关键步骤:
1. 为 page 定义一个 CO/controller
2. 定义一个 AM/application module 并附加到这个页面上.
当一个页面在浏览器中显示时, 会发生下面的事情:
a. 框架会在内存中, 根据 MDS 给出的 XML 文件建立一个 webBean 的层级关系, 用来表示页面的结构.
b. 创建一个 ApplicationModule 对象. 我们可以重新获取这个 AM 对象来管理页面的数据库状态.
c. CO 中的processRequest() 方法执行.

执行processRequest() 方法会传递哪些参数呢?
OAPageContext
OAWebBean

OAPageContext 参数有什么用处?
1. 使用 oaPageContext.getParameter() 和 oaPageContext.putParameter() 来设置获取和设置字段( field) 的值.
2. 重新导向页面到当前页面或者其他页面. 比如, oaPageContext.forwardImmediatelyToCurrentPage() 重新导向到当前页面, oaPageContext.sendRedirect(newPage) 导向到其他页面.
3. 获取 AM: oaPageContext.getRootApplicationModule(), 因为 AM 已经被附加到页面上了.
4. 写 debug 信息: oaPageContext.writeDiagnostics().
5. 从 FND 消息字典中获取信息: oaPageContext.getMessage().

OAWebBean 参数有什么用?
我们知道 webBean 对象表示了页面中的结构/层次关系. 因此用这个参数, 我们可以操作这个页面结构中的所有组件. 一旦我们获得了组件的对象( field bean or button bean), 我们就可以在 runtime 的时候用 setRendered() 等等方法来改变页面的行为.
例如:
1. OAWebBean lastName = oaWebBean.findIndexedChildRecursive("personLastName");
2. 获取一个区域的对象: OAStackLayoutBean oaStackLayoutBean = (OAStackLayoutBean) oaWebBean.findIndexedChildRecursive("stackRegionName");
3. 如上面两点所示, findIndexedChildRecursive() 方法返回的对象可以被映射到对应的 bean 对象.

问题集锦:
现在有一个页面, 里面的区域是嵌套的, 每一个区域都有自己的 CO/controller. 当页面出来的时候, 每一个 CO 中的 processRequest() 方法都会被执行吗?

回答: 会的. 内部区域的 CO 会先执行, 然后执行外部区域的 CO. 这很常见, 当你在主页面中添加一个公用区域( shared region) 的时候, 每一个公用区域都可能有自己的 CO.

MDS 页面定义会被缓存吗?
回答: 会的. 因此当在数据库中 update 了MDS, 就要重启 weblogic 服务器.
但是这对用 jDeveloper 测试页面不适用, jDeveloper 会先找本地的 XML 文件/本地MDS, 只有当本地文件系统找不到, 框架才会从数据库中去找页面定义.

热心网友 时间:2022-04-14 13:55

用以下的代码可以实现,但是有一点不足,就是当数据量比较多的时候,无法按照指定的行数进行分页显示。

先在页面上创建一个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 al \r\n");
sbfSQL.append("UNION ALL \r\n");
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.getApplicationMole(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();
}
}
}
}
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
高考560分能上211大学吗? - 知乎 河北高考多少分能上211大学 河北2023高考211分数线是多少? 考560分能上211大学吗河北 刀剑英雄合王者武器多少费用 刀剑英雄帝辰王者现在什么价位 2021年度工程施工合同范本 2021承包转让简单的合同范本 2021医院食堂承包合同范本 div+css+js实现菜单的收缩与展开 调用数据库内容的时候为什么内容字段... 沙蟹图片不吃东西可以吗? 梦见爬山又下山后东西落在山顶上 梦见跟朋友去外地玩。爬上山顶下山后看见左右供着的佛像。接着走又看见别人家供着的是死婆。纳闷 白象江边石头底下抓到的小螃蟹肚子那里都是紫色的卵能吃吗 请问这是什么螃蟹,可以吃吗 这种沙蟹可以吃吗?是不是角眼沙蟹? 奉贤海滩上的螃蟹可以吃吗 像这种江边的小螃蟹,如果抓一篮子拿去炸的话,可以吃吗?有没有细菌感染? 梦见登上山顶看日落又下山 这是什么蟹?能吃吗?怎么吃?海滩边挖的,有人说可以油炸,爆炒。有人说不能吃。 这是什么蟹?能吃吗?浙江台州沿海江边捉的! 新华通讯社社长是不是公务员 新华社湖北分社是行政还是事业单位 新华社和CCTV是什么关系? 在新华社工作是怎样一种体验 新华社归什么机构管理 新华社各省分社是什么性质的单位,工资待遇如何 新华社新华每日电讯社的行政级别是什么? 新华社的行政级别是什么一 新华社是个什么样的组织? 怎么在Windows上配置EBS R12.1.3的OAF开发环境 千山暮雪莫绍谦和童雪哪集相识的?怎么没看到? 《千山暮雪》莫绍谦和童雪浴缸激情戏在第几集? 千山暮雪中童雪是什么时候开始爱上莫绍谦的 千山暮雪 莫绍谦和童雪第一次遇见是什么时候? 千山暮雪莫绍谦和童雪回忆在几集相遇 千山暮雪里面的童雪爱的是谁 千山暮雪最后童雪爱上了绍谦了吗? 梦见追寻初恋情人和她闺蜜? mac怎么用虚拟机里的oracle 装了厨宝,下面没有插座,所以按了个接线板,然后接线板的线热热的,会有什么问题吗 厨热宝插在墙上的插座坏了,可以用移动插线板吗? AO史密斯小厨宝可以用接线板接电吗? 从一个插座处引线再装一个插座用来装小厨宝安全吗? 水池下就有一个插座,怎么同时装小厨宝和净水器呢。能差一个插线板,把厨宝和净水器插在上边吗?_百度问一问 梦到和自己的女朋友分手了然后我和他闺蜜在一起了。再然后我又后悔了。。。。我了个擦擦啊 win7系统Oracle VM VirtualBox虚拟机使用问题 梦见男友和前女友近一周老发短信 说忘不掉前女友 然后我让他们和好了我退出了 我还跟前女友的闺蜜谈了 Oracle VM VirtualBox虚拟机如何使用U盘,求详细步骤,现在插入U盘宿主机可以显示,但虚拟机里面没有。 厨房水槽下没有预留插头怎么安装小厨宝