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

mybatis / ibatis-2 / 730

28 Dec 2025 10:16PM UTC coverage: 65.615% (+0.5%) from 65.146%
730

push

github

web-flow
Update README.md

1602 of 2802 branches covered (57.17%)

5053 of 7701 relevant lines covered (65.61%)

0.66 hits per line

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

88.51
/src/main/java/com/ibatis/sqlmap/engine/impl/SqlMapExecutorDelegate.java
1
/*
2
 * Copyright 2004-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 com.ibatis.sqlmap.engine.impl;
17

18
import com.ibatis.common.beans.Probe;
19
import com.ibatis.common.beans.ProbeFactory;
20
import com.ibatis.common.jdbc.exception.NestedSQLException;
21
import com.ibatis.common.util.PaginatedList;
22
import com.ibatis.sqlmap.client.SqlMapException;
23
import com.ibatis.sqlmap.client.event.RowHandler;
24
import com.ibatis.sqlmap.engine.cache.CacheKey;
25
import com.ibatis.sqlmap.engine.cache.CacheModel;
26
import com.ibatis.sqlmap.engine.exchange.DataExchangeFactory;
27
import com.ibatis.sqlmap.engine.execution.BatchException;
28
import com.ibatis.sqlmap.engine.execution.DefaultSqlExecutor;
29
import com.ibatis.sqlmap.engine.execution.SqlExecutor;
30
import com.ibatis.sqlmap.engine.mapping.parameter.ParameterMap;
31
import com.ibatis.sqlmap.engine.mapping.result.ResultMap;
32
import com.ibatis.sqlmap.engine.mapping.result.ResultObjectFactory;
33
import com.ibatis.sqlmap.engine.mapping.statement.InsertStatement;
34
import com.ibatis.sqlmap.engine.mapping.statement.MappedStatement;
35
import com.ibatis.sqlmap.engine.mapping.statement.PaginatedDataList;
36
import com.ibatis.sqlmap.engine.mapping.statement.SelectKeyStatement;
37
import com.ibatis.sqlmap.engine.scope.SessionScope;
38
import com.ibatis.sqlmap.engine.scope.StatementScope;
39
import com.ibatis.sqlmap.engine.transaction.Transaction;
40
import com.ibatis.sqlmap.engine.transaction.TransactionException;
41
import com.ibatis.sqlmap.engine.transaction.TransactionManager;
42
import com.ibatis.sqlmap.engine.transaction.TransactionState;
43
import com.ibatis.sqlmap.engine.transaction.user.UserProvidedTransaction;
44
import com.ibatis.sqlmap.engine.type.TypeHandlerFactory;
45

46
import java.sql.Connection;
47
import java.sql.SQLException;
48
import java.util.HashMap;
49
import java.util.Iterator;
50
import java.util.List;
51
import java.util.Map;
52

53
import javax.sql.DataSource;
54

55
/**
56
 * The workhorse that really runs the SQL.
57
 */
