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

mybatis / mybatis-3 / #3198

27 Aug 2023 08:39PM UTC coverage: 86.703% (-0.9%) from 87.632%
#3198

push

github

web-flow
Merge pull request #2944 from hazendaz/copyright

Update maven and github actions

9305 of 10732 relevant lines covered (86.7%)

0.87 hits per line

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

90.5
/src/main/java/org/apache/ibatis/session/Configuration.java
1
/*
2
 *    Copyright 2009-2023 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;
17

18
import java.util.Arrays;
19
import java.util.Collection;
20
import java.util.HashMap;
21
import java.util.HashSet;
22
import java.util.Iterator;
23
import java.util.LinkedList;
24
import java.util.List;
25
import java.util.Map;
26
import java.util.Properties;
27
import java.util.Set;
28
import java.util.concurrent.ConcurrentHashMap;
29
import java.util.function.BiFunction;
30

31
import org.apache.ibatis.binding.MapperRegistry;
32
import org.apache.ibatis.builder.CacheRefResolver;
33
import org.apache.ibatis.builder.IncompleteElementException;
34
import org.apache.ibatis.builder.ResultMapResolver;
35
import org.apache.ibatis.builder.annotation.MethodResolver;
36
import org.apache.ibatis.builder.xml.XMLStatementBuilder;
37
import org.apache.ibatis.cache.Cache;
38
import org.apache.ibatis.cache.decorators.FifoCache;
39
import org.apache.ibatis.cache.decorators.LruCache;
40
import org.apache.ibatis.cache.decorators.SoftCache;
41
import org.apache.ibatis.cache.decorators.WeakCache;
42
import org.apache.ibatis.cache.impl.PerpetualCache;
43
import org.apache.ibatis.datasource.jndi.JndiDataSourceFactory;
44
import org.apache.ibatis.datasource.pooled.PooledDataSourceFactory;
45
import org.apache.ibatis.datasource.unpooled.UnpooledDataSourceFactory;
46
import org.apache.ibatis.executor.BatchExecutor;
47
import org.apache.ibatis.executor.CachingExecutor;
48
import org.apache.ibatis.executor.Executor;
49
import org.apache.ibatis.executor.ReuseExecutor;
50
import org.apache.ibatis.executor.SimpleExecutor;
51
import org.apache.ibatis.executor.keygen.KeyGenerator;
52
import org.apache.ibatis.executor.loader.ProxyFactory;
53
import org.apache.ibatis.executor.loader.cglib.CglibProxyFactory;
54
import org.apache.ibatis.executor.loader.javassist.JavassistProxyFactory;
55
import org.apache.ibatis.executor.parameter.ParameterHandler;
56
import org.apache.ibatis.executor.resultset.DefaultResultSetHandler;
57
import org.apache.ibatis.executor.resultset.ResultSetHandler;
58
import org.apache.ibatis.executor.statement.RoutingStatementHandler;
59
import org.apache.ibatis.executor.statement.StatementHandler;
60
import org.apache.ibatis.io.VFS;
61
import org.apache.ibatis.logging.Log;
62
import org.apache.ibatis.logging.LogFactory;
63
import org.apache.ibatis.logging.commons.JakartaCommonsLoggingImpl;
64
import org.apache.ibatis.logging.jdk14.Jdk14LoggingImpl;
65
import org.apache.ibatis.logging.log4j.Log4jImpl;
66
import org.apache.ibatis.logging.log4j2.Log4j2Impl;
67
import org.apache.ibatis.logging.nologging.NoLoggingImpl;
68
import org.apache.ibatis.logging.slf4j.Slf4jImpl;
69
import org.apache.ibatis.logging.stdout.StdOutImpl;
70
import org.apache.ibatis.mapping.BoundSql;
71
import org.apache.ibatis.mapping.Environment;
72
import org.apache.ibatis.mapping.MappedStatement;
73
import org.apache.ibatis.mapping.ParameterMap;
74
import org.apache.ibatis.mapping.ResultMap;
75
import org.apache.ibatis.mapping.ResultSetType;
76
import org.apache.ibatis.mapping.VendorDatabaseIdProvider;
77
import org.apache.ibatis.parsing.XNode;
78
import org.apache.ibatis.plugin.Interceptor;
79
import org.apache.ibatis.plugin.InterceptorChain;
80
import org.apache.ibatis.reflection.DefaultReflectorFactory;
81
import org.apache.ibatis.reflection.MetaObject;
82
import org.apache.ibatis.reflection.ReflectorFactory;
83
import org.apache.ibatis.reflection.factory.DefaultObjectFactory;
84
import org.apache.ibatis.reflection.factory.ObjectFactory;
85
import org.apache.ibatis.reflection.wrapper.DefaultObjectWrapperFactory;
86
import org.apache.ibatis.reflection.wrapper.ObjectWrapperFactory;
87
import org.apache.ibatis.scripting.LanguageDriver;
88
import org.apache.ibatis.scripting.LanguageDriverRegistry;
89
import org.apache.ibatis.scripting.defaults.RawLanguageDriver;
90
import org.apache.ibatis.scripting.xmltags.XMLLanguageDriver;
91
import org.apache.ibatis.transaction.Transaction;
92
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
93
import org.apache.ibatis.transaction.managed.ManagedTransactionFactory;
94
import org.apache.ibatis.type.JdbcType;
95
import org.apache.ibatis.type.TypeAliasRegistry;
96
import org.apache.ibatis.type.TypeHandler;
97
import org.apache.ibatis.type.TypeHandlerRegistry;
98

99
/**
100
 * @author Clinton Begin
101
 */
