RowHandler<ROW> インターフェース

com.ibm.pdq.runtime.handlers.RowHandler<ROW> インターフェースのインプリメンテーションを使用して pureQuery が SQL 照会から照会結果の各行を返す方法をカスタマイズします。
RowHandler<ROW> インターフェースは 1 つのメソッドのみ宣言します。
ROW handle (ResultSet resultSet, ROW object) throws SQLException;

照会結果の各行ごとに、pureQuery は handle() メソッドを呼び出し、行を表すオブジェクトを作成します。pureQuery は、ResultSet のカーソルを現在行に置いたまま java.sql.ResultSet のインスタンス中の照会結果をメソッドに渡します。 パラメーターのオブジェクトは NULL です。RowHandler<ROW> のインプリメンテーションを作成する場合は、このメソッドを実装して、ResultSet インスタンスのカーソルによって示された行を表すオブジェクト・タイプ <ROW> を作成し、戻します。

ResultSet オブジェクトが空であるか ResultSet オブジェクトの最後の行がすでに読み取られた場合、handle() メソッドは呼び出されません。

重要: pureQuery は handle() メソッドを呼び出す前に、ResultSet の next() メソッドを呼び出すことにより、現在行に ResultSet のカーソルを配置します。 そのため、ハンドル・メソッドは ResultSet の next() メソッドを呼び出してはいけません。

以下の例では、照会結果の各行で戻される String オブジェクトには、区切り文字で区切られている各列の一連のストリング値が含まれます。 この汎用かつ単純なハンドラーでは、入力 ResultSet オブジェクトに関する特別な知識は必要ありません。

package customHandlers;

import com.ibm.pdq.runtime.handlers.RowHandler;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;


   public class SimpleStringRowHandler implements RowHandler<String>
 {
   public SimpleStringRowHandler ()
   {
     delimiter = ", ";
   }

   public SimpleStringRowHandler (String delimiter)
   {
     this.delimiter = delimiter;
   }

   private int columnCount = -1;
   private String delimiter;
   String handle (ResultSet resultSet, java.lang.String object) throws SQLException
   {
     if (columnCount < 0)
       columnCount = resultSet.getMetaData().getColumnCount();
     StringBuffer myBuff = new StringBuffer();
     if (columnCount > 0) {
       myBuff.append(resultSet.getString(1));
       for (int ii=2; ii<=columnCount; ii++) {
         myBuff.append(delimiter);
         myBuff.append(resultSet.getString(ii)));
       }
     }
     return myBuff.toString();
   }  // handle
 }

アノテーション付きメソッドを用いた RowHandler オブジェクトの使用

RowHandler オブジェクトは、アノテーション付きメソッドに対して 3 つの方法で指定できます。

@Handler アノテーションの使用
@Select または @Update アノテーションを提供することに加えて、@Handler アノテーションをメソッドの宣言に提供します。 @Handler アノテーションでは、RowHandler インプリメンテーションのクラスを指定します。 指定するハンドラーは public な、引数なしコンストラクターでなければなりません。 pureQuery は引数なしコンストラクターを使用して、ハンドラーの単一インスタンスを作成し、そのインスタンスはアノテーション付きメソッドのすべての呼び出しによって使用されます。
例えば、SimpleStringRowHandler を使用したアノテーション付きメソッドを宣言できます。 pureQuery は引数なしコンストラクターを使用してハンドラーをインスタンス化します。つまり、列の区切り文字は ", " になります。
@Select(sql = "select * from employee where workdept = ?1.departmentNumber") 
@Handler(rowHandler = customHandlers.SimpleStringRowHandler.class) 
public Iterator<String> selectEmployeesInDepartment(DepartmentBean department);
@Handler アノテーションと RowHandlerWithParameters エレメントの使用
@Handlers アノテーションで RowHandlerWithParameters エレメントを使用すれば、 メソッドで渡された SQL ステートメント入力パラメーターにアクセスできます。 @Handler アノテーションで RowHandlerWithParameters エレメントを指定すると、 生成されたコードによって、追加パラメーター (メソッドで渡されたパラメーター値を表すオブジェクト配列) で handle( ) メソッドが呼び出されます。 基本的に、オブジェクトは、parameterHandler に渡されるオブジェクト配列と同じです (指定された場合)。

RowHandlerWithParameters 実装クラスでは、2 つの handle() メソッド (2 つの引数を持つメソッドと、3 つの引数を持つメソッド) が 提供されなければなりません。 2 つの引数のシグニチャーは空のメソッドにすることができます。

