1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.mybatis.spring;
17
18 import static java.lang.reflect.Proxy.newProxyInstance;
19 import static org.apache.ibatis.reflection.ExceptionUtil.unwrapThrowable;
20 import static org.mybatis.spring.SqlSessionUtils.closeSqlSession;
21 import static org.mybatis.spring.SqlSessionUtils.getSqlSession;
22 import static org.mybatis.spring.SqlSessionUtils.isSqlSessionTransactional;
23 import static org.springframework.util.Assert.notNull;
24
25 import java.lang.reflect.InvocationHandler;
26 import java.lang.reflect.Method;
27 import java.sql.Connection;
28 import java.util.List;
29 import java.util.Map;
30
31 import org.apache.ibatis.exceptions.PersistenceException;
32 import org.apache.ibatis.executor.BatchResult;
33 import org.apache.ibatis.session.Configuration;
34 import org.apache.ibatis.session.ExecutorType;
35 import org.apache.ibatis.session.ResultHandler;
36 import org.apache.ibatis.session.RowBounds;
37 import org.apache.ibatis.session.SqlSession;
38 import org.apache.ibatis.session.SqlSessionFactory;
39 import org.springframework.dao.support.PersistenceExceptionTranslator;
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76 public class SqlSessionTemplate implements SqlSession {
77
78 private final SqlSessionFactory sqlSessionFactory;
79
80 private final ExecutorType executorType;
81
82 private final SqlSession sqlSessionProxy;
83
84 private final PersistenceExceptionTranslator exceptionTranslator;
85
86
87
88
89
90
91
92 public SqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
93 this(sqlSessionFactory, sqlSessionFactory.getConfiguration().getDefaultExecutorType());
94 }
95
96
97
98
99
100
101
102
103
104
105 public SqlSessionTemplate(SqlSessionFactory sqlSessionFactory, ExecutorType executorType) {
106 this(sqlSessionFactory, executorType,
107 new MyBatisExceptionTranslator(
108 sqlSessionFactory.getConfiguration().getEnvironment().getDataSource(), true));
109 }
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125 public SqlSessionTemplate(SqlSessionFactory sqlSessionFactory, ExecutorType executorType,
126 PersistenceExceptionTranslator exceptionTranslator) {
127
128 notNull(sqlSessionFactory, "Property 'sqlSessionFactory' is required");
129 notNull(executorType, "Property 'executorType' is required");
130
131 this.sqlSessionFactory = sqlSessionFactory;
132 this.executorType = executorType;
133 this.exceptionTranslator = exceptionTranslator;
134 this.sqlSessionProxy = (SqlSession) newProxyInstance(
135 SqlSessionFactory.class.getClassLoader(),
136 new Class[] { SqlSession.class },
137 new SqlSessionInterceptor());
138 }
139
140 public SqlSessionFactory getSqlSessionFactory() {
141 return this.sqlSessionFactory;
142 }
143
144 public ExecutorType getExecutorType() {
145 return this.executorType;
146 }
147
148 public PersistenceExceptionTranslator getPersistenceExceptionTranslator() {
149 return this.exceptionTranslator;
150 }
151
152
153
154
155 @Override
156 public <T> T selectOne(String statement) {
157 return this.sqlSessionProxy.<T> selectOne(statement);
158 }
159
160
161
162
163 @Override
164 public <T> T selectOne(String statement, Object parameter) {
165 return this.sqlSessionProxy.<T> selectOne(statement, parameter);
166 }
167
168
169
170
171 @Override
172 public <K, V> Map<K, V> selectMap(String statement, String mapKey) {
173 return this.sqlSessionProxy.<K, V> selectMap(statement, mapKey);
174 }
175
176
177
178
179 @Override
180 public <K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey) {
181 return this.sqlSessionProxy.<K, V> selectMap(statement, parameter, mapKey);
182 }
183
184
185
186
187 @Override
188 public <K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey, RowBounds rowBounds) {
189 return this.sqlSessionProxy.<K, V> selectMap(statement, parameter, mapKey, rowBounds);
190 }
191
192
193
194
195 @Override
196 public <E> List<E> selectList(String statement) {
197 return this.sqlSessionProxy.<E> selectList(statement);
198 }
199
200
201
202
203 @Override
204 public <E> List<E> selectList(String statement, Object parameter) {
205 return this.sqlSessionProxy.<E> selectList(statement, parameter);
206 }
207
208
209
210
211 @Override
212 public <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds) {
213 return this.sqlSessionProxy.<E> selectList(statement, parameter, rowBounds);
214 }
215
216
217
218
219 @Override
220 public void select(String statement, ResultHandler handler) {
221 this.sqlSessionProxy.select(statement, handler);
222 }
223
224
225
226
227 @Override
228 public void select(String statement, Object parameter, ResultHandler handler) {
229 this.sqlSessionProxy.select(statement, parameter, handler);
230 }
231
232
233
234
235 @Override
236 public void select(String statement, Object parameter, RowBounds rowBounds, ResultHandler handler) {
237 this.sqlSessionProxy.select(statement, parameter, rowBounds, handler);
238 }
239
240
241
242
243 @Override
244 public int insert(String statement) {
245 return this.sqlSessionProxy.insert(statement);
246 }
247
248
249
250
251 @Override
252 public int insert(String statement, Object parameter) {
253 return this.sqlSessionProxy.insert(statement, parameter);
254 }
255
256
257
258
259 @Override
260 public int update(String statement) {
261 return this.sqlSessionProxy.update(statement);
262 }
263
264
265
266
267 @Override
268 public int update(String statement, Object parameter) {
269 return this.sqlSessionProxy.update(statement, parameter);
270 }
271
272
273
274
275 @Override
276 public int delete(String statement) {
277 return this.sqlSessionProxy.delete(statement);
278 }
279
280
281
282
283 @Override
284 public int delete(String statement, Object parameter) {
285 return this.sqlSessionProxy.delete(statement, parameter);
286 }
287
288
289
290
291 @Override
292 public <T> T getMapper(Class<T> type) {
293 return getConfiguration().getMapper(type, this);
294 }
295
296
297
298
299 @Override
300 public void commit() {
301 throw new UnsupportedOperationException("Manual commit is not allowed over a Spring managed SqlSession");
302 }
303
304
305
306
307 @Override
308 public void commit(boolean force) {
309 throw new UnsupportedOperationException("Manual commit is not allowed over a Spring managed SqlSession");
310 }
311
312
313
314
315 @Override
316 public void rollback() {
317 throw new UnsupportedOperationException("Manual rollback is not allowed over a Spring managed SqlSession");
318 }
319
320
321
322
323 @Override
324 public void rollback(boolean force) {
325 throw new UnsupportedOperationException("Manual rollback is not allowed over a Spring managed SqlSession");
326 }
327
328
329
330
331 @Override
332 public void close() {
333 throw new UnsupportedOperationException("Manual close is not allowed over a Spring managed SqlSession");
334 }
335
336
337
338
339 @Override
340 public void clearCache() {
341 this.sqlSessionProxy.clearCache();
342 }
343
344
345
346
347
348 @Override
349 public Configuration getConfiguration() {
350 return this.sqlSessionFactory.getConfiguration();
351 }
352
353
354
355
356 @Override
357 public Connection getConnection() {
358 return this.sqlSessionProxy.getConnection();
359 }
360
361
362
363
364
365
366
367 @Override
368 public List<BatchResult> flushStatements() {
369 return this.sqlSessionProxy.flushStatements();
370 }
371
372
373
374
375
376
377
378 private class SqlSessionInterceptor implements InvocationHandler {
379 @Override
380 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
381 SqlSession sqlSession = getSqlSession(
382 SqlSessionTemplate.this.sqlSessionFactory,
383 SqlSessionTemplate.this.executorType,
384 SqlSessionTemplate.this.exceptionTranslator);
385 try {
386 Object result = method.invoke(sqlSession, args);
387 if (!isSqlSessionTransactional(sqlSession, SqlSessionTemplate.this.sqlSessionFactory)) {
388
389
390 sqlSession.commit(true);
391 }
392 return result;
393 } catch (Throwable t) {
394 Throwable unwrapped = unwrapThrowable(t);
395 if (SqlSessionTemplate.this.exceptionTranslator != null && unwrapped instanceof PersistenceException) {
396
397 closeSqlSession(sqlSession, SqlSessionTemplate.this.sqlSessionFactory);
398 sqlSession = null;
399 Throwable translated = SqlSessionTemplate.this.exceptionTranslator.translateExceptionIfPossible((PersistenceException) unwrapped);
400 if (translated != null) {
401 unwrapped = translated;
402 }
403 }
404 throw unwrapped;
405 } finally {
406 if (sqlSession != null) {
407 closeSqlSession(sqlSession, SqlSessionTemplate.this.sqlSessionFactory);
408 }
409 }
410 }
411 }
412
413 }