102
public class Configuration {
103

104
  protected Environment environment;
105

106
  protected boolean safeRowBoundsEnabled;
107
  protected boolean safeResultHandlerEnabled = true;
1✔
108
  protected boolean mapUnderscoreToCamelCase;
109
  protected boolean aggressiveLazyLoading;
110
  protected boolean multipleResultSetsEnabled = true;
1✔
111
  protected boolean useGeneratedKeys;
112
  protected boolean useColumnLabel = true;
1✔
113
  protected boolean cacheEnabled = true;
1✔
114
  protected boolean callSettersOnNulls;
115
  protected boolean useActualParamName = true;
1✔
116
  protected boolean returnInstanceForEmptyRow;
117
  protected boolean shrinkWhitespacesInSql;
118
  protected boolean nullableOnForEach;
119
  protected boolean argNameBasedConstructorAutoMapping;
120

121
  protected String logPrefix;
122
  protected Class<? extends Log> logImpl;
123
  protected Class<? extends VFS> vfsImpl;
124
  protected Class<?> defaultSqlProviderType;
125
  protected LocalCacheScope localCacheScope = LocalCacheScope.SESSION;
1✔
126
  protected JdbcType jdbcTypeForNull = JdbcType.OTHER;
1✔
127
  protected Set<String> lazyLoadTriggerMethods = new HashSet<>(
1✔
128
      Arrays.asList("equals", "clone", "hashCode", "toString"));
1✔
129
  protected Integer defaultStatementTimeout;
130
  protected Integer defaultFetchSize;
131
  protected ResultSetType defaultResultSetType;
132
  protected ExecutorType defaultExecutorType = ExecutorType.SIMPLE;
1✔
133
  protected AutoMappingBehavior autoMappingBehavior = AutoMappingBehavior.PARTIAL;
1✔
134
  protected AutoMappingUnknownColumnBehavior autoMappingUnknownColumnBehavior = AutoMappingUnknownColumnBehavior.NONE;
1✔
135

136
  protected Properties variables = new Properties();
1✔
137
  protected ReflectorFactory reflectorFactory = new DefaultReflectorFactory();
1✔
138
  protected ObjectFactory objectFactory = new DefaultObjectFactory();
1✔
139
  protected ObjectWrapperFactory objectWrapperFactory = new DefaultObjectWrapperFactory();
1✔
140

141
  protected boolean lazyLoadingEnabled;
142
  protected ProxyFactory proxyFactory = new JavassistProxyFactory(); // #224 Using internal Javassist instead of OGNL
1✔
143

144
  protected String databaseId;
145
  /**
146
   * Configuration factory class. Used to create Configuration for loading deserialized unread properties.
147
   *
148
   * @see <a href='https://github.com/mybatis/old-google-code-issues/issues/300'>Issue 300 (google code)</a>
149
   */
150
  protected Class<?> configurationFactory;
151

152
  protected final MapperRegistry mapperRegistry = new MapperRegistry(this);
1✔
153
  protected final InterceptorChain interceptorChain = new InterceptorChain();
1✔
154
  protected final TypeHandlerRegistry typeHandlerRegistry = new TypeHandlerRegistry(this);
1✔
155
  protected final TypeAliasRegistry typeAliasRegistry = new TypeAliasRegistry();
1✔
156
  protected final LanguageDriverRegistry languageRegistry = new LanguageDriverRegistry();
1✔
157

158
  protected final Map<String, MappedStatement> mappedStatements = new StrictMap<MappedStatement>(
1✔
159
      "Mapped Statements collection")
160
          .conflictMessageProducer((savedValue, targetValue) -> ". please check " + savedValue.getResource() + " and "
1✔
161
              + targetValue.getResource());
1✔
162
  protected final Map<String, Cache> caches = new StrictMap<>("Caches collection");
1✔
163
  protected final Map<String, ResultMap> resultMaps = new StrictMap<>("Result Maps collection");
1✔
164
  protected final Map<String, ParameterMap> parameterMaps = new StrictMap<>("Parameter Maps collection");
1✔
165
  protected final Map<String, KeyGenerator> keyGenerators = new StrictMap<>("Key Generators collection");
1✔
166

167
  protected final Set<String> loadedResources = new HashSet<>();
1✔
168
  protected final Map<String, XNode> sqlFragments = new StrictMap<>("XML fragments parsed from previous mappers");
1✔
169

170
  protected final Collection<XMLStatementBuilder> incompleteStatements = new LinkedList<>();
1✔
171
  protected final Collection<CacheRefResolver> incompleteCacheRefs = new LinkedList<>();
1✔
172
  protected final Collection<ResultMapResolver> incompleteResultMaps = new LinkedList<>();
1✔
173
  protected final Collection<MethodResolver> incompleteMethods = new LinkedList<>();
1✔
174

175
  /*
176
   * A map holds cache-ref relationship. The key is the namespace that references a cache bound to another namespace and
177
   * the value is the namespace which the actual cache is bound to.
178
   */
179
  protected final Map<String, String> cacheRefMap = new HashMap<>();
1✔
180

181
  public Configuration(Environment environment) {
182
    this();
1✔
183
    this.environment = environment;
1✔
184
  }
1✔
185

186
  public Configuration() {
1✔
187
    typeAliasRegistry.registerAlias("JDBC", JdbcTransactionFactory.class);
1✔
188
    typeAliasRegistry.registerAlias("MANAGED", ManagedTransactionFactory.class);
1✔
189

190
    typeAliasRegistry.registerAlias("JNDI", JndiDataSourceFactory.class);
1✔
191
    typeAliasRegistry.registerAlias("POOLED", PooledDataSourceFactory.class);
1✔
192
    typeAliasRegistry.registerAlias("UNPOOLED", UnpooledDataSourceFactory.class);
1✔
193

194
    typeAliasRegistry.registerAlias("PERPETUAL", PerpetualCache.class);
1✔
195
    typeAliasRegistry.registerAlias("FIFO", FifoCache.class);
1✔
196
    typeAliasRegistry.registerAlias("LRU", LruCache.class);
1✔
197
    typeAliasRegistry.registerAlias("SOFT", SoftCache.class);
1✔
198
    typeAliasRegistry.registerAlias("WEAK", WeakCache.class);
1✔
199

200
    typeAliasRegistry.registerAlias("DB_VENDOR", VendorDatabaseIdProvider.class);
1✔
201

202
    typeAliasRegistry.registerAlias("XML", XMLLanguageDriver.class);
1✔
203
    typeAliasRegistry.registerAlias("RAW", RawLanguageDriver.class);
1✔
204

205
    typeAliasRegistry.registerAlias("SLF4J", Slf4jImpl.class);
1✔
206
    typeAliasRegistry.registerAlias("COMMONS_LOGGING", JakartaCommonsLoggingImpl.class);
1✔
207
    typeAliasRegistry.registerAlias("LOG4J", Log4jImpl.class);
1✔
208
    typeAliasRegistry.registerAlias("LOG4J2", Log4j2Impl.class);
1✔
209
    typeAliasRegistry.registerAlias("JDK_LOGGING", Jdk14LoggingImpl.class);
1✔
210
    typeAliasRegistry.registerAlias("STDOUT_LOGGING", StdOutImpl.class);
1✔
211
    typeAliasRegistry.registerAlias("NO_LOGGING", NoLoggingImpl.class);
1✔
212

213
    typeAliasRegistry.registerAlias("CGLIB", CglibProxyFactory.class);
1✔
214
    typeAliasRegistry.registerAlias("JAVASSIST", JavassistProxyFactory.class);
1✔
215

216
    languageRegistry.setDefaultDriverClass(XMLLanguageDriver.class);
1✔
217
    languageRegistry.register(RawLanguageDriver.class);
1✔
218
  }
1✔
219

220
  public String getLogPrefix() {
221
    return logPrefix;
1✔
222
  }
223

224
  public void setLogPrefix(String logPrefix) {
225
    this.logPrefix = logPrefix;
1✔
226
  }
1✔
227

228
  public Class<? extends Log> getLogImpl() {
229
    return logImpl;
1✔
230
  }
231

232
  public void setLogImpl(Class<? extends Log> logImpl) {
233
    if (logImpl != null) {
1✔
234
      this.logImpl = logImpl;
1✔
235
      LogFactory.useCustomLogging(this.logImpl);
1✔
236
    }
237
  }
1✔
238

239
  public Class<? extends VFS> getVfsImpl() {
240
    return this.vfsImpl;
×
241
  }
242

243
  public void setVfsImpl(Class<? extends VFS> vfsImpl) {
244
    if (vfsImpl != null) {
×
245
      this.vfsImpl = vfsImpl;
×
246
      VFS.addImplClass(this.vfsImpl);
×
247
    }
248
  }
×
249

250
  /**
251
   * Gets an applying type when omit a type on sql provider annotation(e.g.
252
   * {@link org.apache.ibatis.annotations.SelectProvider}).
253
   *
254
   * @return the default type for sql provider annotation
255
   *
256
   * @since 3.5.6
257
   */
258
  public Class<?> getDefaultSqlProviderType() {
259
    return defaultSqlProviderType;
1✔
260
  }
261

262
  /**
263
   * Sets an applying type when omit a type on sql provider annotation(e.g.
264
   * {@link org.apache.ibatis.annotations.SelectProvider}).
265
   *
266
   * @param defaultSqlProviderType
267
   *          the default type for sql provider annotation
268
   *
269
   * @since 3.5.6
270
   */
271
  public void setDefaultSqlProviderType(Class<?> defaultSqlProviderType) {
272
    this.defaultSqlProviderType = defaultSqlProviderType;
1✔
273
  }
1✔
274

275
  public boolean isCallSettersOnNulls() {
276
    return callSettersOnNulls;
1✔
277
  }
278

279
  public void setCallSettersOnNulls(boolean callSettersOnNulls) {
280
    this.callSettersOnNulls = callSettersOnNulls;
1✔
281
  }
1✔
282

283
  public boolean isUseActualParamName() {
284
    return useActualParamName;
1✔
285
  }
286

287
  public void setUseActualParamName(boolean useActualParamName) {
288
    this.useActualParamName = useActualParamName;
1✔
289
  }
1✔
290

291
  public boolean isReturnInstanceForEmptyRow() {
292
    return returnInstanceForEmptyRow;
1✔
293
  }
294

295
  public void setReturnInstanceForEmptyRow(boolean returnEmptyInstance) {
296
    this.returnInstanceForEmptyRow = returnEmptyInstance;
1✔
297
  }
1✔
298

299
  public boolean isShrinkWhitespacesInSql() {
300
    return shrinkWhitespacesInSql;
1✔
301
  }
302

303
  public void setShrinkWhitespacesInSql(boolean shrinkWhitespacesInSql) {
304
    this.shrinkWhitespacesInSql = shrinkWhitespacesInSql;
1✔
305
  }
1✔
306

307
  /**
308
   * Sets the default value of 'nullable' attribute on 'foreach' tag.
309
   *
310
   * @param nullableOnForEach
311
   *          If nullable, set to {@code true}
312
   *
313
   * @since 3.5.9
314
   */
315
  public void setNullableOnForEach(boolean nullableOnForEach) {
316
    this.nullableOnForEach = nullableOnForEach;
1✔
317
  }
1✔
318

319
  /**
320
   * Returns the default value of 'nullable' attribute on 'foreach' tag.
321
   * <p>
322
   * Default is {@code false}.
323
   *
324
   * @return If nullable, set to {@code true}
325
   *
326
   * @since 3.5.9
327
   */
328
  public boolean isNullableOnForEach() {
329
    return nullableOnForEach;
1✔
330
  }
331

332
  public boolean isArgNameBasedConstructorAutoMapping() {
333
    return argNameBasedConstructorAutoMapping;
1✔
334
  }
335

336
  public void setArgNameBasedConstructorAutoMapping(boolean argNameBasedConstructorAutoMapping) {
337
    this.argNameBasedConstructorAutoMapping = argNameBasedConstructorAutoMapping;
1✔
338
  }
1✔
339

340
  public String getDatabaseId() {
341
    return databaseId;
1✔
342
  }
343

344
  public void setDatabaseId(String databaseId) {
345
    this.databaseId = databaseId;
1✔
346
  }
1✔
347

348
  public Class<?> getConfigurationFactory() {
349
    return configurationFactory;
1✔
350
  }
351

352
  public void setConfigurationFactory(Class<?> configurationFactory) {
353
    this.configurationFactory = configurationFactory;
1✔
354
  }
1✔
355

356
  public boolean isSafeResultHandlerEnabled() {
357
    return safeResultHandlerEnabled;
1✔
358
  }
359

360
  public void setSafeResultHandlerEnabled(boolean safeResultHandlerEnabled) {
361
    this.safeResultHandlerEnabled = safeResultHandlerEnabled;
1✔
362
  }
1✔
363

364
  public boolean isSafeRowBoundsEnabled() {
365
    return safeRowBoundsEnabled;
1✔
366
  }
367

368
  public void setSafeRowBoundsEnabled(boolean safeRowBoundsEnabled) {
369
    this.safeRowBoundsEnabled = safeRowBoundsEnabled;
1✔
370
  }
1✔
371

372
  public boolean isMapUnderscoreToCamelCase() {
373
    return mapUnderscoreToCamelCase;
1✔
374
  }
375

376
  public void setMapUnderscoreToCamelCase(boolean mapUnderscoreToCamelCase) {
377
    this.mapUnderscoreToCamelCase = mapUnderscoreToCamelCase;
1✔
378
  }
1✔
379

380
  public void addLoadedResource(String resource) {
381
    loadedResources.add(resource);
1✔
382
  }
1✔
383

384
  public boolean isResourceLoaded(String resource) {
385
    return loadedResources.contains(resource);
1✔
386
  }
387

388
  public Environment getEnvironment() {
389
    return environment;
1✔
390
  }
391

392
  public void setEnvironment(Environment environment) {
393
    this.environment = environment;
1✔
394
  }
1✔
395

396
  public AutoMappingBehavior getAutoMappingBehavior() {
397
    return autoMappingBehavior;
1✔
398
  }
399

400
  public void setAutoMappingBehavior(AutoMappingBehavior autoMappingBehavior) {
401
    this.autoMappingBehavior = autoMappingBehavior;
1✔
402
  }
1✔
403

404
  /**
405
   * Gets the auto mapping unknown column behavior.
406
   *
407
   * @return the auto mapping unknown column behavior
408
   *
409
   * @since 3.4.0
410
   */
411
  public AutoMappingUnknownColumnBehavior getAutoMappingUnknownColumnBehavior() {
412
    return autoMappingUnknownColumnBehavior;
1✔
413
  }
414

415
  /**
416
   * Sets the auto mapping unknown column behavior.
417
   *
418
   * @param autoMappingUnknownColumnBehavior
419
   *          the new auto mapping unknown column behavior
420
   *
421
   * @since 3.4.0
422
   */
423
  public void setAutoMappingUnknownColumnBehavior(AutoMappingUnknownColumnBehavior autoMappingUnknownColumnBehavior) {
424
    this.autoMappingUnknownColumnBehavior = autoMappingUnknownColumnBehavior;
1✔
425
  }
1✔
426

427
  public boolean isLazyLoadingEnabled() {
428
    return lazyLoadingEnabled;
1✔
429
  }
430

431
  public void setLazyLoadingEnabled(boolean lazyLoadingEnabled) {
432
    this.lazyLoadingEnabled = lazyLoadingEnabled;
1✔
433
  }
1✔
434

435
  public ProxyFactory getProxyFactory() {
436
    return proxyFactory;
1✔
437
  }
438

439
  public void setProxyFactory(ProxyFactory proxyFactory) {
440
    if (proxyFactory == null) {
1✔
441
      proxyFactory = new JavassistProxyFactory();
1✔
442
    }
443
    this.proxyFactory = proxyFactory;
1✔
444
  }
1✔
445

446
  public boolean isAggressiveLazyLoading() {
447
    return aggressiveLazyLoading;
1✔
448
  }
449

450
  public void setAggressiveLazyLoading(boolean aggressiveLazyLoading) {
451
    this.aggressiveLazyLoading = aggressiveLazyLoading;
1✔
452
  }
1✔
453

454
  public boolean isMultipleResultSetsEnabled() {
455
    return multipleResultSetsEnabled;
1✔
456
  }
457

458
  public void setMultipleResultSetsEnabled(boolean multipleResultSetsEnabled) {
459
    this.multipleResultSetsEnabled = multipleResultSetsEnabled;
1✔
460
  }
1✔
461

462
  public Set<String> getLazyLoadTriggerMethods() {
463
    return lazyLoadTriggerMethods;
1✔
464
  }
465

466
  public void setLazyLoadTriggerMethods(Set<String> lazyLoadTriggerMethods) {
467
    this.lazyLoadTriggerMethods = lazyLoadTriggerMethods;
1✔
468
  }
1✔
469

470
  public boolean isUseGeneratedKeys() {
471
    return useGeneratedKeys;
1✔
472
  }
473

474
  public void setUseGeneratedKeys(boolean useGeneratedKeys) {
475
    this.useGeneratedKeys = useGeneratedKeys;
1✔
476
  }
1✔
477

478
  public ExecutorType getDefaultExecutorType() {
479
    return defaultExecutorType;
1✔
480
  }
481

482
  public void setDefaultExecutorType(ExecutorType defaultExecutorType) {
483
    this.defaultExecutorType = defaultExecutorType;
1✔
484
  }
1✔
485

486
  public boolean isCacheEnabled() {
487
    return cacheEnabled;
1✔
488
  }
489

490
  public void setCacheEnabled(boolean cacheEnabled) {
491
    this.cacheEnabled = cacheEnabled;
1✔
492
  }
1✔
493

494
  public Integer getDefaultStatementTimeout() {
495
    return defaultStatementTimeout;
1✔
496
  }
497

498
  public void setDefaultStatementTimeout(Integer defaultStatementTimeout) {
499
    this.defaultStatementTimeout = defaultStatementTimeout;
1✔
500
  }
1✔
501

502
  /**
503
   * Gets the default fetch size.
504
   *
505
   * @return the default fetch size
506
   *
507
   * @since 3.3.0
508
   */
509
  public Integer getDefaultFetchSize() {
510
    return defaultFetchSize;
1✔
511
  }
512

513
  /**
514
   * Sets the default fetch size.
515
   *
516
   * @param defaultFetchSize
517
   *          the new default fetch size
518
   *
519
   * @since 3.3.0
520
   */
521
  public void setDefaultFetchSize(Integer defaultFetchSize) {
522
    this.defaultFetchSize = defaultFetchSize;
1✔
523
  }
1✔
524

525
  /**
526
   * Gets the default result set type.
527
   *
528
   * @return the default result set type
529
   *
530
   * @since 3.5.2
531
   */
532
  public ResultSetType getDefaultResultSetType() {
533
    return defaultResultSetType;
1✔
534
  }
535

536
  /**
537
   * Sets the default result set type.
538
   *
539
   * @param defaultResultSetType
540
   *          the new default result set type
541
   *
542
   * @since 3.5.2
543
   */
544
  public void setDefaultResultSetType(ResultSetType defaultResultSetType) {
545
    this.defaultResultSetType = defaultResultSetType;
1✔
546
  }
1✔
547

548
  public boolean isUseColumnLabel() {
549
    return useColumnLabel;
1✔
550
  }
551

552
  public void setUseColumnLabel(boolean useColumnLabel) {
553
    this.useColumnLabel = useColumnLabel;
1✔
554
  }
1✔
555

556
  public LocalCacheScope getLocalCacheScope() {
557
    return localCacheScope;
1✔
558
  }
559

560
  public void setLocalCacheScope(LocalCacheScope localCacheScope) {
561
    this.localCacheScope = localCacheScope;
1✔
562
  }
1✔
563

564
  public JdbcType getJdbcTypeForNull() {
565
    return jdbcTypeForNull;
1✔
566
  }
567

568
  public void setJdbcTypeForNull(JdbcType jdbcTypeForNull) {
569
    this.jdbcTypeForNull = jdbcTypeForNull;
1✔
570
  }
1✔
571

572
  public Properties getVariables() {
573
    return variables;
1✔
574
  }
575

576
  public void setVariables(Properties variables) {
577
    this.variables = variables;
1✔
578
  }
1✔
579

580
  public TypeHandlerRegistry getTypeHandlerRegistry() {
581
    return typeHandlerRegistry;
1✔
582
  }
583

584
  /**
585
   * Set a default {@link TypeHandler} class for {@link Enum}. A default {@link TypeHandler} is
586
   * {@link org.apache.ibatis.type.EnumTypeHandler}.
587
   *
588
   * @param typeHandler
589
   *          a type handler class for {@link Enum}
590
   *
591
   * @since 3.4.5
592
   */
593
  public void setDefaultEnumTypeHandler(Class<? extends TypeHandler> typeHandler) {
594
    if (typeHandler != null) {
1✔
595
      getTypeHandlerRegistry().setDefaultEnumTypeHandler(typeHandler);
×
596
    }
597
  }
1✔
598

599
  public TypeAliasRegistry getTypeAliasRegistry() {
600
    return typeAliasRegistry;
1✔
601
  }
602

603
  /**
604
   * Gets the mapper registry.
605
   *
606
   * @return the mapper registry
607
   *
608
   * @since 3.2.2
609
   */
610
  public MapperRegistry getMapperRegistry() {
611
    return mapperRegistry;
1✔
612
  }
613

614
  public ReflectorFactory getReflectorFactory() {
615
    return reflectorFactory;
1✔
616
  }
617

618
  public void setReflectorFactory(ReflectorFactory reflectorFactory) {
619
    this.reflectorFactory = reflectorFactory;
×
620
  }
×
621

622
  public ObjectFactory getObjectFactory() {
623
    return objectFactory;
1✔
624
  }
625

626
  public void setObjectFactory(ObjectFactory objectFactory) {
627
    this.objectFactory = objectFactory;
1✔
628
  }
1✔
629

630
  public ObjectWrapperFactory getObjectWrapperFactory() {
631
    return objectWrapperFactory;
1✔
632
  }
633

634
  public void setObjectWrapperFactory(ObjectWrapperFactory objectWrapperFactory) {
635
    this.objectWrapperFactory = objectWrapperFactory;
1✔
636
  }
1✔
637

638
  /**
639
   * Gets the interceptors.
640
   *
641
   * @return the interceptors
642
   *
643
   * @since 3.2.2
644
   */
645
  public List<Interceptor> getInterceptors() {
646
    return interceptorChain.getInterceptors();
×
647
  }
648

649
  public LanguageDriverRegistry getLanguageRegistry() {
650
    return languageRegistry;
1✔
651
  }
652

653
  public void setDefaultScriptingLanguage(Class<? extends LanguageDriver> driver) {
654
    if (driver == null) {
1✔
655
      driver = XMLLanguageDriver.class;
1✔
656
    }
657
    getLanguageRegistry().setDefaultDriverClass(driver);
1✔
658
  }
1✔
659

660
  public LanguageDriver getDefaultScriptingLanguageInstance() {
661
    return languageRegistry.getDefaultDriver();
1✔
662
  }
663

664
  /**
665
   * Gets the language driver.
666
   *
667
   * @param langClass
668
   *          the lang class
669
   *
670
   * @return the language driver
671
   *
672
   * @since 3.5.1
673
   */
674
  public LanguageDriver getLanguageDriver(Class<? extends LanguageDriver> langClass) {
675
    if (langClass == null) {
1✔
676
      return languageRegistry.getDefaultDriver();
1✔
677
    }
678
    languageRegistry.register(langClass);
1✔
679
    return languageRegistry.getDriver(langClass);
1✔
680
  }
681

682
  /**
683
   * Gets the default scripting language instance.
684
   *
685
   * @return the default scripting language instance
686
   *
687
   * @deprecated Use {@link #getDefaultScriptingLanguageInstance()}
688
   */
689
  @Deprecated
690
  public LanguageDriver getDefaultScriptingLanuageInstance() {
691
    return getDefaultScriptingLanguageInstance();
1✔
692
  }
693

694
  public MetaObject newMetaObject(Object object) {
695
    return MetaObject.forObject(object, objectFactory, objectWrapperFactory, reflectorFactory);
1✔
696
  }
697

698
  public ParameterHandler newParameterHandler(MappedStatement mappedStatement, Object parameterObject,
699
      BoundSql boundSql) {
700
    ParameterHandler parameterHandler = mappedStatement.getLang().createParameterHandler(mappedStatement,
1✔
701
        parameterObject, boundSql);
702
    return (ParameterHandler) interceptorChain.pluginAll(parameterHandler);
1✔
703
  }
704

705
  public ResultSetHandler newResultSetHandler(Executor executor, MappedStatement mappedStatement, RowBounds rowBounds,
706
      ParameterHandler parameterHandler, ResultHandler resultHandler, BoundSql boundSql) {
707
    ResultSetHandler resultSetHandler = new DefaultResultSetHandler(executor, mappedStatement, parameterHandler,
1✔
708
        resultHandler, boundSql, rowBounds);
709
    return (ResultSetHandler) interceptorChain.pluginAll(resultSetHandler);
1✔
710
  }
711

712
  public StatementHandler newStatementHandler(Executor executor, MappedStatement mappedStatement,
713
      Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
714
    StatementHandler statementHandler = new RoutingStatementHandler(executor, mappedStatement, parameterObject,
1✔
715
        rowBounds, resultHandler, boundSql);
716
    return (StatementHandler) interceptorChain.pluginAll(statementHandler);
1✔
717
  }
718

719
  public Executor newExecutor(Transaction transaction) {
720
    return newExecutor(transaction, defaultExecutorType);
×
721
  }
722

723
  public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
724
    executorType = executorType == null ? defaultExecutorType : executorType;
1✔
725
    Executor executor;
726
    if (ExecutorType.BATCH == executorType) {
1✔
727
      executor = new BatchExecutor(this, transaction);
1✔
728
    } else if (ExecutorType.REUSE == executorType) {
1✔
729
      executor = new ReuseExecutor(this, transaction);
1✔
730
    } else {
731
      executor = new SimpleExecutor(this, transaction);
1✔
732
    }
733
    if (cacheEnabled) {
1✔
734
      executor = new CachingExecutor(executor);
1✔
735
    }
736
    return (Executor) interceptorChain.pluginAll(executor);
1✔
737
  }
