1
2
3
4
5
6
7 package org.springframework.orm.ibatis;
8
9 import com.ibatis.sqlmap.client.SqlMapClient;
10 import com.ibatis.sqlmap.client.SqlMapExecutor;
11 import com.ibatis.sqlmap.client.SqlMapSession;
12 import com.ibatis.sqlmap.client.event.RowHandler;
13
14 import java.sql.Connection;
15 import java.sql.SQLException;
16 import java.util.List;
17 import java.util.Map;
18
19 import javax.sql.DataSource;
20
21 import org.springframework.dao.DataAccessException;
22 import org.springframework.jdbc.CannotGetJdbcConnectionException;
23 import org.springframework.jdbc.JdbcUpdateAffectedIncorrectNumberOfRowsException;
24 import org.springframework.jdbc.datasource.DataSourceUtils;
25 import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy;
26 import org.springframework.jdbc.support.JdbcAccessor;
27 import org.springframework.util.Assert;
28
29
30
31
32
33
34
35
36
37
38
39
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 @Deprecated
76 @SuppressWarnings("rawtypes")
77 public class SqlMapClientTemplate extends JdbcAccessor implements SqlMapClientOperations {
78
79 private SqlMapClient sqlMapClient;
80
81
82
83
84 public SqlMapClientTemplate() {
85 }
86
87
88
89
90
91
92
93 public SqlMapClientTemplate(SqlMapClient sqlMapClient) {
94 setSqlMapClient(sqlMapClient);
95 afterPropertiesSet();
96 }
97
98
99
100
101
102
103
104
105
106 public SqlMapClientTemplate(DataSource dataSource, SqlMapClient sqlMapClient) {
107 setDataSource(dataSource);
108 setSqlMapClient(sqlMapClient);
109 afterPropertiesSet();
110 }
111
112
113
114
115
116
117
118 public void setSqlMapClient(SqlMapClient sqlMapClient) {
119 this.sqlMapClient = sqlMapClient;
120 }
121
122
123
124
125
126
127 public SqlMapClient getSqlMapClient() {
128 return this.sqlMapClient;
129 }
130
131
132
133
134
135
136 @Override
137 public DataSource getDataSource() {
138 DataSource ds = super.getDataSource();
139 return (ds != null ? ds : this.sqlMapClient.getDataSource());
140 }
141
142 @Override
143 public void afterPropertiesSet() {
144 if (this.sqlMapClient == null) {
145 throw new IllegalArgumentException("Property 'sqlMapClient' is required");
146 }
147 super.afterPropertiesSet();
148 }
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163 public <T> T execute(SqlMapClientCallback<T> action) throws DataAccessException {
164 Assert.notNull(action, "Callback object must not be null");
165 Assert.notNull(this.sqlMapClient, "No SqlMapClient specified");
166
167
168
169
170
171
172
173
174 SqlMapSession session = this.sqlMapClient.openSession();
175 if (logger.isDebugEnabled()) {
176 logger.debug("Opened SqlMapSession [" + session + "] for iBATIS operation");
177 }
178 Connection ibatisCon = null;
179
180 try {
181 Connection springCon = null;
182 DataSource dataSource = getDataSource();
183 boolean transactionAware = (dataSource instanceof TransactionAwareDataSourceProxy);
184
185
186 try {
187 ibatisCon = session.getCurrentConnection();
188 if (ibatisCon == null) {
189 springCon = (transactionAware ? dataSource.getConnection() : DataSourceUtils.doGetConnection(dataSource));
190 session.setUserConnection(springCon);
191 if (logger.isDebugEnabled()) {
192 logger.debug("Obtained JDBC Connection [" + springCon + "] for iBATIS operation");
193 }
194 } else {
195 if (logger.isDebugEnabled()) {
196 logger.debug("Reusing JDBC Connection [" + ibatisCon + "] for iBATIS operation");
197 }
198 }
199 } catch (SQLException ex) {
200 throw new CannotGetJdbcConnectionException("Could not get JDBC Connection", ex);
201 }
202
203
204 try {
205 return action.doInSqlMapClient(session);
206 } catch (SQLException ex) {
207 throw getExceptionTranslator().translate("SqlMapClient operation", null, ex);
208 } finally {
209 try {
210 if (springCon != null) {
211 if (transactionAware) {
212 springCon.close();
213 } else {
214 DataSourceUtils.doReleaseConnection(springCon, dataSource);
215 }
216 }
217 } catch (Throwable ex) {
218 logger.debug("Could not close JDBC Connection", ex);
219 }
220 }
221
222
223 } finally {
224
225
226 if (ibatisCon == null) {
227 session.close();
228 }
229 }
230 }
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245 @Deprecated
246 public List executeWithListResult(SqlMapClientCallback<List> action) throws DataAccessException {
247 return execute(action);
248 }
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263 @Deprecated
264 public Map executeWithMapResult(SqlMapClientCallback<Map> action) throws DataAccessException {
265 return execute(action);
266 }
267
268 @Override
269 public Object queryForObject(String statementName) throws DataAccessException {
270 return queryForObject(statementName, null);
271 }
272
273 @Override
274 public Object queryForObject(final String statementName, final Object parameterObject) throws DataAccessException {
275 return execute(executor -> executor.queryForObject(statementName, parameterObject));
276 }
277
278 @Override
279 public Object queryForObject(final String statementName, final Object parameterObject, final Object resultObject)
280 throws DataAccessException {
281 return execute(executor -> executor.queryForObject(statementName, parameterObject, resultObject));
282 }
283
284 @Override
285 public List queryForList(String statementName) throws DataAccessException {
286 return queryForList(statementName, null);
287 }
288
289 @Override
290 public List queryForList(final String statementName, final Object parameterObject) throws DataAccessException {
291 return execute(executor -> executor.queryForList(statementName, parameterObject));
292 }
293
294 @Override
295 public List queryForList(String statementName, int skipResults, int maxResults) throws DataAccessException {
296 return queryForList(statementName, null, skipResults, maxResults);
297 }
298
299 @Override
300 public List queryForList(final String statementName, final Object parameterObject, final int skipResults,
301 final int maxResults) throws DataAccessException {
302 return execute(executor -> executor.queryForList(statementName, parameterObject, skipResults, maxResults));
303 }
304
305 @Override
306 public void queryWithRowHandler(String statementName, RowHandler rowHandler) throws DataAccessException {
307 queryWithRowHandler(statementName, null, rowHandler);
308 }
309
310 @Override
311 public void queryWithRowHandler(final String statementName, final Object parameterObject, final RowHandler rowHandler)
312 throws DataAccessException {
313 execute(executor -> {
314 executor.queryWithRowHandler(statementName, parameterObject, rowHandler);
315 return null;
316 });
317 }
318
319 @Override
320 public Map queryForMap(final String statementName, final Object parameterObject, final String keyProperty)
321 throws DataAccessException {
322 return execute(executor -> executor.queryForMap(statementName, parameterObject, keyProperty));
323 }
324
325 @Override
326 public Map queryForMap(final String statementName, final Object parameterObject, final String keyProperty,
327 final String valueProperty) throws DataAccessException {
328 return execute(executor -> executor.queryForMap(statementName, parameterObject, keyProperty, valueProperty));
329 }
330
331 @Override
332 public Object insert(String statementName) throws DataAccessException {
333 return insert(statementName, null);
334 }
335
336 @Override
337 public Object insert(final String statementName, final Object parameterObject) throws DataAccessException {
338 return execute(executor -> executor.insert(statementName, parameterObject));
339 }
340
341 @Override
342 public int update(String statementName) throws DataAccessException {
343 return update(statementName, null);
344 }
345
346 @Override
347 public int update(final String statementName, final Object parameterObject) throws DataAccessException {
348 Integer result = execute(executor -> executor.update(statementName, parameterObject));
349 return (result != null ? result : 0);
350 }
351
352 @Override
353 public void update(String statementName, Object parameterObject, int requiredRowsAffected)
354 throws DataAccessException {
355 int actualRowsAffected = update(statementName, parameterObject);
356 if (actualRowsAffected != requiredRowsAffected) {
357 throw new JdbcUpdateAffectedIncorrectNumberOfRowsException(statementName, requiredRowsAffected,
358 actualRowsAffected);
359 }
360 }
361
362 @Override
363 public int delete(String statementName) throws DataAccessException {
364 return delete(statementName, null);
365 }
366
367 @Override
368 public int delete(final String statementName, final Object parameterObject) throws DataAccessException {
369 Integer result = execute(executor -> executor.delete(statementName, parameterObject));
370 return (result != null ? result : 0);
371 }
372
373 @Override
374 public void delete(String statementName, Object parameterObject, int requiredRowsAffected)
375 throws DataAccessException {
376 int actualRowsAffected = delete(statementName, parameterObject);
377 if (actualRowsAffected != requiredRowsAffected) {
378 throw new JdbcUpdateAffectedIncorrectNumberOfRowsException(statementName, requiredRowsAffected,
379 actualRowsAffected);
380 }
381 }
382
383 }