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

mybatis / ibatis-2 / 575

26 May 2025 06:27PM UTC coverage: 65.515% (-0.02%) from 65.532%
575

push

github

web-flow
Merge pull request #285 from hazendaz/master

Use declared constructor to call new instance

1611 of 2820 branches covered (57.13%)

0 of 4 new or added lines in 2 files covered. (0.0%)

5082 of 7757 relevant lines covered (65.52%)

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);
×
NEW
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
        // ...and still throw the exception.
485
        throw e;
1✔
486
      } finally {
487
        endStatementScope(statementScope);
1✔
488
      }
489

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

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

499
    return generatedKey;
1✔
500
  }
501

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

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

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

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

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

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

577
    return rows;
1✔
578
  }
579

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

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

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

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

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

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

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

658
    return object;
1✔
659
  }
660

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

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

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

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

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

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

722
    return list;
1✔
723
  }
724

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

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

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

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

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

762
  }
1✔
763

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

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

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

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

835
    for (int i = 0, n = list.size(); i < n; i++) {
1✔
836
      Object object = list.get(i);
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
    }
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 TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc