1
2
3
4
5
6
7
8
9
10
11
12
13
14
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
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) {
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, Integer transactionTimeout) throws SQLException {
85 ErrorContext.instance().sql(boundSql.getSql());
86 Statement statement = null;
87 try {
88 statement = instantiateStatement(connection);
89 setStatementTimeout(statement, transactionTimeout);
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, Integer transactionTimeout) throws SQLException {
104 Integer queryTimeout = null;
105 if (mappedStatement.getTimeout() != null) {
106 queryTimeout = mappedStatement.getTimeout();
107 } else if (configuration.getDefaultStatementTimeout() != null) {
108 queryTimeout = configuration.getDefaultStatementTimeout();
109 }
110 if (queryTimeout != null) {
111 stmt.setQueryTimeout(queryTimeout);
112 }
113 StatementUtil.applyTransactionTimeout(stmt, queryTimeout, transactionTimeout);
114 }
115
116 protected void setFetchSize(Statement stmt) throws SQLException {
117 Integer fetchSize = mappedStatement.getFetchSize();
118 if (fetchSize != null) {
119 stmt.setFetchSize(fetchSize);
120 return;
121 }
122 Integer defaultFetchSize = configuration.getDefaultFetchSize();
123 if (defaultFetchSize != null) {
124 stmt.setFetchSize(defaultFetchSize);
125 }
126 }
127
128 protected void closeStatement(Statement statement) {
129 try {
130 if (statement != null) {
131 statement.close();
132 }
133 } catch (SQLException e) {
134
135 }
136 }
137
138 protected void generateKeys(Object parameter) {
139 KeyGenerator keyGenerator = mappedStatement.getKeyGenerator();
140 ErrorContext.instance().store();
141 keyGenerator.processBefore(executor, mappedStatement, null, parameter);
142 ErrorContext.instance().recall();
143 }
144
145 }