到目前为止,已添加至 Web 页面的每个 JSF 组件都已被绑定至一个数据库表中的数据。如果正在使用复杂的关系数据库,则可能会希望同时使用多个表中的数据。
在此练习中,将通过同时显示来自 Customer 表和 State 表的数据来定制结果。采用这种方法,结果将同时显示客户的名字(来自 Customer 表)和客户所在州的全名而不是两个字母的缩写(来自 State 表)。还将通过把客户的名和姓合并到全名字段中来处理结果。产生的数据表看起来应如下所示:
创建此类定制数据表的最简单方法是创建表示此数据表中的单个记录的定制 EGL 记录。然后,将创建绑定至数据表的这些记录的数组。在此练习中创建的定制 EGL 记录有下列三个字段:
function getOneState(state stateTable) get state; end
Record stateTable type sqlRecord
{tableNames=[["EGL.STATETABLE"]],
keyItems=["STATE_ABBREV"] }
STATE_ABBREV char(2) {column="STATE_ABBREV", isReadOnly=no,
isNullable=no, sqlVariableLen=yes};
STATE_NAME char(20) {column="STATE_NAME", isReadOnly=no,
isNullable=yes, sqlVariableLen=yes};
end以下是一些有关刚才添加的两段 EGL 代码的技术说明:
如果在保存文件之后看到任何错误,则确保在库中最后一个 end 语句前面插入了 getOneState 函数,在库中最后一个 end 语句后面插入了 stateTable 记录。
package pagehandlers;
import data.*;
PageHandler customersearch { handleHardIOErrors = no, throwNrfEofExceptions = yes }
{view="customersearch.jsp", onPageLoadFunction="onPageLoad"}
searchTerms Customer; //Customer record (search) values
searchResults Customer[]; //Customers results rows
pagemsgRec msgRec; //pagemsgRec variable of type MsgRec
func int; //func - a flag to pass the state of the results
andOr char(3); //A char field that will be bound to the radio button group
customerStates Customer[]; //List of all states represented in the database
oneRecord customizedResult; //A single record to told one search result
allRecords customizedResult[]; //An array of records to hold all search results
counter int;
state stateTable;
Function onPageLoad()
CustomerLib.getAllCustomerStates(customerStates);
if (func == 0) //Either no rows, or 1st time into page
pagemsgRec.msg="No customer(s) found or no search criteria entered.";
End
end
function searchFunction()
func = 1; //Initialize func before calling database
searchTerms.Last_Name = searchTerms.Last_Name+"%"; //Add wildcard (%)
if (andOr == "AND")
CustomerLib.NameAndStateSearch_And(func, searchTerms.Last_Name,
searchTerms.State, searchResults); //Call search function
pagemsgRec.msg = "Customer(s) found. Search again?"; //Assign msg text
pagemsgRec.nbr = sysLib.size(searchResults); //Assign row count
else
CustomerLib.NameAndStateSearch_Or(func, searchTerms.Last_Name,
searchTerms.State, searchResults); //Call search function
pagemsgRec.msg = "Customer(s) found. Search again?"; //Assign msg text
pagemsgRec.nbr = sysLib.size(searchResults); //Get row count
end
allRecords.removeAll(); //Clear the old results so new ones can be displayed
counter = 1;
while (counter <= sysLib.size(searchResults)) //Repeat for each search result
oneRecord.fullName = searchResults[counter].First_Name //Assemble the full name
+ " " + searchResults[counter].Last_Name; //by combining the two names
oneRecord.email = searchResults[counter].email_address; //Get the email address
state.STATE_ABBREV = searchResults[counter].State; //Get the abbreviation
CustomerLib.getOneState(state); //Look up the full state name
oneRecord.stateName = state.STATE_NAME;
allRecords.appendElement(oneRecord); //Add this search result to the list
counter = counter + 1;
end
end
End
Record msgRec //Custom EGL record type definition
//used to combine numeric and string data
10 nbr int; //Integer - numeric field
10 msg char(222); //Character data
end
Record customizedResult //Custom record for search results
10 fullName char(44)
{displayName = "Full Name"};
10 email char(44)
{displayName = "Email Address"};
10 stateName char(44)
{displayName = "State"};
end
以下是一些有关刚才添加的代码的技术说明:
旧的搜索结果数据表在页面上仍然存在。您也可以删除该结果。
现在,当您搜索客户时,将在数据表中看到客户的全名、电子邮件地址和完整州名。该页面看起来应如下所示:

这是此教程中的最后一个练习。请继续查看教程总结。