• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mybatis / mybatis-3 / 2604

03 Jan 2025 10:00AM UTC coverage: 87.524% (+0.3%) from 87.177%
2604

Pull #3146

github

web-flow
Merge 60c1f5fea into 8ac3920af
Pull Request #3146: Shared ambiguity instance

3633 of 4401 branches covered (82.55%)

4 of 4 new or added lines in 1 file covered. (100.0%)

254 existing lines in 22 files now uncovered.

9569 of 10933 relevant lines covered (87.52%)

0.88 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

83.78
/src/main/java/org/apache/ibatis/session/defaults/DefaultSqlSession.java
1
/*
2
 *    Copyright 2009-2025 the original author or authors.
3
 *
4
 *    Licensed under the Apache License, Version 2.0 (the "License");
5
 *    you may not use this file except in compliance with the License.
6
 *    You may obtain a copy of the License at
7
 *
8
 *       https://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 *    Unless required by applicable law or agreed to in writing, software
11
 *    distributed under the License is distributed on an "AS IS" BASIS,
12
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 *    See the License for the specific language governing permissions and
14
 *    limitations under the License.
15
 */
16
package org.apache.ibatis.session.defaults;
17

18
import java.sql.Connection;
19
import java.sql.SQLException;
20
import java.util.ArrayList;
21
import java.util.HashMap;
22
import java.util.List;
23
import java.util.Map;
24

25
import org.apache.ibatis.binding.BindingException;
26
import org.apache.ibatis.cursor.Cursor;
27
import org.apache.ibatis.exceptions.ExceptionFactory;
28
import org.apache.ibatis.exceptions.TooManyResultsException;
29
import org.apache.ibatis.executor.BatchResult;
30
import org.apache.ibatis.executor.ErrorContext;
31
import org.apache.ibatis.executor.Executor;
32
import org.apache.ibatis.executor.result.DefaultMapResultHandler;
33
import org.apache.ibatis.executor.result.DefaultResultContext;
34
import org.apache.ibatis.mapping.MappedStatement;
35
import org.apache.ibatis.reflection.ParamNameResolver;
36
import org.apache.ibatis.session.Configuration;
37
import org.apache.ibatis.session.ResultHandler;
38
import org.apache.ibatis.session.RowBounds;
39
import org.apache.ibatis.session.SqlSession;
40

41
/**
42
 * The default implementation for {@link SqlSession}. Note that this class is not Thread-Safe.
43
 *
44
 * @author Clinton Begin
45
 */
46
public class DefaultSqlSession implements SqlSession {
47

48
  private final Configuration configuration;
49
  private final Executor executor;
50

51
  private final boolean autoCommit;
52
  private boolean dirty;
53
  private List<Cursor<?>> cursorList;
54

55
  public DefaultSqlSession(Configuration configuration, Executor executor, boolean autoCommit) {
1✔
56
    this.configuration = configuration;
1✔
57
    this.executor = executor;
1✔
58
    this.dirty = false;
1✔
59
    this.autoCommit = autoCommit;
1✔
60
  }
1✔
61

62
  public DefaultSqlSession(Configuration configuration, Executor executor) {
UNCOV
63
    this(configuration, executor, false);
×
64
  }
×
65

66
  @Override
67
  public <T> T selectOne(String statement) {
68
    return this.selectOne(statement, null);
1✔
69
  }
70

71
  @Override
72
  public <T> T selectOne(String statement, Object parameter) {
73
    // Popular vote was to return null on 0 results and throw exception on too many.
74
    List<T> list = this.selectList(statement, parameter);
1✔
75
    if (list.size() == 1) {
1✔
76
      return list.get(0);
1✔
77
    }
78
    if (list.size() > 1) {
1✔
79
      throw new TooManyResultsException(
1✔
80
          "Expected one result (or null) to be returned by selectOne(), but found: " + list.size());
1✔
81
    } else {
82
      return null;
1✔
83
    }
84
  }
85

86
  @Override
87
  public <K, V> Map<K, V> selectMap(String statement, String mapKey) {
88
    return this.selectMap(statement, null, mapKey, RowBounds.DEFAULT);
1✔
89
  }
90

91
  @Override
92
  public <K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey) {
93
    return this.selectMap(statement, parameter, mapKey, RowBounds.DEFAULT);
1✔
94
  }
95

