到目前为止,已添加至 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
以下是一些有关刚才添加的代码的技术说明:
旧的搜索结果数据表在页面上仍然存在。您也可以删除该结果。
现在,当您搜索客户时,将在数据表中看到客户的全名、电子邮件地址和完整州名。该页面看起来应如下所示:
这是此教程中的最后一个练习。请继续查看教程总结。