ParameterHandler<T> 인터페이스에는 handleParameters()라는 한 가지 메소드만 있습니다. 이 메소드를 호출할 때 pureQuery는 어노테이션이 있는 메소드에 전달한 매개변수와 함께 PreparedStatement 오브젝트를 전달합니다. 이 오브젝트는 SQL문을 실행하는 데 사용되었습니다.
ParameterHandler<T> 오브젝트를 사용하여 SQL문의 매개변수 값을 설정하고 모든 OUT 또는 INOUT 매개변수를 등록하십시오. java.sql.PreparedStatement 인터페이스에 대한 정보는 사용자의 Java™ SDK에 대한 Javadoc을 참조하십시오.
이 예제의 용도는 코드의 주석에 설명되어 있습니다.
package com.samplePackage; import java.sql.CallableStatement; import java.sql.PreparedStatement; import java.sql.SQLException; import java.sql.Types; import com.ibm.pdq.runtime.generator.ParameterHandler; // This is an example of a custom ParameterHandler that: // (1) validates a method parameter, and // (2) processes a method parameter // before setting the method parameter as a statement parameter. This custom // ParameterHandler also // (3) Sets one of the statement parameters with a hard-coded value. // // This first statement parameter is bonusFactor. The value set is a number between // 1 and 2. The value passed in as a method parameter is between 100% and 200%. // Therefore, the parameter handler verifies that the passed-in value is between // 100 and 200, and it divides the value by 100 before setting it as the statement // parameter bonusFactor. // // The second statement parameter is bonusMaxSumForDept. This is set with a value // that is hard-coded in the parameter handler -- $20,000.00 . public class BonusIncreaseParameterHandler implements ParameterHandler { // ?1 is the return value // The IN parameter ?2 is set from the passed-in method parameter newBonusPercentageOfOldBonus // The IN parameter ?3 is set from a fixed number in the ParameterHandler // There are four OUT parameters to the SQL call statement: // (1) ?4 => deptsWithoutNewBonuses // (2) ?5 => countDeptsViewed // (3) ?6 => countDeptsBonusChanged // (5) ?7 => errorMsg public void handleParameters (PreparedStatement stmt, Object... parameters) throws SQLException { CallableStatement cstmt = (CallableStatement) stmt; double newBonusPercentageOfOldBonus = (Double) parameters[1]; // Verify that the value of the parameter is reasonable if (100 > newBonusPercentageOfOldBonus || 200 < newBonusPercentageOfOldBonus) { throw new RuntimeException ( "The bonusFactorPercentage must be between 100 and 200 inclusive. The new bonus will be this percentage of the old bonus. (So, for example, if bonusFactorPercentage=100, then the bonus will not change.)"); } // Calculate the bonusFactor to set in cstmt double bonusFactor = newBonusPercentageOfOldBonus / 100.0; // The value for this cstmt parameter is fixed double bonusMaxSumForDept = 20000.00; // Register OUT parameters and set IN parameters cstmt.registerOutParameter (1, Types.INTEGER); stmt.setDouble (2, bonusFactor); stmt.setDouble (3, bonusMaxSumForDept); cstmt.registerOutParameter (4, Types.VARCHAR); cstmt.registerOutParameter (5, Types.INTEGER); cstmt.registerOutParameter (6, Types.INTEGER); cstmt.registerOutParameter (7, Types.VARCHAR); } }
이 예제의 용도는 코드의 주석에 설명되어 있습니다.
package com.samplePackage; import java.sql.PreparedStatement; import java.sql.SQLException; import com.ibm.pdq.runtime.generator.ParameterHandler; // This is an example of a custom ParameterHandler that enables a "legacy" user // bean to be used un-changed. See the CustomDepartment class for details about the // bean implementation and why it is being used un-changed. public class CustomDepartmentParameterHandler implements ParameterHandler { public void handleParameters (PreparedStatement stmt, Object... parameters) throws SQLException { CustomDepartment department = (CustomDepartment) parameters[0]; stmt.setString (1, department.getDepartmentCode ()); } }
CustomDepartment Bean의 정의는 다음과 같습니다.
package com.samplePackage; // This is an example of a "legacy" bean that a theoretical user might not want // to modify. Changes he would need to make to make this bean compliant: // (1) Either change the property names, add @Column, or add @ColumnOverride to // enable the properties to be mapped to the columns. // (2) Add setters corresponding to the included getters. // // Change (1) Would be a simple modification -- but if the user has lots of beans // like this, or if he has legacy code that he cannot modify, then he could use a // ParameterHandler instead. // // Change (2) could potentially require significant changes to the user's design // architecture. For example, in this particular case, it may be that the user // only wants to allow changes to departmentName and departmentCode when both // are changed together. Therefore, he has a changeDepartment(String,String) method, // but no setDepartmentName(String) or setDepartmentCode(String) methods. A custom // ParameterHandler would allow the user to still use this bean as-is. public class CustomDepartment { private String departmentName; private String departmentCode; // Other properties public CustomDepartment (String departmentName, String departmentCode) { this.departmentName = departmentName; this.departmentCode = departmentCode; } public void changeDepartment (String departmentName, String departmentCode) { this.departmentName = departmentName; this.departmentCode = departmentCode; } public String getDepartmentName () { return departmentName; } public String getDepartmentCode () { return departmentCode; } // Other methods }
이 예제의 용도는 코드의 주석에 설명되어 있습니다.
package com.samplePackage; import java.sql.PreparedStatement; import java.sql.SQLException; import com.ibm.pdq.runtime.generator.ParameterHandler; // This is an example of a custom parameter handler in which the SQL parameters // are not set based on values already available in the method parameters. In // this case, the project length is calcuated by multiplying a value of a property // from the ProjectLevel parameter with a value of a property from the AdefUser // parameter. public class ProjectLevelParameterHandler implements ParameterHandler { public void handleParameters (PreparedStatement stmt, Object... parameters) throws SQLException { System.out.println("CDS in parameter handler"); ProjectLevel projectLevel = (ProjectLevel) parameters[0]; AdefUser adefUser = (AdefUser) parameters[1]; int numberOfEmployees = adefUser.getNumberOfEmloyees (); double lengthInDays = projectLevel.getMinimumProjectLengthInDaysPerDepartmentMember () * numberOfEmployees; String workDepartment = adefUser.getWorkDept (); System.out.println("CDS trying to set parameters"); stmt.setDouble (1, numberOfEmployees); stmt.setDouble (2, lengthInDays); stmt.setString (3, workDepartment); } }
AdefUser Bean의 정의는 다음과 같습니다.
package com.samplePackage; import com.ibm.pdq.annotation.Column; public class AdefUser { private String workDept; private int numberOfEmloyees; public AdefUser (String workDept, int numberOfEmployees) { this.workDept = workDept; this.numberOfEmloyees = numberOfEmployees; } @Column(name="no_of_employees") public int getNumberOfEmloyees () { return numberOfEmloyees; } public void setNumberOfEmloyees (int numberOfEmloyees) { this.numberOfEmloyees = numberOfEmloyees; } public String getWorkDept () { return workDept; } public void setWorkDept (String workDept) { this.workDept = workDept; } }
ProjectLevel Bean의 정의는 다음과 같습니다.
package com.samplePackage; public class ProjectLevel { private int projectLevel; private double minimumProjectLengthInDaysPerDepartmentMember; public ProjectLevel(int projectLevel, double minimumProjectLengthInDaysPerDepartmentMember) { this.projectLevel = projectLevel; this.minimumProjectLengthInDaysPerDepartmentMember = minimumProjectLengthInDaysPerDepartmentMember; } public double getMinimumProjectLengthInDaysPerDepartmentMember () { return minimumProjectLengthInDaysPerDepartmentMember; } public void setMinimumProjectLengthInDaysPerDepartmentMember (double minimumProjectLengthInDaysPerDepartmentMember) { this.minimumProjectLengthInDaysPerDepartmentMember = minimumProjectLengthInDaysPerDepartmentMember; } public int getProjectLevel () { return projectLevel; } public void setProjectLevel (int projectLevel) { this.projectLevel = projectLevel; } }