738

739
  public void addKeyGenerator(String id, KeyGenerator keyGenerator) {
740
    keyGenerators.put(id, keyGenerator);
1✔
741
  }
1✔
742

743
  public Collection<String> getKeyGeneratorNames() {
744
    return keyGenerators.keySet();
×
745
  }
746

747
  public Collection<KeyGenerator> getKeyGenerators() {
748
    return keyGenerators.values();
×
749
  }
750

751
  public KeyGenerator getKeyGenerator(String id) {
752
    return keyGenerators.get(id);
1✔
753
  }
754

755
  public boolean hasKeyGenerator(String id) {
756
    return keyGenerators.containsKey(id);
1✔
757
  }
758

759
  public void addCache(Cache cache) {
760
    caches.put(cache.getId(), cache);
1✔
761
  }
1✔
762

763
  public Collection<String> getCacheNames() {
764
    return caches.keySet();
×
765
  }
766

767
  public Collection<Cache> getCaches() {
768
    return caches.values();
×
769
  }
770

771
  public Cache getCache(String id) {
772
    return caches.get(id);
1✔
773
  }
774

775
  public boolean hasCache(String id) {
776
    return caches.containsKey(id);
×
777
  }
778

779
  public void addResultMap(ResultMap rm) {
780
    resultMaps.put(rm.getId(), rm);
1✔
781
    checkLocallyForDiscriminatedNestedResultMaps(rm);
1✔
782
    checkGloballyForDiscriminatedNestedResultMaps(rm);
1✔
783
  }
