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) 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
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 }