com.ibm.pdq.runtime.handlers
Interface ParameterHandler
public interface ParameterHandlerSets the values of the parameters in the
PreparedStatement stmt
from the values in the passed-in
parameters
and registers any OUT or INOUT parameters.
pureQuery has a standard algorithm that it uses to set the values of the parameters in an SQL statement based on the
parameters to the method executing the statement. This algorithm also registers OUT and INOUT parameters in SQL
stored procedure calls. When another procedure for setting or registering the SQL parameters is required, an
implementation of ParameterHandler
can be specified.
The following examples show some situations in which it would be helpful to use a custom
ParameterHandler
implementation:
- Existing beans need to be used without modification for the parameters, and the beans do not follow the rules for pureQuery beans. For example, an existing bean might have unmatched getters or setters.
- The parameters need to be modified before they can be set in the
PreparedStatement
. - The input parameters must be validated before being set in the
PreparedStatement
. - One or more of the
PreparedStatement
parameters must be set by something other than a passed-in parameter. For example, a value could be hard-coded in aParameterHandler
implementation. - A more complex property-to-parameter mapping needs to be performed than is provided by the pureQuery default behavior.
ParameterHandler
implementation can be specified for annotated methods in one of two ways.
- An implementation that can be instantiated by using a public no-argument constructor can be specified by using
the
@Handler(parameterHandler=...)
annotation. In this approach, pureQuery creates a single instance of the implementation, and uses that instance every time the annotated method is invoked. - An implementation can be specified as a parameter in an annotated method declaration. An instance of the
implementation is then passed as an argument to the method at runtime. This approach should be used only when
necessary because performance is slightly better when handlers are specified by using the
@Handler(parameterHandler=...)
annotation. When one or more handlers are provided as parameters to an annotated method, the handlers must be the last parameters to the method.
When a ParameterHandler
implementation is specified, pureQuery does not use the standard pureQuery
algorithm for setting and registering the parameters. Instead, pureQuery calls the handleParameters(PreparedStatement stmt, Object...)
method of the specified implementation to set the method
parameters into the PreparedStatement stmt
of the SQL string and to register any OUT and INOUT
parameters.
Example of creating a ParameterHandler
implementation
The following example demonstrates the basic syntax for creating a very simple ParameterHandler<T>
implementation. Notice that this class has two constructors: one that takes no arguments and one that takes one
argument. CustomDepartmentParameterHandler
stores a list of allowed department numbers. Its
handleParameters (PreparedStatement stmt, Object... paramters)
method expects that
parameters[0]
is an instance of DepartmentBean
. handleParameters
verifies that the department number in the DepartmentBean
instance is one of the allowed numbers, and
then it sets the value of the first parameter of the SQL statement to that number.
public class CustomDepartmentParameterHandler implements ParameterHandler {
private final List<String> validDepartments;
public CustomDepartmentParameterHandler () {
validDepartments = Arrays.asList (new String[] { "A00", "B01", "C01", "D01", "D11", "D21", "E01", "E11", "E21" });
}
public CustomDepartmentParameterHandler (List<String> validDepartments) {
this.validDepartments = validDepartments;
}
public void handleParameters (PreparedStatement stmt, Object... parameters) throws SQLException {
String number = ((DepartmentBean) parameters[0]).getDepartmentNumber ();
if (!validDepartments.contains (number))
throw new RuntimeException ("The department number \"" + number + "\" is not allowed.");
stmt.setString (1, number);
}
}
Examples of specifying a ParameterHandler
implementation for annotated methods
The following two examples demonstrate the basic syntax for specifying the created ParameterHandler
implementation for an annotated method. The two examples assume that the annotated methods are declared in an
interface named SampleInterfaceData
. In the first example, the list of valid departments used by the
no-argument constructor is needed. Since the handler is instantiated with a no-argument constructor, the handler is
specified in the @Handler(parameterHandler=...)
annotation. The annotated method could be declared
in an interface like this:
@Select(sql = "select * from employee where workdept = ?")
@Handler(parameterHandler = CustomDepartmentParameterHandler.class)
public Iterator<EmployeeBean> selectEmployeesInDepartment (DepartmentBean department);
Then, after the pureQuery Generator is used to generate the implementation class for the interface, the method could be invoked like this:
Connection connection = DriverManager.getConnection (...);
SampleInterfaceData sampleInterfaceData = DataFactory.getData (SampleInterfaceData.class, connection);
DepartmentBean department = ...;
Iterator<EmployeeBean> employees = sampleInterfaceData.selectEmployeesInDepartment (department);
In the next example, the list of allowed departments needs to be specified at runtime, so the implementation must be instantiated with a constructor that takes an argument. As a result, the handler is specified as a parameter to the annotated method. The annotated method could be declared in an interface like this:
@Select(sql = "select * from employee where workdept = ?")
public Iterator<EmployeeBean> selectEmployeesInDepartment (DepartmentBean department, CustomDepartmentParameterHandler parameterHandler);
Then, after the pureQuery Generator is used to generate the implementation class for the interface, the method could
be invoked with an instance of CustomDepartmentParameterHandler
like this:
Connection connection = DriverManager.getConnection (...);
SampleInterfaceData sampleInterfaceData = DataFactory.getData (SampleInterfaceData.class, connection);
List<String> validDepartments = Arrays.asList (new String[] { "A00", "B01", "C01", "D01", "E01" });
CustomDepartmentParameterHandler handler = new CustomDepartmentParameterHandler (validDepartments);
DepartmentBean department = ...;
Iterator<EmployeeBean> employees = sampleInterfaceData.selectEmployeesInDepartment (department, handler);
Method Summary
Modifier and Type | Method and Description |
---|---|
|
handleParameters(PreparedStatement stmt,Object... parameters)
Registers any OUT or INOUT parameters and sets the values of the IN and INOUT parameters in the
PreparedStatement stmt from the values in the passed-in parameters .
|
Method Detail
handleParameters
void handleParameters(PreparedStatement stmt, Object... parameters) throws SQLException
stmt
- the PreparedStatement
of the SQL. stmt
is passed to the data source later
for execution. In this method, the values of the stmt
parameters must be set, probably from
the values in parameters
. Additionally, any OUT and INOUT parameters that
stmt
has must be registered. parameters
- the parameters that were passed to the associated annotated method
PreparedStatement stmt
from the values in the passed-inparameters
.