1✔
784

785
  public Collection<String> getResultMapNames() {
786
    return resultMaps.keySet();
×
787
  }
788

789
  public Collection<ResultMap> getResultMaps() {
790
    return resultMaps.values();
1✔
791
  }
792

793
  public ResultMap getResultMap(String id) {
794
    return resultMaps.get(id);
1✔
795
  }
796

797
  public boolean hasResultMap(String id) {
798
    return resultMaps.containsKey(id);
1✔
799
  }
800

801
  public void addParameterMap(ParameterMap pm) {
802
    parameterMaps.put(pm.getId(), pm);
1✔
803
  }
1✔
804

805
  public Collection<String> getParameterMapNames() {
806
    return parameterMaps.keySet();
×
807
  }
808

809
  public Collection<ParameterMap> getParameterMaps() {
810
    return parameterMaps.values();
×
811
  }
812

813
  public ParameterMap getParameterMap(String id) {
814
    return parameterMaps.get(id);
1✔
815
  }
816

817
  public boolean hasParameterMap(String id) {
818
    return parameterMaps.containsKey(id);
×
819
  }
820

821
  public void addMappedStatement(MappedStatement ms) {
822
    mappedStatements.put(ms.getId(), ms);
1✔
823
  }
1✔
824

825
  public Collection<String> getMappedStatementNames() {
826
    buildAllStatements();
1✔
827
    return mappedStatements.keySet();
1✔
828
  }