58
public class SqlMapExecutorDelegate {
59

60
  /** The Constant PROBE. */
61
  private static final Probe PROBE = ProbeFactory.getProbe();
1✔
62

63
  /** The lazy loading enabled. */
64
  private boolean lazyLoadingEnabled = true;
1✔
65

66
  /** The cache models enabled. */
67
  private boolean cacheModelsEnabled = true;
1✔
68

69
  /** The enhancement enabled. */
70
  private boolean enhancementEnabled = false;
1✔
71

72
  /** The use column label. */
73
  private boolean useColumnLabel = true;
1✔
74

75
  /** The force multiple result set support. */
76
  private boolean forceMultipleResultSetSupport;
77

78
  /** The tx manager. */
79
  private TransactionManager txManager;
80

81
  /** The mapped statements. */
82
  private HashMap mappedStatements;
83

84
  /** The cache models. */
85
  private HashMap cacheModels;
86

87
  /** The result maps. */
88
  private HashMap resultMaps;
89

90
  /** The parameter maps. */
91
  private HashMap parameterMaps;
92

93
  /** The sql executor. */
94
  protected SqlExecutor sqlExecutor;
95

96
  /** The type handler factory. */
97
  private TypeHandlerFactory typeHandlerFactory;
98

99
  /** The data exchange factory. */
100
  private DataExchangeFactory dataExchangeFactory;
101

102
  /** The result object factory. */
103
  private ResultObjectFactory resultObjectFactory;
104

105
  /** The statement cache enabled. */
106
  private boolean statementCacheEnabled = true;
1✔
107

108
  /**
109
   * Default constructor.
110
   */
111
  public SqlMapExecutorDelegate() {
1✔
112
    mappedStatements = new HashMap<>();
1✔
113
    cacheModels = new HashMap<>();
1✔
114
    resultMaps = new HashMap<>();
1✔
115
    parameterMaps = new HashMap<>();
1✔
116

117
    sqlExecutor = new DefaultSqlExecutor();
1✔
118
    typeHandlerFactory = new TypeHandlerFactory();
1✔
119
    dataExchangeFactory = new DataExchangeFactory(typeHandlerFactory);
1✔
120
  }
1✔
121

122
  /**
123
   * Sets the custom executor.
124
   *
125
   * @param sqlExecutorClass
126
   *          the new custom executor
127
   */
128
  public void setCustomExecutor(String sqlExecutorClass) {
129
    try {
130
      Class factoryClass = Class.forName(sqlExecutorClass);
×
131
      sqlExecutor = (SqlExecutor) factoryClass.getDeclaredConstructor().newInstance();
×
132
    } catch (Exception e) {
×
133
      throw new SqlMapException(
×
134
          "Error instantiating " + sqlExecutorClass + ". Please check the class given in properties file. Cause: " + e,
135
          e);
136
    }
×
137
  }
×
138

139
  /**
140
   * DO NOT DEPEND ON THIS. Here to avoid breaking spring integration.
141
   *
142
   * @return the max transactions
143
   *
144
   * @deprecated
145
   */
146
  @Deprecated
147
  public int getMaxTransactions() {
148
    return -1;
×
149
  }
150

151
  /**
152
   * Getter for the DataExchangeFactory.
153
   *
154
   * @return - the DataExchangeFactory
155
   */
156
  public DataExchangeFactory getDataExchangeFactory() {
157
    return dataExchangeFactory;
1✔
158
  }
159

160
  /**
161
   * Getter for the TypeHandlerFactory.
162
   *
163
   * @return - the TypeHandlerFactory
164
   */
165
  public TypeHandlerFactory getTypeHandlerFactory() {
166
    return typeHandlerFactory;
1✔
167
  }
168

169
  /**
170
   * Getter for the status of lazy loading.
171
   *
172
   * @return - the status
173
   */
174
  public boolean isLazyLoadingEnabled() {
175
    return lazyLoadingEnabled;
1✔
176
  }
177

178
  /**
179
   * Turn on or off lazy loading.
180
   *
181
   * @param lazyLoadingEnabled
182
   *          - the new state of caching
183
   */
184
  public void setLazyLoadingEnabled(boolean lazyLoadingEnabled) {
185
    this.lazyLoadingEnabled = lazyLoadingEnabled;
1✔
186
  }
1✔
187

188
  /**
189
   * Getter for the status of caching.
190
   *
191
   * @return - the status
192
   */
193
  public boolean isCacheModelsEnabled() {
194
    return cacheModelsEnabled;
1✔
195
  }
196

197
  /**
198
   * Turn on or off caching.
199
   *
200
   * @param cacheModelsEnabled
201
   *          - the new state of caching
202
   */
203
  public void setCacheModelsEnabled(boolean cacheModelsEnabled) {
204
    this.cacheModelsEnabled = cacheModelsEnabled;
1✔
205
  }
1✔
206

207
  /**
208
   * Getter for the status of CGLib enhancements.
209
   *
210
   * @return - the status
211
   */
212
  public boolean isEnhancementEnabled() {
213
    return enhancementEnabled;
1✔
214
  }
215

216
  /**
217
   * Turn on or off CGLib enhancements.
218
   *
219
   * @param enhancementEnabled
220
   *          - the new state
221
   */
222
  public void setEnhancementEnabled(boolean enhancementEnabled) {
223
    this.enhancementEnabled = enhancementEnabled;
1✔
224
  }
1✔
225

226
  /**
227
   * Checks if is use column label.
228
   *
229
   * @return true, if is use column label
230
   */
231
  public boolean isUseColumnLabel() {
232
    return useColumnLabel;
1✔
233
  }
234

235
  /**
236
   * Sets the use column label.
237
   *
238
   * @param useColumnLabel
239
   *          the new use column label
240
   */
241
  public void setUseColumnLabel(boolean useColumnLabel) {
242
    this.useColumnLabel = useColumnLabel;
1✔
243
  }
1✔
244

245
  /**
246
   * Getter for the transaction manager.
247
   *
248
   * @return - the transaction manager
249
   */
250
  public TransactionManager getTxManager() {
251
    return txManager;
1✔
252
  }
253

254
  /**
255
   * Setter for the transaction manager.
256
   *
257
   * @param txManager
258
   *          - the transaction manager
259
   */
260
  public void setTxManager(TransactionManager txManager) {
261
    this.txManager = txManager;
1✔
262
  }
1✔
263

264
  /**
265
   * Add a mapped statement.
266
   *
267
   * @param ms
268
   *          - the mapped statement to add
269
   */
270
  public void addMappedStatement(MappedStatement ms) {
271
    if (mappedStatements.containsKey(ms.getId())) {
1!
272
      throw new SqlMapException("There is already a statement named " + ms.getId() + " in this SqlMap.");
×
273
    }
274
    ms.setBaseCacheKey(hashCode());
1✔
275
    mappedStatements.put(ms.getId(), ms);
1✔
276
  }
1✔
277

278
  /**
279
   * Get an iterator of the mapped statements.
280
   *
281
   * @return - the iterator
282
   */
283
  public Iterator getMappedStatementNames() {
284
    return mappedStatements.keySet().iterator();
×
285
  }
286

287
  /**
288
   * Get a mapped statement by its ID.
289
   *
290
   * @param id
291
   *          - the statement ID
292
   *
293
   * @return - the mapped statement
294
   */
295
  public MappedStatement getMappedStatement(String id) {
296
    MappedStatement ms = (MappedStatement) mappedStatements.get(id);
1✔
297
    if (ms == null) {
1!
298
      throw new SqlMapException("There is no statement named " + id + " in this SqlMap.");
×
299
    }
300
    return ms;
1✔
301
  }
302

303
  /**
304
   * Add a cache model.
305
   *
306
   * @param model
307
   *          - the model to add
308
   */
309
  public void addCacheModel(CacheModel model) {
310
    cacheModels.put(model.getId(), model);
1✔
311
  }
1✔
312

313
  /**
314
   * Get an iterator of the cache models.
315
   *
316
   * @return - the cache models
317
   */
318
  public Iterator getCacheModelNames() {
319
    return cacheModels.keySet().iterator();
1✔
320
  }
321

322
  /**
323
   * Get a cache model by ID.
324
   *
325
   * @param id
326
   *          - the ID
327
   *
328
   * @return - the cache model
329
   */
330
  public CacheModel getCacheModel(String id) {
331
    CacheModel model = (CacheModel) cacheModels.get(id);
1✔
332
    if (model == null) {
1!
333
      throw new SqlMapException("There is no cache model named " + id + " in this SqlMap.");
×
334
    }
335
    return model;
1✔
336
  }
337

338
  /**
339
   * Add a result map.
340
   *
341
   * @param map
342
   *          - the result map to add
343
   */
344
  public void addResultMap(ResultMap map) {
345
    resultMaps.put(map.getId(), map);
1✔
346
  }
1✔
347

348
  /**
349
   * Get an iterator of the result maps.
350
   *
351
   * @return - the result maps
352
   */
353
  public Iterator getResultMapNames() {
354
    return resultMaps.keySet().iterator();
1✔
355
  }
356

357
  /**
358
   * Get a result map by ID.
359
   *
360
   * @param id
361
   *          - the ID
362
   *
363
   * @return - the result map
364
   */
365
  public ResultMap getResultMap(String id) {
366
    ResultMap map = (ResultMap) resultMaps.get(id);
1✔
367
    if (map == null) {
1!
368
      throw new SqlMapException("There is no result map named " + id + " in this SqlMap.");
×
369
    }
370
    return map;
1✔
371
  }
372

373
  /**
374
   * Add a parameter map.
375
   *
376
   * @param map
377
   *          - the map to add
378
   */
379
  public void addParameterMap(ParameterMap map) {
380
    parameterMaps.put(map.getId(), map);
1✔
381
  }
1✔
382

383
  /**
384
   * Get an iterator of all of the parameter maps.
385
   *
386
   * @return - the parameter maps
387
   */
388
  public Iterator getParameterMapNames() {
389
    return parameterMaps.keySet().iterator();
×
390
  }
391

392
  /**
393
   * Get a parameter map by ID.
394
   *
395
   * @param id
396
   *          - the ID
397
   *
398
   * @return - the parameter map
399
   */
400
  public ParameterMap getParameterMap(String id) {
401
    ParameterMap map = (ParameterMap) parameterMaps.get(id);
1✔
402
    if (map == null) {
1!
403
      throw new SqlMapException("There is no parameter map named " + id + " in this SqlMap.");
×
404
    }
405
    return map;
1✔
406
  }
407

408
  /**
409
   * Flush all of the data caches.
410
   */
411
  public void flushDataCache() {
412
    Iterator models = cacheModels.values().iterator();
1✔
413
    while (models.hasNext()) {
1✔
414
      ((CacheModel) models.next()).flush();
1✔
415
    }
416
  }
1✔
417

418
  /**
419
   * Flush a single cache by ID.
420
   *
421
   * @param id
422
   *          - the ID
423
   */
424
  public void flushDataCache(String id) {
425
    CacheModel model = getCacheModel(id);
×
426
    if (model != null) {
×
427
      model.flush();
×
428
    }
429
  }
×
430

431
  // -- Basic Methods
432
  /**
433
   * Call an insert statement by ID.
434
   *
435
   * @param sessionScope
436
   *          - the session
437
   * @param id
438
   *          - the statement ID
439
   * @param param
440
   *          - the parameter object
441
   *
442
   * @return - the generated key (or null)
443
   *
444
   * @throws SQLException
445
   *           - if the insert fails
446
   */
447
  public Object insert(SessionScope sessionScope, String id, Object param) throws SQLException {
448
    Object generatedKey = null;
1✔
449

450
    MappedStatement ms = getMappedStatement(id);
1✔
451
    Transaction trans = getTransaction(sessionScope);
1✔
452
    boolean autoStart = trans == null;
1✔
453

454
    try {
455
      trans = autoStartTransaction(sessionScope, autoStart, trans);
1✔
456

457
      SelectKeyStatement selectKeyStatement = null;
1✔
458
      if (ms instanceof InsertStatement) {
1!
459
        selectKeyStatement = ((InsertStatement) ms).getSelectKeyStatement();
1✔
460
      }
461

462
      // Here we get the old value for the key property. We'll want it later if for some
463
      // reason the
464
      // insert fails.
465
      Object oldKeyValue = null;
1✔
466
      String keyProperty = null;
1✔
467
      boolean resetKeyValueOnFailure = false;
1✔
468
      if (selectKeyStatement != null && !selectKeyStatement.isRunAfterSQL()) {
1✔
469
        keyProperty = selectKeyStatement.getKeyProperty();
1✔
470
        oldKeyValue = PROBE.getObject(param, keyProperty);
1✔
471
        generatedKey = executeSelectKey(sessionScope, trans, ms, param);
1✔
472
        resetKeyValueOnFailure = true;
1✔
473
      }
474

475
      StatementScope statementScope = beginStatementScope(sessionScope, ms);
1✔
476
      try {
477
        ms.executeUpdate(statementScope, trans, param);
1✔
478
      } catch (SQLException e) {
1✔
479
        // uh-oh, the insert failed, so if we set the reset flag earlier, we'll put the old
480
        // value
481
        // back...
482
        if (resetKeyValueOnFailure) {
1!
483
          PROBE.setObject(param, keyProperty, oldKeyValue);
×
484
        }
485
        // ...and still throw the exception.
486
        throw e;
1✔
487
      } finally {
488
        endStatementScope(statementScope);
1✔
489
      }
490

491
      if (selectKeyStatement != null && selectKeyStatement.isRunAfterSQL()) {
1✔
492
        generatedKey = executeSelectKey(sessionScope, trans, ms, param);
1✔
493
      }
494

495
      autoCommitTransaction(sessionScope, autoStart);
1✔
496
    } finally {
497
      autoEndTransaction(sessionScope, autoStart);
1✔
498
    }
499

500
    return generatedKey;
1✔
501
  }
502

503
  /**
504
   * Execute select key.
505
   *
506
   * @param sessionScope
507
   *          the session scope
508
   * @param trans
509
   *          the trans
510
   * @param ms
511
   *          the ms
512
   * @param param
513
   *          the param
514
   *
515
   * @return the object
516
   *
517
   * @throws SQLException
518
   *           the SQL exception
519
   */
520
  private Object executeSelectKey(SessionScope sessionScope, Transaction trans, MappedStatement ms, Object param)
521
      throws SQLException {
522
    Object generatedKey = null;
1✔
523
    StatementScope statementScope;
524
    InsertStatement insert = (InsertStatement) ms;
1✔
525
    SelectKeyStatement selectKeyStatement = insert.getSelectKeyStatement();
1✔
526
    if (selectKeyStatement != null) {
1!
527
      statementScope = beginStatementScope(sessionScope, selectKeyStatement);
1✔
528
      try {
529
        generatedKey = selectKeyStatement.executeQueryForObject(statementScope, trans, param, null);
1✔
530
        String keyProp = selectKeyStatement.getKeyProperty();
1✔
531
        if (keyProp != null) {
1!
532
          PROBE.setObject(param, keyProp, generatedKey);
1✔
533
        }
534
      } finally {
535
        endStatementScope(statementScope);
1✔
536
      }
537
    }
538
    return generatedKey;
1✔
539
  }
540

541
  /**
542
   * Execute an update statement.
543
   *
544
   * @param sessionScope
545
   *          - the session scope
546
   * @param id
547
   *          - the statement ID
548
   * @param param
549
   *          - the parameter object
550
   *
551
   * @return - the number of rows updated
552
   *
553
   * @throws SQLException
554
   *           - if the update fails
555
   */
556
  public int update(SessionScope sessionScope, String id, Object param) throws SQLException {
557
    int rows = 0;
1✔
558

559
    MappedStatement ms = getMappedStatement(id);
1✔
560
    Transaction trans = getTransaction(sessionScope);
1✔
561
    boolean autoStart = trans == null;
1✔
562

563
    try {
564
      trans = autoStartTransaction(sessionScope, autoStart, trans);
1✔
565

566
      StatementScope statementScope = beginStatementScope(sessionScope, ms);
1✔
567
      try {
568
        rows = ms.executeUpdate(statementScope, trans, param);
1✔
569
      } finally {
570
        endStatementScope(statementScope);
1✔
571
      }
572

573
      autoCommitTransaction(sessionScope, autoStart);
1✔
574
    } finally {
575
      autoEndTransaction(sessionScope, autoStart);
1✔
576
    }
577

578
    return rows;
1✔
579
  }
580

581
  /**
582
   * Execute a delete statement.
583
   *
584
   * @param sessionScope
585
   *          - the session scope
586
   * @param id
587
   *          - the statement ID
588
   * @param param
589
   *          - the parameter object
590
   *
591
   * @return - the number of rows deleted
592
   *
593
   * @throws SQLException
594
   *           - if the delete fails
595
   */
596
  public int delete(SessionScope sessionScope, String id, Object param) throws SQLException {
597
    return update(sessionScope, id, param);
×
598
  }
599

600
  /**
601
   * Execute a select for a single object.
602
   *
603
   * @param sessionScope
604
   *          - the session scope
605
   * @param id
606
   *          - the statement ID
607
   * @param paramObject
608
   *          - the parameter object
609
   *
610
   * @return - the result of the query
611
   *
612
   * @throws SQLException
613
   *           - if the query fails
614
   */
615
  public Object queryForObject(SessionScope sessionScope, String id, Object paramObject) throws SQLException {
616
    return queryForObject(sessionScope, id, paramObject, null);
1✔
617
  }
618

619
  /**
620
   * Execute a select for a single object.
621
   *
622
   * @param sessionScope
623
   *          - the session scope
624
   * @param id
625
   *          - the statement ID
626
   * @param paramObject
627
   *          - the parameter object
628
   * @param resultObject
629
   *          - the result object (if not supplied or null, a new object will be created)
630
   *
631
   * @return - the result of the query
632
   *
633
   * @throws SQLException
634
   *           - if the query fails
635
   */
636
  public Object queryForObject(SessionScope sessionScope, String id, Object paramObject, Object resultObject)
637
      throws SQLException {
638
    Object object = null;
1✔
639

640
    MappedStatement ms = getMappedStatement(id);
1✔
641
    Transaction trans = getTransaction(sessionScope);
1✔
642
    boolean autoStart = trans == null;
1✔
643

644
    try {
645
      trans = autoStartTransaction(sessionScope, autoStart, trans);
1✔
646

647
      StatementScope statementScope = beginStatementScope(sessionScope, ms);
1✔
648
      try {
649
        object = ms.executeQueryForObject(statementScope, trans, paramObject, resultObject);
1✔
650
      } finally {
651
        endStatementScope(statementScope);
1✔
652
      }
653

654
      autoCommitTransaction(sessionScope, autoStart);
1✔
655
    } finally {
656
      autoEndTransaction(sessionScope, autoStart);
1✔
657
    }
658

659
    return object;
1✔
660
  }
661

662
  /**
663
   * Execute a query for a list.
664
   *
665
   * @param sessionScope
666
   *          - the session scope
667
   * @param id
668
   *          - the statement ID
669
   * @param paramObject
670
   *          - the parameter object
671
   *
672
   * @return - the data list
673
   *
674
   * @throws SQLException
675
   *           - if the query fails
676
   */
677
  public List queryForList(SessionScope sessionScope, String id, Object paramObject) throws SQLException {
678
    return queryForList(sessionScope, id, paramObject, SqlExecutor.NO_SKIPPED_RESULTS, SqlExecutor.NO_MAXIMUM_RESULTS);
1✔
679
  }
680

681
  /**
682
   * Execute a query for a list.
683
   *
684
   * @param sessionScope
685
   *          - the session scope
686
   * @param id
687
   *          - the statement ID
688
   * @param paramObject
689
   *          - the parameter object
690
   * @param skip
691
   *          - the number of rows to skip
692
   * @param max
693
   *          - the maximum number of rows to return
694
   *
695
   * @return - the data list
696
   *
697
   * @throws SQLException
698
   *           - if the query fails
699
   */
700
  public List queryForList(SessionScope sessionScope, String id, Object paramObject, int skip, int max)
701
      throws SQLException {
702
    List list = null;
1✔
703

704
    MappedStatement ms = getMappedStatement(id);
1✔
705
    Transaction trans = getTransaction(sessionScope);
1✔
706
    boolean autoStart = trans == null;
1✔
707

708
    try {
709
      trans = autoStartTransaction(sessionScope, autoStart, trans);
1✔
710

711
      StatementScope statementScope = beginStatementScope(sessionScope, ms);
1✔
712
      try {
713
        list = ms.executeQueryForList(statementScope, trans, paramObject, skip, max);
1✔
714
      } finally {
715
        endStatementScope(statementScope);
1✔
716
      }
717

718
      autoCommitTransaction(sessionScope, autoStart);
1✔
719
    } finally {
720
      autoEndTransaction(sessionScope, autoStart);
1✔
721
    }
722

723
    return list;
1✔
724
  }
725

726
  /**
727
   * Execute a query with a row handler. The row handler is called once per row in the query results.
728
   *
729
   * @param sessionScope
730
   *          - the session scope
731
   * @param id
732
   *          - the statement ID
733
   * @param paramObject
734
   *          - the parameter object
735
   * @param rowHandler
736
   *          - the row handler
737
   *
738
   * @throws SQLException
739
   *           - if the query fails
740
   */
741
  public void queryWithRowHandler(SessionScope sessionScope, String id, Object paramObject, RowHandler rowHandler)
742
      throws SQLException {
743

744
    MappedStatement ms = getMappedStatement(id);
1✔
745
    Transaction trans = getTransaction(sessionScope);
1✔
746
    boolean autoStart = trans == null;
1!
747

748
    try {
749
      trans = autoStartTransaction(sessionScope, autoStart, trans);
1✔
750

751
      StatementScope statementScope = beginStatementScope(sessionScope, ms);
1✔
752
      try {
753
        ms.executeQueryWithRowHandler(statementScope, trans, paramObject, rowHandler);
1✔
754
      } finally {
755
        endStatementScope(statementScope);
1✔
756
      }
757

758
      autoCommitTransaction(sessionScope, autoStart);
1✔
759
    } finally {
760
      autoEndTransaction(sessionScope, autoStart);
1✔
761
    }
762

763
  }
1✔
764

765
  /**
766
   * Execute a query and return a paginated list.
767
   *
768
   * @param sessionScope
769
   *          - the session scope
770
   * @param id
771
   *          - the statement ID
772
   * @param paramObject
773
   *          - the parameter object
774
   * @param pageSize
775
   *          - the page size
776
   *
777
   * @return - the data list
778
   *
779
   * @throws SQLException
780
   *           - if the query fails
781
   *
782
   * @deprecated All paginated list features have been deprecated
783
   */
784
  @Deprecated
785
  public PaginatedList queryForPaginatedList(SessionScope sessionScope, String id, Object paramObject, int pageSize)
786
      throws SQLException {
787
    return new PaginatedDataList(sessionScope.getSqlMapExecutor(), id, paramObject, pageSize);
1✔
788
  }
789

790
  /**
791
   * Execute a query for a map. The map has the table key as the key, and the results as the map data
792
   *
793
   * @param sessionScope
794
   *          - the session scope
795
   * @param id
796
   *          - the statement ID
797
   * @param paramObject
798
   *          - the parameter object
799
   * @param keyProp
800
   *          - the key property (from the results for the map)
801
   *
802
   * @return - the Map
803
   *
804
   * @throws SQLException
805
   *           - if the query fails
806
   */
807
  public Map queryForMap(SessionScope sessionScope, String id, Object paramObject, String keyProp) throws SQLException {
808
    return queryForMap(sessionScope, id, paramObject, keyProp, null);
1✔
809
  }
810

811
  /**
812
   * Execute a query for a map. The map has the table key as the key, and a property from the results as the map data
813
   *
814
   * @param sessionScope
815
   *          - the session scope
816
   * @param id
817
   *          - the statement ID
818
   * @param paramObject
819
   *          - the parameter object
820
   * @param keyProp
821
   *          - the property for the map key
822
   * @param valueProp
823
   *          - the property for the map data
824
   *
825
   * @return - the Map
826
   *
827
   * @throws SQLException
828
   *           - if the query fails
829
   */
830
  public Map queryForMap(SessionScope sessionScope, String id, Object paramObject, String keyProp, String valueProp)
831
      throws SQLException {
832
    Map map = new HashMap<>();
1✔
833

834
    List list = queryForList(sessionScope, id, paramObject);
1✔
835

836
    for (Object object : list) {
1✔
837
      Object key = PROBE.getObject(object, keyProp);
1✔
838
      Object value = null;
1✔
839
      if (valueProp == null) {
1✔
840
        value = object;
1✔
841
      } else {
842
        value = PROBE.getObject(object, valueProp);
1✔
843
      }
844
      map.put(key, value);
1✔
845
    }
1✔
846

847
    return map;
1✔
848
  }
849

850
  // -- Transaction Control Methods
851
  /**
852
   * Start a transaction on the session.
853
   *
854
   * @param sessionScope
855
   *          - the session
856
   *
857
   * @throws SQLException
858
   *           - if the transaction could not be started
859
   */
860
  public void startTransaction(SessionScope sessionScope) throws SQLException {
861
    try {
862
      txManager.begin(sessionScope);
1✔
863
    } catch (TransactionException e) {
1✔
864
      throw new NestedSQLException("Could not start transaction.  Cause: " + e, e);
1✔
865
    }
1✔
866
  }
1✔
867

868
  /**
869
   * Start a transaction on the session with the specified isolation level.
870
   *
871
   * @param sessionScope
872
   *          - the session
873
   * @param transactionIsolation
874
   *          the transaction isolation
875
   *
876
   * @throws SQLException
877
   *           - if the transaction could not be started
878
   */
879
  public void startTransaction(SessionScope sessionScope, int transactionIsolation) throws SQLException {
880
    try {
881
      txManager.begin(sessionScope, transactionIsolation);
×
882
    } catch (TransactionException e) {
×
883
      throw new NestedSQLException("Could not start transaction.  Cause: " + e, e);
×
884
    }
×
885
  }
×
886

887
  /**
888
   * Commit the transaction on a session.
889
   *
890
   * @param sessionScope
891
   *          - the session
892
   *
893
   * @throws SQLException
894
   *           - if the transaction could not be committed
895
   */
896
  public void commitTransaction(SessionScope sessionScope) throws SQLException {
897
    try {
898
      // Auto batch execution
899
      if (sessionScope.isInBatch()) {
1✔
900
        executeBatch(sessionScope);
1✔
901
      }
902
      sqlExecutor.cleanup(sessionScope);
1✔
903
      txManager.commit(sessionScope);
1✔
904
    } catch (TransactionException e) {
1✔
905
      throw new NestedSQLException("Could not commit transaction.  Cause: " + e, e);
1✔
906
    }
1✔
907
  }
1✔
908

909
  /**
910
   * End the transaction on a session.
911
   *
912
   * @param sessionScope
913
   *          - the session
914
   *
915
   * @throws SQLException
916
   *           - if the transaction could not be ended
917
   */
918
  public void endTransaction(SessionScope sessionScope) throws SQLException {
919
    try {
920
      try {
921
        sqlExecutor.cleanup(sessionScope);
1✔
922
      } finally {
923
        txManager.end(sessionScope);
1✔
924
      }
925
    } catch (TransactionException e) {
1✔
926
      throw new NestedSQLException("Error while ending transaction.  Cause: " + e, e);
1✔
927
    }
1✔
928
  }
1✔
929

930
  /**
931
   * Start a batch for a session.
932
   *
933
   * @param sessionScope
934
   *          - the session
935
   */
936
  public void startBatch(SessionScope sessionScope) {
937
    sessionScope.setInBatch(true);
1✔
938
  }
1✔
939

940
  /**
941
   * Execute a batch for a session.
942
   *
943
   * @param sessionScope
944
   *          - the session
945
   *
946
   * @return - the number of rows impacted by the batch
947
   *
948
   * @throws SQLException
949
   *           - if the batch fails
950
   */
951
  public int executeBatch(SessionScope sessionScope) throws SQLException {
952
    sessionScope.setInBatch(false);
1✔
953
    return sqlExecutor.executeBatch(sessionScope);
1✔
954
  }
955

956
  /**
957
   * Execute a batch for a session.
958
   *
959
   * @param sessionScope
960
   *          - the session
961
   *
962
   * @return - a List of BatchResult objects (may be null if no batch has been initiated). There will be one BatchResult
963
   *         object in the list for each sub-batch executed
964
   *
965
   * @throws SQLException
966
   *           if a database access error occurs, or the drive does not support batch statements
967
   * @throws BatchException
968
   *           if the driver throws BatchUpdateException
969
   */
970
  public List executeBatchDetailed(SessionScope sessionScope) throws SQLException, BatchException {
971
    sessionScope.setInBatch(false);
1✔
972
    return sqlExecutor.executeBatchDetailed(sessionScope);
1✔
973
  }
974

975
  /**
976
   * Use a user-provided transaction for a session.
977
   *
978
   * @param sessionScope
979
   *          - the session scope
980
   * @param userConnection
981
   *          - the user supplied connection
982
   */
983
  public void setUserProvidedTransaction(SessionScope sessionScope, Connection userConnection) {
984
    if (sessionScope.getTransactionState() == TransactionState.STATE_USER_PROVIDED) {
1!
985
      sessionScope.recallTransactionState();
×
986
    }
987
    if (userConnection != null) {
1!
988
      Connection conn = userConnection;
1✔
989
      sessionScope.saveTransactionState();
1✔
990
      sessionScope.setTransaction(new UserProvidedTransaction(conn));
1✔
991
      sessionScope.setTransactionState(TransactionState.STATE_USER_PROVIDED);
1✔
992
    } else {
1✔
993
      sessionScope.setTransaction(null);
×
994
      sessionScope.closePreparedStatements();
×
995
      sessionScope.cleanup();
×
996
    }
997
  }
1✔
998

999
  /**
1000
   * Get the DataSource for the session.
1001
   *
1002
   * @return - the DataSource
1003
   */
1004
  public DataSource getDataSource() {
1005
    DataSource ds = null;
1✔
1006
    if (txManager != null) {
1!
1007
      ds = txManager.getConfig().getDataSource();
1✔
1008
    }
1009
    return ds;
1✔
1010
  }
1011

1012
  /**
1013
   * Getter for the SqlExecutor.
1014
   *
1015
   * @return the SqlExecutor
1016
   */
1017
  public SqlExecutor getSqlExecutor() {
1018
    return sqlExecutor;
1✔
1019
  }
1020

1021
  /**
1022
   * Get a transaction for the session.
1023
   *
1024
   * @param sessionScope
1025
   *          - the session
1026
   *
1027
   * @return - the transaction
1028
   */
1029
  public Transaction getTransaction(SessionScope sessionScope) {
1030
    return sessionScope.getTransaction();
1✔
1031
  }
1032

1033
  // -- Protected Methods
1034

1035
  /**
1036
   * Auto end transaction.
1037
   *
1038
   * @param sessionScope
1039
   *          the session scope
1040
   * @param autoStart
1041
   *          the auto start
1042
   *
1043
   * @throws SQLException
1044
   *           the SQL exception
1045
   */
1046
  protected void autoEndTransaction(SessionScope sessionScope, boolean autoStart) throws SQLException {
1047
    if (autoStart) {
1✔
1048
      sessionScope.getSqlMapTxMgr().endTransaction();
1✔
1049
    }
1050
  }
1✔
1051

1052
  /**
1053
   * Auto commit transaction.
1054
   *
1055
   * @param sessionScope
1056
   *          the session scope
1057
   * @param autoStart
1058
   *          the auto start
1059
   *
1060
   * @throws SQLException
1061
   *           the SQL exception
1062
   */
1063
  protected void autoCommitTransaction(SessionScope sessionScope, boolean autoStart) throws SQLException {
1064
    if (autoStart) {
1✔
1065
      sessionScope.getSqlMapTxMgr().commitTransaction();
1✔
1066
    }
1067
  }
1✔
1068

1069
  /**
1070
   * Auto start transaction.
1071
   *
1072
   * @param sessionScope
1073
   *          the session scope
1074
   * @param autoStart
1075
   *          the auto start
1076
   * @param trans
1077
   *          the trans
1078
   *
1079
   * @return the transaction
1080
   *
1081
   * @throws SQLException
1082
   *           the SQL exception
1083
   */
1084
  protected Transaction autoStartTransaction(SessionScope sessionScope, boolean autoStart, Transaction trans)
1085
      throws SQLException {
1086
    Transaction transaction = trans;
1✔
1087
    if (autoStart) {
1✔
1088
      sessionScope.getSqlMapTxMgr().startTransaction();
1✔
1089
      transaction = getTransaction(sessionScope);
1✔
1090
    }
1091
    return transaction;
1✔
1092
  }
1093

1094
  @Override
1095
  public boolean equals(Object obj) {
1096
    return this == obj;
×
1097
  }
1098

1099
  @Override
1100
  public int hashCode() {
1101
    CacheKey key = new CacheKey();
1✔
1102
    if (txManager != null) {
1!
1103
      key.update(txManager);
1✔
1104
      if (txManager.getConfig().getDataSource() != null) {
1!
1105
        key.update(txManager.getConfig().getDataSource());
1✔
1106
      }
1107
    }
1108
    key.update(System.identityHashCode(this));
1✔
1109
    return key.hashCode();
1✔
1110
  }
1111

1112
  /**
1113
   * Begin statement scope.
1114
   *
1115
   * @param sessionScope
1116
   *          the session scope
1117
   * @param mappedStatement
1118
   *          the mapped statement
1119
   *
1120
   * @return the statement scope
1121
   */
1122
  protected StatementScope beginStatementScope(SessionScope sessionScope, MappedStatement mappedStatement) {
1123
    StatementScope statementScope = new StatementScope(sessionScope);
1✔
1124
    sessionScope.incrementRequestStackDepth();
1✔
1125
    mappedStatement.initRequest(statementScope);
1✔
1126
    return statementScope;
1✔
1127
  }
1128

1129
  /**
1130
   * End statement scope.
1131
   *
1132
   * @param statementScope
1133
   *          the statement scope
1134
   */
1135
  protected void endStatementScope(StatementScope statementScope) {
1136
    statementScope.getSession().decrementRequestStackDepth();
1✔
1137
  }
1✔
1138

1139
  /**
1140
   * Begin session scope.
1141
   *
1142
   * @return the session scope
1143
   */
1144
  protected SessionScope beginSessionScope() {
1145
    return new SessionScope();
1✔
1146
  }
1147

1148
  /**
1149
   * End session scope.
1150
   *
1151
   * @param sessionScope
1152
   *          the session scope
1153
   */
1154
  protected void endSessionScope(SessionScope sessionScope) {
1155
    sessionScope.cleanup();
1✔
1156
  }
1✔
1157

1158
  /**
1159
   * Gets the result object factory.
1160
   *
1161
   * @return the result object factory
1162
   */
1163
  public ResultObjectFactory getResultObjectFactory() {
1164
    return resultObjectFactory;
1✔
1165
  }
1166

1167
  /**
1168
   * Sets the result object factory.
1169
   *
1170
   * @param resultObjectFactory
1171
   *          the new result object factory
1172
   */
1173
  public void setResultObjectFactory(ResultObjectFactory resultObjectFactory) {
1174
    this.resultObjectFactory = resultObjectFactory;
1✔
1175
  }
1✔
1176

1177
  /**
1178
   * Checks if is statement cache enabled.
1179
   *
1180
   * @return true, if is statement cache enabled
1181
   */
1182
  public boolean isStatementCacheEnabled() {
1183
    return statementCacheEnabled;
1✔
1184
  }
1185

1186
  /**
1187
   * Sets the statement cache enabled.
1188
   *
1189
   * @param statementCacheEnabled
1190
   *          the new statement cache enabled
1191
   */
1192
  public void setStatementCacheEnabled(boolean statementCacheEnabled) {
1193
    this.statementCacheEnabled = statementCacheEnabled;
1✔
1194
  }
1✔
1195

1196
  /**
1197
   * Checks if is force multiple result set support.
1198
   *
1199
   * @return true, if is force multiple result set support
1200
   */
1201
  public boolean isForceMultipleResultSetSupport() {
1202
    return forceMultipleResultSetSupport;
1✔
1203
  }
1204

1205
  /**
1206
   * Sets the force multiple result set support.
1207
   *
1208
   * @param forceMultipleResultSetSupport
1209
   *          the new force multiple result set support
1210
   */
1211
  public void setForceMultipleResultSetSupport(boolean forceMultipleResultSetSupport) {
1212
    this.forceMultipleResultSetSupport = forceMultipleResultSetSupport;
1✔
1213
  }
1✔
1214
}
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