これまでは、Web ページに追加した各 JSF コンポーネントを単一のデータベース・テーブルのデータにバインドしてきました。複雑なリレーショナル・データベースを使用している場合には、複数のテーブルのデータを同時に処理することもできます。
この演習では、Customer テーブルと State テーブルの両方のデータが表示されるように、結果をカスタマイズします。そうすることで、顧客の名前 (Customer テーブルのデータ) と顧客の状態 (State テーブルのデータ) の両方が結果に表示されるようになります。顧客の状態は、2 文字の略語ではなく、完全な名称で表示されます。また、顧客の姓と名がフルネーム・フィールドにまとめられるように、結果を操作することもできます。結果として表示されるデータ・テーブルは次のようになります。
このようなカスタマイズ・データ・テーブルを作成するための最も簡単な方法は、このデータ・テーブル内の単一のレコードを表すカスタマイズ EGL レコードを作成してから、それらのレコードの配列を作成し、データ・テーブルにバインドすることです。この演習で作成するカスタマイズ EGL レコードには以下の 3 つのフィールドが含まれます。
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以下は、ここで追加した 2 つの EGL コードに関する技術面での注釈です。
ファイルの保管後にエラーが発生した場合には、getOneState 関数がライブラリー内の最後の end 文の前に挿入されていること、および、stateTable レコードがライブラリー内の最後の end 文の後に挿入されていることを確認してください。
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
以下は、ここで追加したコードに関する技術面での注釈です。
古い検索結果データ・テーブルは依然として表示されています。必要に応じて削除してください。
これで、顧客を検索したときに、顧客のフルネーム、電子メール・アドレス、および完全な状態名がデータ・テーブルに表示されるようになります。ページは次のようになります。

これで、このチュートリアルは終了です。チュートリアルの要約に進んでください。