829

830
  public Collection<MappedStatement> getMappedStatements() {
831
    buildAllStatements();
×
832
    return mappedStatements.values();
×
833
  }
834

835
  public Collection<XMLStatementBuilder> getIncompleteStatements() {
836
    return incompleteStatements;
1✔
837
  }
838

839
  public void addIncompleteStatement(XMLStatementBuilder incompleteStatement) {
840
    incompleteStatements.add(incompleteStatement);
1✔
841
  }
1✔
842

843
  public Collection<CacheRefResolver> getIncompleteCacheRefs() {
844
    return incompleteCacheRefs;
1✔
845
  }
846

847
  public void addIncompleteCacheRef(CacheRefResolver incompleteCacheRef) {
848
    incompleteCacheRefs.add(incompleteCacheRef);
1✔
849
  }
1✔
850

851
  public Collection<ResultMapResolver> getIncompleteResultMaps() {
852
    return incompleteResultMaps;
1✔
853
  }
854

855
  public void addIncompleteResultMap(ResultMapResolver resultMapResolver) {
856
    incompleteResultMaps.add(resultMapResolver);
1✔
857
  }
1✔
858

859
  public void addIncompleteMethod(MethodResolver builder) {
860
    incompleteMethods.add(builder);
1✔
861
  }
1✔
862