次の例では、アプリケーションに照会が含まれています。 この照会では、複数の入力パラメーターがこの照会の検索基準となります。 SELECT リストでは入力パラメーターの値は返されません。 これは、その値が入力値と同じになるためです。 ただし、作成される出力 Bean にはこれらの値が存在していなければなりません。 このアプリケーションは、RowHandler のスタイルを使用して RowHandler 内の値にアクセスできます。
@Select ("SELECT EVENT_NAME, EVENT_LOCATION FROM EVENTS" + 
    "WHERE EVENT_CODE = ? AND EVENT_DATE = ? AND EVENT_TIME = ?")  
@Handlers (rowHandlerWithParameters = com.bigtickets.eventRowHandlerWithParameters) 
List<Event> getEvents (eventCode,eventDate,eventTime);
指定された RowHandlerWithParameters クラスには、3 つのパラメーターを使用するハンドル・メソッドが含まれています。
Sql String
ResultSet
Object[]   (contains the input parameters)

このハンドル・メソッドでは、Object 配列で SQL ステートメントに渡されたパラメーターにアクセスできます。

メソッド・パラメーターの使用
代わりに、RowHandler インプリメンテーションをアノテーション付きメソッドの定義に引数として指定できます。 アプリケーションがメソッドを呼び出すとき、メソッドは、実際のインスタンスを pureQuery が使用するために提供できます。
パラメーターとして指定されたハンドラーは、@Handler アノテーションに指定されたハンドラーほど多くの制約を受けません。 例えば、パラメーターとして指定されたハンドラーは、引数付きコンストラクターを持つ必要はありません。 ただし、@Handler アノテーションを使ってハンドラーを指定すると、pureQuery はすべてのメソッド呼び出しにハンドラーの 1 つのインスタンスしか使用できません。pureQuery が実行時に行う処理は少なくなります。そのため、この @Handler アノテーションには多少のパフォーマンス上の利点があり、ハンドラーを @Handler アノテーションを使用して指定できない場合にのみ、ハンドラーをメソッド・パラメーターとして指定する必要があります。

ハンドラーをパラメーターとして指定する場合、そのパラメーターはメソッド・シグニチャーの最後のパラメーターでなければなりません。ParameterHandler と一緒に RowHandler をパラメーターとして指定する場合、これらのパラメーターはメソッド・シグニチャーの最後の 2 つのパラメーターでなければなりません。

例えば、インターフェースには SimpleStringRowHandler を使用するアノテーション付きのメソッドを定義できます。
@Select(sql = "SELECT * FROM employee where workdept = ?1.departmentNumber")
Iterator<String> selectEmployeesInDepartment(DepartmentBean department, ¥
	customHandlers.SimpleStringRowHandler rowHandler);
タブ文字で列を区切る SimpleStringRowHandler のインスタンスを指定することにより、メソッドを呼び出すことができます。
Iterator<String> employees = face.selectEmployeesInDepartment(theDepartment, new customHandlers.SimpleStringRowHandler("¥t"));
複数の RowHandler<ROW> を使用して単一のアノテーション付きメソッド宣言を使用する場合は、汎用 RowHandler<ROW> を使用するアノテーション付きメソッドをシグニチャーに定義できます。
@Select(sql = "SELECT * FROM employee where workdept = ?1.departmentNumber")
  <ROW> Iterator<ROW> selectEmployeesInDepartment(DepartmentBean department, RowHandler<ROW> rh);
その後、必要なタイプの RowHandler オブジェクトを渡すことにより、メソッドを呼び出すことができます。
Iterator<String> employees = face.selectEmployeesInDepartment(theDepartment, new customHandlers.simpleStringRowHandler("¥t"));

インライン・メソッドを用いた RowHandler オブジェクトの使用

インライン・メソッドに RowHandler を指定するには、RowHandler をパラメーターとして取るインライン・メソッドの 1 つを使用します。例えば、customHandlers.SimpleStringRowHandler という名前のカスタム RowHandler によって各行を作成し、リストに照会結果を入れる場合は、RowHandler をパラメーターとして取る com.ibm.pdq.runtime.Data.queryList(…) メソッドを呼び出すことができます。以下に例を示します。
List<EmployeeString> emp = db.queryList("select * from employee where workdept = ?1.departmentNumber",¥
     new customHandlers.SimpleStringRowHandler("¥t"), theDepartment);

フィードバック