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