public T handle (ResultSet resultSet);
pureQuery は handle() メソッドを呼び出し、行を表すオブジェクトを作成します。pureQuery は照会結果を java.sql.ResultSet のインスタンスのメソッドに渡します。ResultHandler<RES> のインプリメンテーションを作成する場合は、このメソッドを実装して、ResultSet インスタンスの照会結果を表すオブジェクト・タイプ <RES> を作成し、戻します。
ハンドラーをパラメーターとして指定する場合、そのパラメーターはメソッド・シグニチャーの最後のパラメーターでなければなりません。ParameterHandler と一緒に ResultHandler をパラメーターとして指定する場合、これらのパラメーターはメソッド・シグニチャーの最後の 2 つのパラメーターでなければなりません。
データ・ソースを照会するアプリケーションが照会結果全体を String オブジェクトとして他のアプリケーションに送信するとします。他方のアプリケーションは、String に一連のオブジェクトが JSON 形式で含まれていることを期待します。ResultHandler<RES> インターフェースの handle() メソッドを使用すると、オブジェクトの配列を表す単一の JSON ストリングに照会結果を変換できます。
package customHandlers; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import com.ibm.pdq.runtime.handlers.ResultHandler; public class JSONResultHandler implements ResultHandler<String> { // The ResultHandler<RES> interface defines this method public String handle (ResultSet rs) { StringBuffer stringBuffer = new StringBuffer (); try { ResultSetMetaData resultSetMetaData = rs.getMetaData (); int columnCount = resultSetMetaData.getColumnCount (); boolean first = true; stringBuffer.append ("["); while (rs.next ()) { // すべての行オブジェクト (最後のものは除く) の後には "," が続きます。 if (!first) stringBuffer.append (","); first = false; stringBuffer.append ("{"); for (int x = 1; x <= columnCount; x++) { stringBuffer.append ("¥""); stringBuffer.append (toJSONString (resultSetMetaData.getColumnLabel (x))); stringBuffer.append ("¥":¥""); stringBuffer.append (toJSONString (rs.getString (x))); stringBuffer.append ("¥""); if (x < columnCount) stringBuffer.append (","); } stringBuffer.append ("}"); } stringBuffer.append ("]"); } catch (SQLException e) { throw new RuntimeException ("The JSONResultHandler failed to create a JSON string from the query results.", e); } return stringBuffer.toString (); } private String toJSONString (String value) { if (value != null) { int valueLength = value.length (); StringBuffer sb = new StringBuffer (valueLength); for (int i = 0; i < valueLength; i++) { char c = value.charAt (i); switch (c) { case '¥¥': sb.append ("¥¥¥¥"); break; case '"': sb.append ("¥¥¥""); break; case '/': sb.append ("¥¥/"); break; case 0x08: sb.append ("¥¥b"); break; case 0xC: sb.append ("¥¥f"); break; case 0xA: sb.append ("¥¥n"); break; case 0xD: sb.append ("¥¥r"); break; case 0x9: sb.append ("¥¥t"); break; default: sb.append (c); break; } } return sb.toString (); } else return null; } }
以下は、JSONResultHandler が生成できる JSON ストリングの例です。
[{"DEPTNO":"A00","DEPTNAME":"SPIFFY COMPUTER SERVICE DIV.","MGRNO":"000010","ADMRDEPT":"A00","LOCATION":"null"}, {"DEPTNO":"B01","DEPTNAME":"PLANNING","MGRNO":"000020", "ADMRDEPT":"A00","LOCATION":"null"},...]
アノテーション付きメソッドを使用するために ResultHandler オブジェクトを指定するには 2 つの方法があります。
@Select(sql = “select * from employee where workdept = ?1.departmentNumber") @Handler(resultHandler = customHandlers.JSONResultHandler.class) String toJSON(DepartmentBean department);
ハンドラーをパラメーターとして指定する場合、そのパラメーターはメソッド・シグニチャーの最後のパラメーターでなければなりません。
例えば、Iterator<EmployeeBean> に照会結果を取得し、Iterator<EmployeeBean> が照会結果の 11 行目から 20 行目のみ含むようにするとします。com.ibm.pdq.runtime.data.handlers.IteratorPagingResultHandler<RES> を使用します。 インターフェースには、IteratorPagingResultHandler<RES> のインスタンスをパラメーターとして取るアノテーション付きメソッドを定義できます。
@Select(sql = "select * from employee where workdept = ?1.departmentNumber") Iterator<EmployeeBean> selectEmployeesInDepartment(DepartmentBean department, IteratorPagingResultHandler resultHandler);
結果の 11 行目から 20 行目を含むようにする場合は、以下のようにメソッドを呼び出します。
//照会を実行して 11 から 20 行目のイテレーターを作成する Iterator<EmployeeBean> employees = face.selectEmployeesInDepartment(theDepartment, new IteratorPagingResultHandler(EmployeeBean.class, 11, 20));
複数の ResultHandler<RES> インプリメンテーションを使用して単一のアノテーション付きメソッド宣言を使用する場合は、汎用 ResultHandler<RES> を使用するアノテーション付きメソッドをシグニチャーに定義できます。
@Select(sql = "select * from employee where workdept = ?1.departmentNumber") <RES> RES selectEmployeesInDepartment(DepartmentBean department, ResultHandler<RES> resultHandler);
その後、特定のタイプの ResultHandler オブジェクトを渡すことにより、メソッドを呼び出すことができます。
Iterator<EmployeeBean> employee = face.selectEmployeesInDepartment(theDepartment, new IteratorPagingResultHandler(EmployeeBean.class, 11, 20));
Connection con = DriverManager.getConnection(...); Data d = DataFactory.getData(con); //照会を実行して 11 から 20 行目のイテレーターを作成する Iterator<EmployeeBean> employees = d.query("select * from employee where workdept = ?1.departmentNumber", theDepartment, new IteratorPagingResultHandler(EmployeeBean.class,11, 20));