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