96
  @Override
97
  public <K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey, RowBounds rowBounds) {
98
    final List<? extends V> list = selectList(statement, parameter, rowBounds);
1✔
99
    final DefaultMapResultHandler<K, V> mapResultHandler = new DefaultMapResultHandler<>(mapKey,
1✔
100
        configuration.getObjectFactory(), configuration.getObjectWrapperFactory(), configuration.getReflectorFactory());
1✔
101
    final DefaultResultContext<V> context = new DefaultResultContext<>();
1✔
102
    for (V o : list) {
1✔
103
      context.nextResultObject(o);
1✔
104
      mapResultHandler.handleResult(context);
1✔
105
    }
1✔
106
    return mapResultHandler.getMappedResults();
1✔
107
  }
108

109
  @Override
110
  public <T> Cursor<T> selectCursor(String statement) {
UNCOV
111
    return selectCursor(statement, null);
×
112
  }
113

114
  @Override
115
  public <T> Cursor<T> selectCursor(String statement, Object parameter) {
116
    return selectCursor(statement, parameter, RowBounds.DEFAULT);
1✔
117
  }
118

119
  @Override
120
  public <T> Cursor<T> selectCursor(String statement, Object parameter, RowBounds rowBounds) {
121
    try {
122
      MappedStatement ms = configuration.getMappedStatement(statement);
1✔
123
      dirty |= ms.isDirtySelect();
1✔
124
      Cursor<T> cursor = executor.queryCursor(ms, wrapCollection(parameter), rowBounds);
1✔
125
      registerCursor(cursor);
1✔
126
      return cursor;
1✔
UNCOV
127
    } catch (Exception e) {
×
128
      throw ExceptionFactory.wrapException("Error querying database.  Cause: " + e, e);
×
129
    } finally {
130
      ErrorContext.instance().reset();
1✔
131
    }
132
  }
133

134
  @Override
135
  public <E> List<E> selectList(String statement) {
136
    return this.selectList(statement, null);
1✔
137
  }
138

139
  @Override
140
  public <E> List<E> selectList(String statement, Object parameter) {
141
    return this.selectList(statement, parameter, RowBounds.DEFAULT);
1✔
142
  }
143

144
  @Override
145
  public <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds) {
146
    return selectList(statement, parameter, rowBounds, Executor.NO_RESULT_HANDLER);
1✔
147
  }
148

149
  private <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds, ResultHandler handler) {
150
    try {
151
      MappedStatement ms = configuration.getMappedStatement(statement);
1✔
152
      dirty |= ms.isDirtySelect();
1✔
153
      return executor.query(ms, wrapCollection(parameter), rowBounds, handler);
1✔
154
    } catch (Exception e) {
1✔
155
      throw ExceptionFactory.wrapException("Error querying database.  Cause: " + e, e);
1✔
156
    } finally {
157
      ErrorContext.instance().reset();
1✔
158
    }
159
  }
160

161
  @Override
162
  public void select(String statement, Object parameter, ResultHandler handler) {
163
    select(statement, parameter, RowBounds.DEFAULT, handler);
1✔
164
  }
1✔
165

166
  @Override
167
  public void select(String statement, ResultHandler handler) {
168
    select(statement, null, RowBounds.DEFAULT, handler);
1✔
169
  }
1✔
170

171
  @Override
172
  public void select(String statement, Object parameter, RowBounds rowBounds, ResultHandler handler) {
173
    selectList(statement, parameter, rowBounds, handler);
1✔
174
  }
1✔
175

176
  @Override
177
  public int insert(String statement) {
UNCOV
178
    return insert(statement, null);
×
179
  }
180

181
  @Override
182
  public int insert(String statement, Object parameter) {
183
    return update(statement, parameter);
1✔
184
  }
185

186
  @Override
187
  public int update(String statement) {
UNCOV
188
    return update(statement, null);
×
189
  }
190

191
  @Override
192
  public int update(String statement, Object parameter) {
193
    try {
194
      dirty = true;
1✔
195
      MappedStatement ms = configuration.getMappedStatement(statement);
1✔
196
      return executor.update(ms, wrapCollection(parameter));
1✔
197
    } catch (Exception e) {
1✔
198
      throw ExceptionFactory.wrapException("Error updating database.  Cause: " + e, e);
1✔
199
    } finally {
200
      ErrorContext.instance().reset();
1✔
201
    }
202
  }
