View Javadoc
1   /**
2    *    Copyright 2009-2015 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    *       http://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.executor.statement;
17  
18  import java.sql.Connection;
19  import java.sql.SQLException;
20  import java.sql.Statement;
21  
22  import org.apache.ibatis.executor.ErrorContext;
23  import org.apache.ibatis.executor.Executor;
24  import org.apache.ibatis.executor.ExecutorException;
25  import org.apache.ibatis.executor.keygen.KeyGenerator;
26  import org.apache.ibatis.executor.parameter.ParameterHandler;
27  import org.apache.ibatis.executor.resultset.ResultSetHandler;
28  import org.apache.ibatis.mapping.BoundSql;
29  import org.apache.ibatis.mapping.MappedStatement;
30  import org.apache.ibatis.reflection.factory.ObjectFactory;
31  import org.apache.ibatis.session.Configuration;
32  import org.apache.ibatis.session.ResultHandler;
33  import org.apache.ibatis.session.RowBounds;
34  import org.apache.ibatis.type.TypeHandlerRegistry;
35  
36  /**
37   * @author Clinton Begin
38   */
39  public abstract class BaseStatementHandler implements StatementHandler {
40  
41    protected final Configuration configuration;
42    protected final ObjectFactory objectFactory;
43    protected final TypeHandlerRegistry typeHandlerRegistry;
44    protected final ResultSetHandler resultSetHandler;
45    protected final ParameterHandler parameterHandler;
46  
47    protected final Executor executor;
48    protected final MappedStatement mappedStatement;
49    protected final RowBounds rowBounds;
50  
51    protected BoundSql boundSql;
52  
53    protected BaseStatementHandler(Executor executor, MappedStatement mappedStatement, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
54      this.configuration = mappedStatement.getConfiguration();
55      this.executor = executor;
56      this.mappedStatement = mappedStatement;
57      this.rowBounds = rowBounds;
58  
59      this.typeHandlerRegistry = configuration.getTypeHandlerRegistry();
60      this.objectFactory = configuration.getObjectFactory();
61  
62      if (boundSql == null) { // issue #435, get the key before calculating the statement
63        generateKeys(parameterObject);
64        boundSql = mappedStatement.getBoundSql(parameterObject);
65      }
66  
67      this.boundSql = boundSql;
68  
69      this.parameterHandler = configuration.newParameterHandler(mappedStatement, parameterObject, boundSql);
70      this.resultSetHandler = configuration.newResultSetHandler(executor, mappedStatement, rowBounds, parameterHandler, resultHandler, boundSql);
71    }
72  
73    @Override
74    public BoundSql getBoundSql() {
75      return boundSql;
76    }
77  
78    @Override
79    public ParameterHandler getParameterHandler() {
80      return parameterHandler;
81    }
82  
83    @Override
84    public Statement prepare(Connection connection) throws SQLException {
85      ErrorContext.instance().sql(boundSql.getSql());
86      Statement statement = null;
87      try {
88        statement = instantiateStatement(connection);
89        setStatementTimeout(statement);
90        setFetchSize(statement);
91        return statement;
92      } catch (SQLException e) {
93        closeStatement(statement);
94        throw e;
95      } catch (Exception e) {
96        closeStatement(statement);
97        throw new ExecutorException("Error preparing statement.  Cause: " + e, e);
98      }
99    }
100 
101   protected abstract Statement instantiateStatement(Connection connection) throws SQLException;
102 
103   protected void setStatementTimeout(Statement stmt) throws SQLException {
104     Integer timeout = mappedStatement.getTimeout();
105     if (timeout != null) {
106       stmt.setQueryTimeout(timeout);
107       return;
108     }
109     Integer defaultTimeout = configuration.getDefaultStatementTimeout();
110     if (defaultTimeout != null) {
111       stmt.setQueryTimeout(defaultTimeout);
112     }
113   }
114 
115   protected void setFetchSize(Statement stmt) throws SQLException {
116     Integer fetchSize = mappedStatement.getFetchSize();
117     if (fetchSize != null) {
118       stmt.setFetchSize(fetchSize);
119       return;
120     }
121     Integer defaultFetchSize = configuration.getDefaultFetchSize();
122     if (defaultFetchSize != null) {
123       stmt.setFetchSize(defaultFetchSize);
124     }
125   }
126 
127   protected void closeStatement(Statement statement) {
128     try {
129       if (statement != null) {
130         statement.close();
131       }
132     } catch (SQLException e) {
133       //ignore
134     }
135   }
136 
137   protected void generateKeys(Object parameter) {
138     KeyGenerator keyGenerator = mappedStatement.getKeyGenerator();
139     ErrorContext.instance().store();
140     keyGenerator.processBefore(executor, mappedStatement, null, parameter);
141     ErrorContext.instance().recall();
142   }
143 
144 }