MyBatisにおけるパラメータ処理の詳細解析:ParameterHandlerの実装

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   }

タグ: MyBatis ParameterHandler JDBC データベース パラメータバインディング

6月27日 19:59 投稿