203

204
  @Override
205
  public int delete(String statement) {
UNCOV
206
    return update(statement, null);
×
207
  }
208

209
  @Override
210
  public int delete(String statement, Object parameter) {
211
    return update(statement, parameter);
1✔
212
  }
213

214
  @Override
215
  public void commit() {
216
    commit(false);
1✔
217
  }
1✔
218

219
  @Override
220
  public void commit(boolean force) {
221
    try {
222
      executor.commit(isCommitOrRollbackRequired(force));
1✔
223
      dirty = false;
1✔
UNCOV
224
    } catch (Exception e) {
×
225
      throw ExceptionFactory.wrapException("Error committing transaction.  Cause: " + e, e);
×
226
    } finally {
227
      ErrorContext.instance().reset();
1✔
228
    }
229
  }
1✔
230

231
  @Override
232
  public void rollback() {
233
    rollback(false);
1✔
234
  }
1✔
235

236
  @Override
237
  public void rollback(boolean force) {
238
    try {
239
      executor.rollback(isCommitOrRollbackRequired(force));
1✔
240
      dirty = false;
1✔
UNCOV
241
    } catch (Exception e) {
×
242
      throw ExceptionFactory.wrapException("Error rolling back transaction.  Cause: " + e, e);
×
243
    } finally {
244
      ErrorContext.instance().reset();
1✔
245
    }
246
  }
1✔
247

248
  @Override
249
  public List<BatchResult> flushStatements() {
250
    try {
251
      return executor.flushStatements();
1✔
252
    } catch (Exception e) {
1✔
253
      throw ExceptionFactory.wrapException("Error flushing statements.  Cause: " + e, e);
1✔
254
    } finally {
255
      ErrorContext.instance().reset();
1✔
256
    }
257
  }
258

259
  @Override
260
  public void close() {
261
    try {
262
      executor.close(isCommitOrRollbackRequired(false));
1✔
263
      closeCursors();
1✔
264
      dirty = false;
1✔
265
    } finally {
266
      ErrorContext.instance().reset();
1✔
267
    }
268
  }
1✔
269

270
  private void closeCursors() {
271
    if (cursorList != null && !cursorList.isEmpty()) {
1!
272
      for (Cursor<?> cursor : cursorList) {
1✔
273
        cursor.close();
1✔
274
      }
1✔
275
      cursorList.clear();
1✔
276
    }
277
  }
1✔
278

279
  @Override
280
  public Configuration getConfiguration() {
281
    return configuration;
1✔
282
  }
283

284
  @Override
285
  public <T> T getMapper(Class<T> type) {
286
    return configuration.getMapper(type, this);
1✔
287
  }
288

289
  @Override
290
  public Connection getConnection() {
291
    try {
292
      return executor.getTransaction().getConnection();
1✔
UNCOV
293
    } catch (SQLException e) {
×
UNCOV
294
      throw ExceptionFactory.wrapException("Error getting a new connection.  Cause: " + e, e);
×
295
    }
296
  }
297

298
  @Override
299
  public void clearCache() {
300
    executor.clearLocalCache();
1✔
301
  }
1✔
302

303
  private <T> void registerCursor(Cursor<T> cursor) {
304
    if (cursorList == null) {
1!
305
      cursorList = new ArrayList<>();
1✔
306
    }
307
    cursorList.add(cursor);
1✔
308
  }
1✔
309

310
  private boolean isCommitOrRollbackRequired(boolean force) {
311
    return !autoCommit && dirty || force;
1✔
312
  }
313

314
  private Object wrapCollection(final Object object) {
315
    return ParamNameResolver.wrapToMapIfCollection(object, null);
1✔
316
  }
317

318
  /**
319
   * @deprecated Since 3.5.5
320
   */
321
  @Deprecated
UNCOV
322
  public static class StrictMap<V> extends HashMap<String, V> {
×
323

324
    private static final long serialVersionUID = -5741767162221585340L;
325

326
    @Override
327
    public V get(Object key) {
UNCOV
328
      if (!super.containsKey(key)) {
×
UNCOV
329
        throw new BindingException("Parameter '" + key + "' not found. Available parameters are " + this.keySet());
×
330
      }
UNCOV
331
      return super.get(key);
×
332
    }
333

334
  }
335

336
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc