Utilisez une implémentation de l'interface com.ibm.pdq.runtime.handlers.RowHandler<ROW> pour personnaliser comment pureQuery retourne chaque ligne d'un résultat d'analyse d'une analyse SQL.
L'interface RowHandler
<ROW> ne déclare qu'une méthode :
ROW handle (ResultSet resultSet, ROW object) throws SQLException;
Pour chaque ligne d'un résultat de requête, pureQuery appelle la méthode handle() pour créer l'objet représentant la ligne. pureQuery transmet à la méthode les résultats de la requête dans une instance de java.sql.ResultSet, avec le curseur ResultSet positionné sur la ligne en cours. L'objet de paramètre possède la valeur null. Si vous créez une implémentation de RowHandler<ROW>,
implémentez cette méthode pour créer et retourner un objet de type <ROW>
représentant la ligne indiquée par le curseur de l'instance ResultSet.
Si l'objet ResultSet est vide ou que la dernière ligne de l'objet ResultSet a été lue, la méthode handle() n'est pas appelée.
Avertissement : Avant que pureQuery n'appelle la méthode handle(), pureQuery
positionne le curseur sur la ligne en cours en appelant la méthode next() de ResultSet. Par conséquent, la méthode handle ne doit pas appeler la méthode next() de ResultSet.
Dans cet exemple, l'objet String retourné pour chaque ligne dans un résultat de requête contient une série délimitée de valeurs de chaîne pour chaque colonne. Dans ce gestionnaire simple et très général, aucune connaissance précise relative à l'objet ResultSet d'entrée n'est requise.
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
}
Utilisation des objets RowHandler avec les méthodes annotées
Il existe deux manières de spécifier des objets RowHandler pour les méthodes annotées.
- Utiliser l'annotation @Handler
- Fournissez l'annotation @Handler dans la déclaration d'une méthode en complément de l'annotation @Select ou @Update. Dans l'annotation @Handler, spécifiez la classe de votre implémentation RowHandler.
Le gestionnaire spécifié doit posséder un constructeur public sans argument.
pureQuery utilise le constructeur sans argument pour créer une instance unique du gestionnaire. Cette instance est utilisée par toutes les invocations de la méthode annotée.
- Par exemple, vous pouvez déclarer une méthode annotée utilisant SimpleStringRowHandler.
pureQuery instancie le gestionnaire avec le constructeur sans argument. Le délimiteur de colonne est donc ",".
@Select(sql = "select * from employee where workdept = ?1.departmentNumber")
@Handler(rowHandler = customHandlers.SimpleStringRowHandler.class)
public Iterator<String> selectEmployeesInDepartment(DepartmentBean department);
- Utiliser les paramètres de méthode
- Vous pouvez sinon spécifier l'implémentation RowHandler en tant qu'argument dans la définition de méthode annotée. Lorsque votre application appelle la méthode, elle peut fournir l'instance réelle à utiliser par pureQuery.
- Les gestionnaires spécifiés en tant que paramètres ne sont pas sujets à autant de restrictions que celles spécifiées dans l'annotation @Handler.
Par exemple, il n'est pas nécessaire que les gestionnaires spécifiés en tant que paramètres possèdent un constructeur sans argument. Toutefois, la spécification de gestionnaires avec l'annotation @Handler oblige pureQuery à utiliser une seule instance de gestionnaire pour toutes les invocations de la méthode et à travailler moins au moment de l'exécution. Par conséquent, l'annotation @Handler procure un léger avantage en matière de performances. Vous devez donc spécifier les gestionnaires en tant que paramètres de méthode uniquement lorsque vous ne pouvez pas les spécifier à l'aide de l'annotation @Handler.
Lorsque vous spécifiez un gestionnaire comme paramètre, le paramètre doit être le dernier paramètre de la signature de méthode. Si vous spécifiez RowHandler
avec ParameterHandler comme paramètres, les gestionnaires doivent être les deux derniers paramètres de la signature de la méthode.
Par exemple, vous pouvez définir dans une interface une méthode annotée utilisant SimpleStringRowHandler:
@Select(sql = "SELECT * FROM employee where workdept = ?1.departmentNumber")
Iterator<String> selectEmployeesInDepartment(DepartmentBean department, \
customHandlers.SimpleStringRowHandler rowHandler);
Vous pouvez appeler la méthode en spécifiant une instance de SimpleStringRowHandler
délimitant les colonnes avec un caractère de tabulation :
Iterator<String> employees = face.selectEmployeesInDepartment(theDepartment, new customHandlers.SimpleStringRowHandler("\t"));
Si vous souhaitez utiliser une déclaration de méthode annotée unique de plusieurs implémentations RowHandler<ROW>, vous pouvez définir une méthode annotée utilisant l'objet RowHandler<ROW> générique dans la signature :
@Select(sql = "SELECT * FROM employee where workdept = ?1.departmentNumber")
<ROW> Iterator<ROW> selectEmployeesInDepartment(DepartmentBean department, RowHandler<ROW> rh);
Vous pouvez ensuite invoquer la méthode en transmettant un objet RowHandler du type requis :
Iterator<String> employees = face.selectEmployeesInDepartment(theDepartment, new customHandlers.simpleStringRowHandler("\t"));
Utilisation des objets RowHandler
avec les méthodes intégrées
Pour spécifier un objet RowHandler pour une méthode intégrée, utilisez l'une des méthodes intégrées prenant un objet RowHandler comme paramètre. Par exemple, si vous souhaitez que les résultats d'une requête figurent dans une liste, avec chaque ligne créée par un objet
RowHandler personnalisé nommé customHandlers.SimpleStringRowHandler, vous pouvez appeler une méthode com.ibm.pdq.runtime.Data.queryList(…) prenant un objet RowHandler comme paramètre, tel que cela est présenté dans cet exemple :
List<EmployeeString> emp = db.queryList("select * from employee where workdept = ?1.departmentNumber",\
new customHandlers.SimpleStringRowHandler("\t"), theDepartment);