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.type;
17  
18  import java.sql.CallableStatement;
19  import java.sql.PreparedStatement;
20  import java.sql.ResultSet;
21  import java.sql.SQLException;
22  
23  import org.apache.ibatis.executor.result.ResultMapException;
24  import org.apache.ibatis.session.Configuration;
25  
26  /**
27   * The base {@link TypeHandler} for references a generic type.
28   * <p>
29   * Important: Since 3.5.0, This class never call the {@link ResultSet#wasNull()} and {@link CallableStatement#wasNull()}
30   * method for handling the SQL {@code NULL} value. In other words, {@code null} value handling should be performed on
31   * subclass.
32   * </p>
33   *
34   * @author Clinton Begin
35   * @author Simone Tripodi
36   * @author Kzuki Shimizu
37   */
38  public abstract class BaseTypeHandler<T> extends TypeReference<T> implements TypeHandler<T> {
39  
40    /**
41     * @deprecated Since 3.5.0 - See https://github.com/mybatis/mybatis-3/issues/1203. This field will remove future.
42     */
43    @Deprecated
44    protected Configuration configuration;
45  
46    /**
47     * Sets the configuration.
48     *
49     * @param c
50     *          the new configuration
51     *
52     * @deprecated Since 3.5.0 - See https://github.com/mybatis/mybatis-3/issues/1203. This property will remove future.
53     */
54    @Deprecated
55    public void setConfiguration(Configuration c) {
56      this.configuration = c;
57    }
58  
59    @Override
60    public void setParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException {
61      if (parameter == null) {
62        if (jdbcType == null) {
63          throw new TypeException("JDBC requires that the JdbcType must be specified for all nullable parameters.");
64        }
65        try {
66          ps.setNull(i, jdbcType.TYPE_CODE);
67        } catch (SQLException e) {
68          throw new TypeException("Error setting null for parameter #" + i + " with JdbcType " + jdbcType + " . "
69              + "Try setting a different JdbcType for this parameter or a different jdbcTypeForNull configuration property. "
70              + "Cause: " + e, e);
71        }
72      } else {
73        try {
74          setNonNullParameter(ps, i, parameter, jdbcType);
75        } catch (Exception e) {
76          throw new TypeException("Error setting non null for parameter #" + i + " with JdbcType " + jdbcType + " . "
77              + "Try setting a different JdbcType for this parameter or a different configuration property. " + "Cause: "
78              + e, e);
79        }
80      }
81    }
82  
83    @Override
84    public T getResult(ResultSet rs, String columnName) throws SQLException {
85      try {
86        return getNullableResult(rs, columnName);
87      } catch (Exception e) {
88        throw new ResultMapException("Error attempting to get column '" + columnName + "' from result set.  Cause: " + e,
89            e);
90      }
91    }
92  
93    @Override
94    public T getResult(ResultSet rs, int columnIndex) throws SQLException {
95      try {
96        return getNullableResult(rs, columnIndex);
97      } catch (Exception e) {
98        throw new ResultMapException("Error attempting to get column #" + columnIndex + " from result set.  Cause: " + e,
99            e);
100     }
101   }
102 
103   @Override
104   public T getResult(CallableStatement cs, int columnIndex) throws SQLException {
105     try {
106       return getNullableResult(cs, columnIndex);
107     } catch (Exception e) {
108       throw new ResultMapException(
109           "Error attempting to get column #" + columnIndex + " from callable statement.  Cause: " + e, e);
110     }
111   }
112 
113   public abstract void setNonNullParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType)
114       throws SQLException;
115 
116   /**
117    * Gets the nullable result.
118    *
119    * @param rs
120    *          the rs
121    * @param columnName
122    *          Column name, when configuration <code>useColumnLabel</code> is <code>false</code>
123    *
124    * @return the nullable result
125    *
126    * @throws SQLException
127    *           the SQL exception
128    */
129   public abstract T getNullableResult(ResultSet rs, String columnName) throws SQLException;
130 
131   public abstract T getNullableResult(ResultSet rs, int columnIndex) throws SQLException;
132 
133   public abstract T getNullableResult(CallableStatement cs, int columnIndex) throws SQLException;
134 
135 }