ParameterHandlerインターフェースはMyBatisにおけるパラメータ処理の核となるコンポーネントであり、org.apache.ibatis.executor.parameterパッケージに位置しています。以下にそのソースコードを示します:
1 public interface ParameterHandler {
2
3 Object getParameterObject(); // パラメータオブジェクトの取得
4
5 void setParameters(PreparedStatement ps) throws SQLException; // パラメータの設定
6
7 }
このインターフェースは、パラメータの取得と設定という2つの基本的なメソッドのみで構成されています。ParameterHandlerのデフォルト実装クラスはDefaultParameterHandlerであり、その主要な実装は以下の通りです:
1 public class DefaultParameterHandler implements ParameterHandler {
2
3 private final TypeHandlerRegistry typeHandlerHandlerRegistry;
4
5 private final MappedStatement mappedStatement;
6 private final Object parameterObject;
7 private BoundSql boundSql;
8 private Configuration configuration;
9
10 public DefaultParameterHandler(MappedStatement mappedStatement, Object parameterObject, BoundSql boundSql) {
11 this.mappedStatement = mappedStatement;
12 this.configuration = mappedStatement.getConfiguration();
13 this.typeHandlerHandlerRegistry = mappedStatement.getConfiguration().getTypeHandlerRegistry();
14 this.parameterObject = parameterObject;
15 this.boundSql = boundSql;
16 }
17
18 @Override
19 public Object getParameterObject() {
20 return parameterObject;
21 }
22
23 @Override
24 public void setParameters(PreparedStatement ps) throws SQLException {
25 ErrorContext.instance().activity("setting parameters").object(mappedStatement.getParameterMap().getId());
26 List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
27
28 if (parameterMappings != null) {
29 for (int i = 0; i < parameterMappings.size(); i++) {
30 ParameterMapping paramMapping = parameterMappings.get(i);
31
32 if (paramMapping.getMode() != ParameterMode.OUT) {
33 Object paramValue;
34 String propertyName = paramMapping.getProperty();
35
36 if (boundSql.hasAdditionalParameter(propertyName)) {
37 paramValue = boundSql.getAdditionalParameter(propertyName);
38 } else if (parameterObject == null) {
39 paramValue = null;
40 } else if (typeHandlerHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {
41 paramValue = parameterObject;
42 } else {
43 MetaObject metaObject = configuration.newMetaObject(parameterObject);
44 paramValue = metaObject.getValue(propertyName);
45 }
46
47 TypeHandler typeHandler = paramMapping.getTypeHandler();
48 JdbcType jdbcType = paramMapping.getJdbcType();
49
50 if (paramValue == null && jdbcType == null) {
51 jdbcType = configuration.getJdbcTypeForNull();
52 }
53
54 try {
55 typeHandler.setParameter(ps, i + 1, paramValue, jdbcType);
56 } catch (TypeException e) {
57 throw new TypeException("パラメータ設定エラー: " + paramMapping + ". 原因: " + e, e);
58 } catch (SQLException e) {
59 throw new TypeException("パラメータ設定エラー: " + paramMapping + ". 原因: " + e, e);
60 }
61 }
62 }
63 }
64 }
65
66 }
ParameterHandlerの初期化はConfigurationクラス内で行われます。その実装コードは以下の通りです:
1 public ParameterHandler newParameterHandler(MappedStatement mappedStatement, Object parameterObject, BoundSql boundSql) {
2 ParameterHandler paramHandler = mappedStatement.getLang().createParameterHandler(mappedStatement, parameterObject, boundSql);
3 paramHandler = (ParameterHandler) interceptorChain.pluginAll(paramHandler);
4 return paramHandler;
5 }