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     Integer defaultTimeout = configuration.getDefaultStatementTimeout();
106     if (timeout != null) {
107       stmt.setQueryTimeout(timeout);
108     } else if (defaultTimeout != null) {
109       stmt.setQueryTimeout(defaultTimeout);
110     }
111   }
112 
113   protected void setFetchSize(Statement stmt) throws SQLException {
114     Integer fetchSize = mappedStatement.getFetchSize();
115     if (fetchSize != null) {
116       stmt.setFetchSize(fetchSize);
117       return;
118     }
119     Integer defaultFetchSize = configuration.getDefaultFetchSize();
120     if (defaultFetchSize != null) {
121       stmt.setFetchSize(defaultFetchSize);
122     }
123   }
124 
125   protected void closeStatement(Statement statement) {
126     try {
127       if (statement != null) {
128         statement.close();
129       }
130     } catch (SQLException e) {
131       //ignore
132     }
133   }
134 
135   protected void generateKeys(Object parameter) {
136     KeyGenerator keyGenerator = mappedStatement.getKeyGenerator();
137     ErrorContext.instance().store();
138     keyGenerator.processBefore(executor, mappedStatement, null, parameter);
139     ErrorContext.instance().recall();
140   }
141 
142 }