View Javadoc
1   /*
2    *    Copyright 2009-2023 the original author or authors.
3    *
4    *    Licensed under the Apache License, Version 2.0 (the "License");
5    *    you may not use this file except in compliance with the License.
6    *    You may obtain a copy of the License at
7    *
8    *       https://www.apache.org/licenses/LICENSE-2.0
9    *
10   *    Unless required by applicable law or agreed to in writing, software
11   *    distributed under the License is distributed on an "AS IS" BASIS,
12   *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *    See the License for the specific language governing permissions and
14   *    limitations under the License.
15   */
16  package org.apache.ibatis.scripting.defaults;
17  
18  import java.sql.PreparedStatement;
19  import java.sql.SQLException;
20  import java.util.List;
21  
22  import org.apache.ibatis.executor.ErrorContext;
23  import org.apache.ibatis.executor.parameter.ParameterHandler;
24  import org.apache.ibatis.mapping.BoundSql;
25  import org.apache.ibatis.mapping.MappedStatement;
26  import org.apache.ibatis.mapping.ParameterMapping;
27  import org.apache.ibatis.mapping.ParameterMode;
28  import org.apache.ibatis.reflection.MetaObject;
29  import org.apache.ibatis.session.Configuration;
30  import org.apache.ibatis.type.JdbcType;
31  import org.apache.ibatis.type.TypeException;
32  import org.apache.ibatis.type.TypeHandler;
33  import org.apache.ibatis.type.TypeHandlerRegistry;
34  
35  /**
36   * @author Clinton Begin
37   * @author Eduardo Macarron
38   */
39  public class DefaultParameterHandler implements ParameterHandler {
40  
41    private final TypeHandlerRegistry typeHandlerRegistry;
42  
43    private final MappedStatement mappedStatement;
44    private final Object parameterObject;
45    private final BoundSql boundSql;
46    private final Configuration configuration;
47  
48    public DefaultParameterHandler(MappedStatement mappedStatement, Object parameterObject, BoundSql boundSql) {
49      this.mappedStatement = mappedStatement;
50      this.configuration = mappedStatement.getConfiguration();
51      this.typeHandlerRegistry = mappedStatement.getConfiguration().getTypeHandlerRegistry();
52      this.parameterObject = parameterObject;
53      this.boundSql = boundSql;
54    }
55  
56    @Override
57    public Object getParameterObject() {
58      return parameterObject;
59    }
60  
61    @Override
62    public void setParameters(PreparedStatement ps) {
63      ErrorContext.instance().activity("setting parameters").object(mappedStatement.getParameterMap().getId());
64      List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
65      if (parameterMappings != null) {
66        MetaObject metaObject = null;
67        for (int i = 0; i < parameterMappings.size(); i++) {
68          ParameterMapping parameterMapping = parameterMappings.get(i);
69          if (parameterMapping.getMode() != ParameterMode.OUT) {
70            Object value;
71            String propertyName = parameterMapping.getProperty();
72            if (boundSql.hasAdditionalParameter(propertyName)) { // issue #448 ask first for additional params
73              value = boundSql.getAdditionalParameter(propertyName);
74            } else if (parameterObject == null) {
75              value = null;
76            } else if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {
77              value = parameterObject;
78            } else {
79              if (metaObject == null) {
80                metaObject = configuration.newMetaObject(parameterObject);
81              }
82              value = metaObject.getValue(propertyName);
83            }
84            TypeHandler typeHandler = parameterMapping.getTypeHandler();
85            JdbcType jdbcType = parameterMapping.getJdbcType();
86            if (value == null && jdbcType == null) {
87              jdbcType = configuration.getJdbcTypeForNull();
88            }
89            try {
90              typeHandler.setParameter(ps, i + 1, value, jdbcType);
91            } catch (TypeException | SQLException e) {
92              throw new TypeException("Could not set parameters for mapping: " + parameterMapping + ". Cause: " + e, e);
93            }
94          }
95        }
96      }
97    }
98  
99  }