これまでは、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 state 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
以下は、ここで追加したコードに関する技術面での注釈です。
古い検索結果データ・テーブルは依然として表示されています。必要に応じて削除してください。
これで、顧客を検索したときに、顧客のフルネーム、電子メール・アドレス、および完全な状態名がデータ・テーブルに表示されるようになります。ページは次のようになります。
これで、このチュートリアルは終了です。チュートリアルの要約に進んでください。