863
  public Collection<MethodResolver> getIncompleteMethods() {
864
    return incompleteMethods;
1✔
865
  }
866

867
  public MappedStatement getMappedStatement(String id) {
868
    return this.getMappedStatement(id, true);
1✔
869
  }
870

871
  public MappedStatement getMappedStatement(String id, boolean validateIncompleteStatements) {
872
    if (validateIncompleteStatements) {
1✔
873
      buildAllStatements();
1✔
874
    }
875
    return mappedStatements.get(id);
1✔
876
  }
877

878
  public Map<String, XNode> getSqlFragments() {
879
    return sqlFragments;
1✔
880
  }
881

882
  public void addInterceptor(Interceptor interceptor) {
883
    interceptorChain.addInterceptor(interceptor);
1✔
884
  }
1✔
885

886
  public void addMappers(String packageName, Class<?> superType) {
887
    mapperRegistry.addMappers(packageName, superType);
×
888
  }
×
889

890
  public void addMappers(String packageName) {
891
    mapperRegistry.addMappers(packageName);
1✔
892
  }
1✔
893

894
  public <T> void addMapper(Class<T> type) {
895
    mapperRegistry.addMapper(type);
1✔
896
  }
1✔
897

898
  public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
899
    return mapperRegistry.getMapper(type, sqlSession);
1✔
900
  }
901

902
  public boolean hasMapper(Class<?> type) {
903
    return mapperRegistry.hasMapper(type);
1✔
904
  }
905

906
  public boolean hasStatement(String statementName) {
907
    return hasStatement(statementName, true);
1✔
908
  }
909

910
  public boolean hasStatement(String statementName, boolean validateIncompleteStatements) {
911
    if (validateIncompleteStatements) {
1✔
912
      buildAllStatements();
1✔
913
    }
914
    return mappedStatements.containsKey(statementName);
1✔
915
  }
916

917
  public void addCacheRef(String namespace, String referencedNamespace) {
918
    cacheRefMap.put(namespace, referencedNamespace);
1✔
919
  }
1✔
920

921
  /*
922
   * Parses all the unprocessed statement nodes in the cache. It is recommended to call this method once all the mappers
923
   * are added as it provides fail-fast statement validation.
924
   */
925
  protected void buildAllStatements() {
926
    parsePendingResultMaps();
1✔
927
    if (!incompleteCacheRefs.isEmpty()) {
1✔
928
      synchronized (incompleteCacheRefs) {
1✔
929
        incompleteCacheRefs.removeIf(x -> x.resolveCacheRef() != null);
1✔
930
      }
1✔
931
    }
932
    if (!incompleteStatements.isEmpty()) {
1✔
933
      synchronized (incompleteStatements) {
1✔
934
        incompleteStatements.removeIf(x -> {
1✔
935
          x.parseStatementNode();
1✔
936
          return true;
1✔
937
        });
938
      }
1✔
939
    }
940
    if (!incompleteMethods.isEmpty()) {
1✔
941
      synchronized (incompleteMethods) {
1✔
942
        incompleteMethods.removeIf(x -> {
1✔
943
          x.resolve();
1✔
944
          return true;
1✔
945
        });
946
      }
1✔
947
    }
948
  }
1✔
949

950
  private void parsePendingResultMaps() {
951
    if (incompleteResultMaps.isEmpty()) {
1✔
952
      return;
1✔
953
    }
954
    synchronized (incompleteResultMaps) {
1✔
955
      boolean resolved;
956
      IncompleteElementException ex = null;
1✔
957
      do {
958
        resolved = false;
1✔
959
        Iterator<ResultMapResolver> iterator = incompleteResultMaps.iterator();
1✔
960
        while (iterator.hasNext()) {
1✔
961
          try {
962
            iterator.next().resolve();
1✔
963
            iterator.remove();
1✔
964
            resolved = true;
1✔
965
          } catch (IncompleteElementException e) {
1✔
966
            ex = e;
1✔
967
          }
1✔
968
        }
969
      } while (resolved);
1✔
970
      if (!incompleteResultMaps.isEmpty() && ex != null) {
1✔
971
        // At least one result map is unresolvable.
972
        throw ex;
×
973
      }
974
    }
1✔
975
  }
1✔
976

977
  /**
978
   * Extracts namespace from fully qualified statement id.
979
   *
980
   * @param statementId
981
   *          the statement id
982
   *
983
   * @return namespace or null when id does not contain period.
984
   */
985
  protected String extractNamespace(String statementId) {
986
    int lastPeriod = statementId.lastIndexOf('.');
×
987
    return lastPeriod > 0 ? statementId.substring(0, lastPeriod) : null;
×
988
  }
989

990
  // Slow but a one time cost. A better solution is welcome.
991
  protected void checkGloballyForDiscriminatedNestedResultMaps(ResultMap rm) {
992
    if (rm.hasNestedResultMaps()) {
1✔
993
      final String resultMapId = rm.getId();
1✔
994
      for (Object resultMapObject : resultMaps.values()) {
1✔
995
        if (resultMapObject instanceof ResultMap) {
1✔
996
          ResultMap entryResultMap = (ResultMap) resultMapObject;
1✔
997
          if (!entryResultMap.hasNestedResultMaps() && entryResultMap.getDiscriminator() != null) {
1✔
998
            Collection<String> discriminatedResultMapNames = entryResultMap.getDiscriminator().getDiscriminatorMap()
1✔
999
                .values();
1✔
1000
            if (discriminatedResultMapNames.contains(resultMapId)) {
1✔
1001
              entryResultMap.forceNestedResultMaps();
×
1002
            }
1003
          }
1004
        }
1005
      }
1✔
1006
    }
1007
  }
1✔
1008

1009
  // Slow but a one time cost. A better solution is welcome.
1010
  protected void checkLocallyForDiscriminatedNestedResultMaps(ResultMap rm) {
1011
    if (!rm.hasNestedResultMaps() && rm.getDiscriminator() != null) {
1✔
1012
      for (String discriminatedResultMapName : rm.getDiscriminator().getDiscriminatorMap().values()) {
1✔
1013
        if (hasResultMap(discriminatedResultMapName)) {
1✔
1014
          ResultMap discriminatedResultMap = resultMaps.get(discriminatedResultMapName);
1✔
1015
          if (discriminatedResultMap.hasNestedResultMaps()) {
1✔
1016
            rm.forceNestedResultMaps();
1✔
1017
            break;
1✔
1018
          }
1019
        }
1020
      }
1✔
1021
    }
1022
  }
1✔
1023

1024
  protected static class StrictMap<V> extends ConcurrentHashMap<String, V> {
1025

1026
    private static final long serialVersionUID = -4950446264854982944L;
1027
    private final String name;
1028
    private BiFunction<V, V, String> conflictMessageProducer;
1029

1030
    public StrictMap(String name, int initialCapacity, float loadFactor) {
1031
      super(initialCapacity, loadFactor);
×
1032
      this.name = name;
×
1033
    }
×
1034

1035
    public StrictMap(String name, int initialCapacity) {
1036
      super(initialCapacity);
×
1037
      this.name = name;
×
1038
    }
×
1039

1040
    public StrictMap(String name) {
1✔
1041
      this.name = name;
1✔
1042
    }
1✔
1043

1044
    public StrictMap(String name, Map<String, ? extends V> m) {
1045
      super(m);
×
1046
      this.name = name;
×
1047
    }
×
1048

1049
    /**
1050
     * Assign a function for producing a conflict error message when contains value with the same key.
1051
     * <p>
1052
     * function arguments are 1st is saved value and 2nd is target value.
1053
     *
1054
     * @param conflictMessageProducer
1055
     *          A function for producing a conflict error message
1056
     *
1057
     * @return a conflict error message
1058
     *
1059
     * @since 3.5.0
1060
     */
1061
    public StrictMap<V> conflictMessageProducer(BiFunction<V, V, String> conflictMessageProducer) {
1062
      this.conflictMessageProducer = conflictMessageProducer;
1✔
1063
      return this;
1✔
1064
    }
1065

1066
    @Override
1067
    @SuppressWarnings("unchecked")
1068
    public V put(String key, V value) {
1069
      if (containsKey(key)) {
1✔
1070
        throw new IllegalArgumentException(name + " already contains key " + key
1✔
1071
            + (conflictMessageProducer == null ? "" : conflictMessageProducer.apply(super.get(key), value)));
1✔
1072
      }
1073
      if (key.contains(".")) {
1✔
1074
        final String shortKey = getShortName(key);
1✔
1075
        if (super.get(shortKey) == null) {
1✔
1076
          super.put(shortKey, value);
1✔
1077
        } else {
1078
          super.put(shortKey, (V) new Ambiguity(shortKey));
1✔
1079
        }
1080
      }
1081
      return super.put(key, value);
1✔
1082
    }
1083

1084
    @Override
1085
    public boolean containsKey(Object key) {
1086
      if (key == null) {
1✔
1087
        return false;
1✔
1088
      }
1089

1090
      return super.get(key) != null;
1✔
1091
    }
1092

1093
    @Override
1094
    public V get(Object key) {
1095
      V value = super.get(key);
1✔
1096
      if (value == null) {
1✔
1097
        throw new IllegalArgumentException(name + " does not contain value for " + key);
1✔
1098
      }
1099
      if (value instanceof Ambiguity) {
1✔
1100
        throw new IllegalArgumentException(((Ambiguity) value).getSubject() + " is ambiguous in " + name
1✔
1101
            + " (try using the full name including the namespace, or rename one of the entries)");
1102
      }
1103
      return value;
1✔
1104
    }
1105

1106
    protected static class Ambiguity {
1107
      private final String subject;
1108

1109
      public Ambiguity(String subject) {
1✔
1110
        this.subject = subject;
1✔
1111
      }
1✔
1112

1113
      public String getSubject() {
1114
        return subject;
1✔
1115
      }
1116
    }
1117

1118
    private String getShortName(String key) {
1119
      final String[] keyParts = key.split("\\.");
1✔
1120
      return keyParts[keyParts.length - 1];
1✔
1121
    }
1122
  }
1123

1124
}
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

© 2026 Coveralls, Inc