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

mybatis / generator / 1950

15 Jan 2026 10:12PM UTC coverage: 88.976% (+0.06%) from 88.914%
1950

Pull #1416

github

web-flow
Merge 542424ec6 into e55778ad1
Pull Request #1416: Major Refactoring - IntrospectedTable No Longer Responsible for Code Generation, Plugins Potentially Impacted

2342 of 3166 branches covered (73.97%)

439 of 500 new or added lines in 26 files covered. (87.8%)

9 existing lines in 3 files now uncovered.

11582 of 13017 relevant lines covered (88.98%)

0.89 hits per line

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

95.66
/core/mybatis-generator-core/src/main/java/org/mybatis/generator/api/IntrospectedTable.java
1
/*
2
 *    Copyright 2006-2026 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.mybatis.generator.api;
17

18
import static org.mybatis.generator.internal.util.StringUtility.isTrue;
19
import static org.mybatis.generator.internal.util.StringUtility.stringHasValue;
20

21
import java.util.ArrayList;
22
import java.util.EnumMap;
23
import java.util.HashMap;
24
import java.util.Iterator;
25
import java.util.List;
26
import java.util.Map;
27
import java.util.Objects;
28
import java.util.Optional;
29
import java.util.Properties;
30
import java.util.function.Function;
31
import java.util.stream.Stream;
32

33
import org.jspecify.annotations.Nullable;
34
import org.mybatis.generator.config.Context;
35
import org.mybatis.generator.config.GeneratedKey;
36
import org.mybatis.generator.config.JavaModelGeneratorConfiguration;
37
import org.mybatis.generator.config.PropertyHolder;
38
import org.mybatis.generator.config.PropertyRegistry;
39
import org.mybatis.generator.config.TableConfiguration;
40
import org.mybatis.generator.internal.PluginAggregator;
41
import org.mybatis.generator.internal.rules.ConditionalModelRules;
42
import org.mybatis.generator.internal.rules.FlatModelRules;
43
import org.mybatis.generator.internal.rules.HierarchicalModelRules;
44
import org.mybatis.generator.internal.rules.Rules;
45

46
/**
47
 * Base class for all code generator implementations. This class provides many
48
 * of the housekeeping methods needed to implement a code generator, with only
49
 * the actual code generation methods left unimplemented.
50
 *
51
 * @author Jeff Butler
52
 */
53
public class IntrospectedTable {
54
    protected enum InternalAttribute {
1✔
55
        ATTR_PRIMARY_KEY_TYPE,
1✔
56
        ATTR_BASE_RECORD_TYPE,
1✔
57
        ATTR_RECORD_WITH_BLOBS_TYPE,
1✔
58
        ATTR_EXAMPLE_TYPE,
1✔
59
        ATTR_MYBATIS3_XML_MAPPER_PACKAGE,
1✔
60
        ATTR_MYBATIS3_XML_MAPPER_FILE_NAME,
1✔
61
        /** also used as XML Mapper namespace if a Java mapper is generated. */
62
        ATTR_MYBATIS3_JAVA_MAPPER_TYPE,
1✔
63
        /** used as XML Mapper namespace if no client is generated. */
64
        ATTR_MYBATIS3_FALLBACK_SQL_MAP_NAMESPACE,
1✔
65
        ATTR_FULLY_QUALIFIED_TABLE_NAME_AT_RUNTIME,
1✔
66
        ATTR_ALIASED_FULLY_QUALIFIED_TABLE_NAME_AT_RUNTIME,
1✔
67
        ATTR_COUNT_BY_EXAMPLE_STATEMENT_ID,
1✔
68
        ATTR_DELETE_BY_EXAMPLE_STATEMENT_ID,
1✔
69
        ATTR_DELETE_BY_PRIMARY_KEY_STATEMENT_ID,
1✔
70
        ATTR_INSERT_STATEMENT_ID,
1✔
71
        ATTR_INSERT_SELECTIVE_STATEMENT_ID,
1✔
72
        ATTR_SELECT_ALL_STATEMENT_ID,
1✔
73
        ATTR_SELECT_BY_EXAMPLE_STATEMENT_ID,
1✔
74
        ATTR_SELECT_BY_EXAMPLE_WITH_BLOBS_STATEMENT_ID,
1✔
75
        ATTR_SELECT_BY_PRIMARY_KEY_STATEMENT_ID,
1✔
76
        ATTR_UPDATE_BY_EXAMPLE_STATEMENT_ID,
1✔
77
        ATTR_UPDATE_BY_EXAMPLE_SELECTIVE_STATEMENT_ID,
1✔
78
        ATTR_UPDATE_BY_EXAMPLE_WITH_BLOBS_STATEMENT_ID,
1✔
79
        ATTR_UPDATE_BY_PRIMARY_KEY_STATEMENT_ID,
1✔
80
        ATTR_UPDATE_BY_PRIMARY_KEY_SELECTIVE_STATEMENT_ID,
1✔
81
        ATTR_UPDATE_BY_PRIMARY_KEY_WITH_BLOBS_STATEMENT_ID,
1✔
82
        ATTR_BASE_RESULT_MAP_ID,
1✔
83
        ATTR_RESULT_MAP_WITH_BLOBS_ID,
1✔
84
        ATTR_EXAMPLE_WHERE_CLAUSE_ID,
1✔
85
        ATTR_BASE_COLUMN_LIST_ID,
1✔
86
        ATTR_BLOB_COLUMN_LIST_ID,
1✔
87
        ATTR_MYBATIS3_UPDATE_BY_EXAMPLE_WHERE_CLAUSE_ID,
1✔
88
        ATTR_MYBATIS3_SQL_PROVIDER_TYPE,
1✔
89
        ATTR_MYBATIS_DYNAMIC_SQL_SUPPORT_TYPE,
1✔
90
        ATTR_KOTLIN_RECORD_TYPE,
1✔
91
        ATTR_MYBATIS_DYNAMIC_SQL_TABLE_OBJECT_NAME
1✔
92
    }
93

94
    protected final TableConfiguration tableConfiguration;
95
    protected final FullyQualifiedTable fullyQualifiedTable;
96
    protected final Context context;
97
    protected Rules rules;
98
    protected final List<IntrospectedColumn> primaryKeyColumns = new ArrayList<>();
1✔
99
    protected final List<IntrospectedColumn> baseColumns = new ArrayList<>();
1✔
100
    protected final List<IntrospectedColumn> blobColumns = new ArrayList<>();
1✔
101
    protected final KnownRuntime knownRuntime;
102

103
    /**
104
     * Attributes may be used by plugins to capture table related state between
105
     * the different plugin calls.
106
     */
107
    protected final Map<String, Object> attributes = new HashMap<>();
1✔
108

109
    /** Internal attributes are used to store commonly accessed items by all code generators. */
110
    protected final Map<IntrospectedTable.InternalAttribute, String> internalAttributes =
1✔
111
            new EnumMap<>(InternalAttribute.class);
112

113
    /**
114
     * Table remarks retrieved from database metadata.
115
     */
116
    protected @Nullable String remarks;
117

118
    /**
119
     * Table type retrieved from database metadata.
120
     *
121
     * <p>Non-null in practice
122
     */
123
    protected @Nullable String tableType;
124

125
    protected IntrospectedTable(Builder builder) {
1✔
126
        this.knownRuntime = Objects.requireNonNull(builder.knownRuntime);
1✔
127
        this.tableConfiguration = Objects.requireNonNull(builder.tableConfiguration);
1✔
128
        this.fullyQualifiedTable = Objects.requireNonNull(builder.fullyQualifiedTable);
1✔
129
        this.context = Objects.requireNonNull(builder.context);
1✔
130
        Objects.requireNonNull(builder.pluginAggregator);
1✔
131

132
        calculateJavaClientAttributes();
1✔
133
        calculateModelAttributes();
1✔
134
        calculateXmlAttributes();
1✔
135

136
        switch (getTableConfiguration().getModelType()) {
1!
137
        case HIERARCHICAL:
138
            rules = new HierarchicalModelRules(this);
1✔
139
            break;
1✔
140
        case FLAT:
141
            rules = new FlatModelRules(this);
1✔
142
            break;
1✔
143
        case CONDITIONAL:
144
            rules = new ConditionalModelRules(this);
1✔
145
            break;
1✔
146
        default:
NEW
147
            throw new IllegalArgumentException("Unknown model type: " + getTableConfiguration().getModelType());
×
148
        }
149

150
        builder.pluginAggregator.initialized(this);
1✔
151
    }
1✔
152

153
    public FullyQualifiedTable getFullyQualifiedTable() {
154
        return Objects.requireNonNull(fullyQualifiedTable);
1✔
155
    }
156

157
    public Optional<String> getSelectByExampleQueryId() {
158
        return getTableConfiguration().getSelectByExampleQueryId();
1✔
159
    }
160

161
    public Optional<String> getSelectByPrimaryKeyQueryId() {
162
        return getTableConfiguration().getSelectByPrimaryKeyQueryId();
1✔
163
    }
164

165
    public Optional<GeneratedKey> getGeneratedKey() {
166
        return getTableConfiguration().getGeneratedKey();
1✔
167
    }
168

169
    public Optional<IntrospectedColumn> getColumn(String columnName) {
170
        return Stream.of(primaryKeyColumns.stream(), baseColumns.stream(), blobColumns.stream())
1✔
171
                .flatMap(Function.identity())
1✔
172
                .filter(ic -> columnMatches(ic, columnName))
1✔
173
                .findFirst();
1✔
174
    }
175

176
    private boolean columnMatches(IntrospectedColumn introspectedColumn, String columnName) {
177
        if (introspectedColumn.isColumnNameDelimited()) {
1✔
178
            return introspectedColumn.getActualColumnName().equals(columnName);
1✔
179
        } else {
180
            return introspectedColumn.getActualColumnName().equalsIgnoreCase(columnName);
1✔
181
        }
182
    }
183

184
    /**
185
     * Returns true if any of the columns in the table are JDBC Dates (as
186
     * opposed to timestamps).
187
     *
188
     * @return true if the table contains DATE columns
189
     */
190
    public boolean hasJDBCDateColumns() {
191
        return Stream.of(primaryKeyColumns.stream(), baseColumns.stream())
1✔
192
                .flatMap(Function.identity())
1✔
193
                .anyMatch(IntrospectedColumn::isJDBCDateColumn);
1✔
194
    }
195

196
    /**
197
     * Returns true if any of the columns in the table are JDBC Times (as
198
     * opposed to timestamps).
199
     *
200
     * @return true if the table contains TIME columns
201
     */
202
    public boolean hasJDBCTimeColumns() {
203
        return Stream.of(primaryKeyColumns.stream(), baseColumns.stream())
1✔
204
                .flatMap(Function.identity())
1✔
205
                .anyMatch(IntrospectedColumn::isJDBCTimeColumn);
1✔
206
    }
207

208
    /**
209
     * Returns the columns in the primary key. If the generatePrimaryKeyClass()
210
     * method returns false, then these columns will be iterated as the
211
     * parameters of the selectByPrimaryKay and deleteByPrimaryKey methods
212
     *
213
     * @return a List of ColumnDefinition objects for columns in the primary key
214
     */
215
    public List<IntrospectedColumn> getPrimaryKeyColumns() {
216
        return primaryKeyColumns;
1✔
217
    }
218

219
    public boolean hasPrimaryKeyColumns() {
220
        return !primaryKeyColumns.isEmpty();
1✔
221
    }
222

223
    public List<IntrospectedColumn> getBaseColumns() {
224
        return baseColumns;
1✔
225
    }
226

227
    /**
228
     * Returns all columns in the table (for use by the select by primary key and
229
     * select by example with BLOBs methods).
230
     *
231
     * @return a List of ColumnDefinition objects for all columns in the table
232
     */
233
    public List<IntrospectedColumn> getAllColumns() {
234
        return Stream.of(primaryKeyColumns.stream(), baseColumns.stream(), blobColumns.stream())
1✔
235
                .flatMap(Function.identity())
1✔
236
                .toList();
1✔
237
    }
238

239
    /**
240
     * Returns all columns except BLOBs (for use by the select by example without BLOBs method).
241
     *
242
     * @return a List of ColumnDefinition objects for columns in the table that are non BLOBs
243
     */
244
    public List<IntrospectedColumn> getNonBLOBColumns() {
245
        return Stream.of(primaryKeyColumns.stream(), baseColumns.stream())
1✔
246
                .flatMap(Function.identity())
1✔
247
                .toList();
1✔
248
    }
249

250
    public int getNonBLOBColumnCount() {
251
        return primaryKeyColumns.size() + baseColumns.size();
×
252
    }
253

254
    public List<IntrospectedColumn> getNonPrimaryKeyColumns() {
255
        return Stream.of(baseColumns.stream(), blobColumns.stream())
1✔
256
                .flatMap(Function.identity())
1✔
257
                .toList();
1✔
258
    }
259

260
    public List<IntrospectedColumn> getBLOBColumns() {
261
        return blobColumns;
1✔
262
    }
263

264
    public boolean hasBLOBColumns() {
265
        return !blobColumns.isEmpty();
1✔
266
    }
267

268
    public boolean hasBaseColumns() {
269
        return !baseColumns.isEmpty();
1✔
270
    }
271

272
    public Rules getRules() {
273
        return Objects.requireNonNull(rules);
1✔
274
    }
275

276
    public @Nullable String getTableConfigurationProperty(String property) {
277
        return getTableConfiguration().getProperty(property);
1✔
278
    }
279

280
    public String getPrimaryKeyType() {
281
        return internalAttributes.get(InternalAttribute.ATTR_PRIMARY_KEY_TYPE);
1✔
282
    }
283

284
    /**
285
     * Gets the base record type.
286
     *
287
     * @return the type for the record (the class that holds non-primary key and non-BLOB fields). Note that the value
288
     *         will be calculated regardless of whether the table has these columns or not.
289
     */
290
    public String getBaseRecordType() {
291
        return internalAttributes.get(InternalAttribute.ATTR_BASE_RECORD_TYPE);
1✔
292
    }
293

294
    public String getKotlinRecordType() {
295
        return internalAttributes.get(InternalAttribute.ATTR_KOTLIN_RECORD_TYPE);
1✔
296
    }
297

298
    /**
299
     * Gets the example type.
300
     *
301
     * @return the type for the example class.
302
     */
303
    public String getExampleType() {
304
        return internalAttributes.get(InternalAttribute.ATTR_EXAMPLE_TYPE);
1✔
305
    }
306

307
    /**
308
     * Gets the record with blobs type.
309
     *
310
     * @return the type for the record with BLOBs class. Note that the value will be calculated regardless of whether
311
     *         the table has BLOB columns or not.
312
     */
313
    public String getRecordWithBLOBsType() {
314
        return internalAttributes.get(InternalAttribute.ATTR_RECORD_WITH_BLOBS_TYPE);
1✔
315
    }
316

317
    public String getMyBatis3SqlMapNamespace() {
318
        String namespace = getMyBatis3JavaMapperType();
1✔
319
        if (namespace == null) {
1✔
320
            namespace = getMyBatis3FallbackSqlMapNamespace();
1✔
321
        }
322

323
        return namespace;
1✔
324
    }
325

326
    public String getMyBatis3FallbackSqlMapNamespace() {
327
        return internalAttributes
1✔
328
                .get(InternalAttribute.ATTR_MYBATIS3_FALLBACK_SQL_MAP_NAMESPACE);
1✔
329
    }
330

331
    public boolean hasAnyColumns() {
332
        return hasPrimaryKeyColumns() || hasBaseColumns() || hasBLOBColumns();
1!
333
    }
334

335
    public void addColumn(IntrospectedColumn introspectedColumn) {
336
        if (introspectedColumn.isBLOBColumn()) {
1✔
337
            blobColumns.add(introspectedColumn);
1✔
338
        } else {
339
            baseColumns.add(introspectedColumn);
1✔
340
        }
341

342
        introspectedColumn.setIntrospectedTable(this);
1✔
343
    }
1✔
344

345
    public void addPrimaryKeyColumn(String columnName) {
346
        boolean found = false;
1✔
347
        // first search base columns
348
        Iterator<IntrospectedColumn> iter = baseColumns.iterator();
1✔
349
        while (iter.hasNext()) {
1!
350
            IntrospectedColumn introspectedColumn = iter.next();
1✔
351
            if (introspectedColumn.getActualColumnName().equals(columnName)) {
1✔
352
                primaryKeyColumns.add(introspectedColumn);
1✔
353
                iter.remove();
1✔
354
                found = true;
1✔
355
                break;
1✔
356
            }
357
        }
1✔
358

359
        // search blob columns in the weird event that a blob is the primary key
360
        if (!found) {
1!
361
            iter = blobColumns.iterator();
×
362
            while (iter.hasNext()) {
×
363
                IntrospectedColumn introspectedColumn = iter.next();
×
364
                if (introspectedColumn.getActualColumnName().equals(columnName)) {
×
365
                    primaryKeyColumns.add(introspectedColumn);
×
366
                    iter.remove();
×
367
                    break;
×
368
                }
369
            }
×
370
        }
371
    }
1✔
372

373
    public Object getAttribute(String name) {
374
        return attributes.get(name);
×
375
    }
376

377
    public void removeAttribute(String name) {
378
        attributes.remove(name);
×
379
    }
×
380

381
    public void setAttribute(String name, Object value) {
382
        attributes.put(name, value);
×
383
    }
×
384

385
    protected void calculateXmlAttributes() {
386
        setMyBatis3XmlMapperFileName(calculateMyBatis3XmlMapperFileName());
1✔
387
        setMyBatis3XmlMapperPackage(calculateSqlMapPackage());
1✔
388

389
        setMyBatis3FallbackSqlMapNamespace(calculateMyBatis3FallbackSqlMapNamespace());
1✔
390

391
        setSqlMapFullyQualifiedRuntimeTableName(calculateSqlMapFullyQualifiedRuntimeTableName());
1✔
392
        setSqlMapAliasedFullyQualifiedRuntimeTableName(calculateSqlMapAliasedFullyQualifiedRuntimeTableName());
1✔
393

394
        setCountByExampleStatementId("countByExample"); //$NON-NLS-1$
1✔
395
        setDeleteByExampleStatementId("deleteByExample"); //$NON-NLS-1$
1✔
396
        setDeleteByPrimaryKeyStatementId("deleteByPrimaryKey"); //$NON-NLS-1$
1✔
397
        setInsertStatementId("insert"); //$NON-NLS-1$
1✔
398
        setInsertSelectiveStatementId("insertSelective"); //$NON-NLS-1$
1✔
399
        setSelectAllStatementId("selectAll"); //$NON-NLS-1$
1✔
400
        setSelectByExampleStatementId("selectByExample"); //$NON-NLS-1$
1✔
401
        setSelectByExampleWithBLOBsStatementId("selectByExampleWithBLOBs"); //$NON-NLS-1$
1✔
402
        setSelectByPrimaryKeyStatementId("selectByPrimaryKey"); //$NON-NLS-1$
1✔
403
        setUpdateByExampleStatementId("updateByExample"); //$NON-NLS-1$
1✔
404
        setUpdateByExampleSelectiveStatementId("updateByExampleSelective"); //$NON-NLS-1$
1✔
405
        setUpdateByExampleWithBLOBsStatementId("updateByExampleWithBLOBs"); //$NON-NLS-1$
1✔
406
        setUpdateByPrimaryKeyStatementId("updateByPrimaryKey"); //$NON-NLS-1$
1✔
407
        setUpdateByPrimaryKeySelectiveStatementId("updateByPrimaryKeySelective"); //$NON-NLS-1$
1✔
408
        setUpdateByPrimaryKeyWithBLOBsStatementId("updateByPrimaryKeyWithBLOBs"); //$NON-NLS-1$
1✔
409
        setBaseResultMapId("BaseResultMap"); //$NON-NLS-1$
1✔
410
        setResultMapWithBLOBsId("ResultMapWithBLOBs"); //$NON-NLS-1$
1✔
411
        setExampleWhereClauseId("Example_Where_Clause"); //$NON-NLS-1$
1✔
412
        setBaseColumnListId("Base_Column_List"); //$NON-NLS-1$
1✔
413
        setBlobColumnListId("Blob_Column_List"); //$NON-NLS-1$
1✔
414
        setMyBatis3UpdateByExampleWhereClauseId("Update_By_Example_Where_Clause"); //$NON-NLS-1$
1✔
415
    }
1✔
416

417
    public void setBlobColumnListId(String s) {
418
        internalAttributes.put(InternalAttribute.ATTR_BLOB_COLUMN_LIST_ID, s);
1✔
419
    }
1✔
420

421
    public void setBaseColumnListId(String s) {
422
        internalAttributes.put(InternalAttribute.ATTR_BASE_COLUMN_LIST_ID, s);
1✔
423
    }
1✔
424

425
    public void setExampleWhereClauseId(String s) {
426
        internalAttributes.put(InternalAttribute.ATTR_EXAMPLE_WHERE_CLAUSE_ID, s);
1✔
427
    }
1✔
428

429
    public void setMyBatis3UpdateByExampleWhereClauseId(String s) {
430
        internalAttributes.put(InternalAttribute.ATTR_MYBATIS3_UPDATE_BY_EXAMPLE_WHERE_CLAUSE_ID, s);
1✔
431
    }
1✔
432

433
    public void setResultMapWithBLOBsId(String s) {
434
        internalAttributes.put(InternalAttribute.ATTR_RESULT_MAP_WITH_BLOBS_ID, s);
1✔
435
    }
1✔
436

437
    public void setBaseResultMapId(String s) {
438
        internalAttributes.put(InternalAttribute.ATTR_BASE_RESULT_MAP_ID, s);
1✔
439
    }
1✔
440

441
    public void setUpdateByPrimaryKeyWithBLOBsStatementId(String s) {
442
        internalAttributes.put(InternalAttribute.ATTR_UPDATE_BY_PRIMARY_KEY_WITH_BLOBS_STATEMENT_ID, s);
1✔
443
    }
1✔
444

445
    public void setUpdateByPrimaryKeySelectiveStatementId(String s) {
446
        internalAttributes.put(InternalAttribute.ATTR_UPDATE_BY_PRIMARY_KEY_SELECTIVE_STATEMENT_ID, s);
1✔
447
    }
1✔
448

449
    public void setUpdateByPrimaryKeyStatementId(String s) {
450
        internalAttributes.put(InternalAttribute.ATTR_UPDATE_BY_PRIMARY_KEY_STATEMENT_ID, s);
1✔
451
    }
1✔
452

453
    public void setUpdateByExampleWithBLOBsStatementId(String s) {
454
        internalAttributes.put(InternalAttribute.ATTR_UPDATE_BY_EXAMPLE_WITH_BLOBS_STATEMENT_ID, s);
1✔
455
    }
1✔
456

457
    public void setUpdateByExampleSelectiveStatementId(String s) {
458
        internalAttributes.put(InternalAttribute.ATTR_UPDATE_BY_EXAMPLE_SELECTIVE_STATEMENT_ID, s);
1✔
459
    }
1✔
460

461
    public void setUpdateByExampleStatementId(String s) {
462
        internalAttributes.put(InternalAttribute.ATTR_UPDATE_BY_EXAMPLE_STATEMENT_ID, s);
1✔
463
    }
1✔
464

465
    public void setSelectByPrimaryKeyStatementId(String s) {
466
        internalAttributes.put(InternalAttribute.ATTR_SELECT_BY_PRIMARY_KEY_STATEMENT_ID, s);
1✔
467
    }
1✔
468

469
    public void setSelectByExampleWithBLOBsStatementId(String s) {
470
        internalAttributes.put(InternalAttribute.ATTR_SELECT_BY_EXAMPLE_WITH_BLOBS_STATEMENT_ID, s);
1✔
471
    }
1✔
472

473
    public void setSelectAllStatementId(String s) {
474
        internalAttributes.put(InternalAttribute.ATTR_SELECT_ALL_STATEMENT_ID, s);
1✔
475
    }
1✔
476

477
    public void setSelectByExampleStatementId(String s) {
478
        internalAttributes.put(InternalAttribute.ATTR_SELECT_BY_EXAMPLE_STATEMENT_ID, s);
1✔
479
    }
1✔
480

481
    public void setInsertSelectiveStatementId(String s) {
482
        internalAttributes.put(InternalAttribute.ATTR_INSERT_SELECTIVE_STATEMENT_ID, s);
1✔
483
    }
1✔
484

485
    public void setInsertStatementId(String s) {
486
        internalAttributes.put(InternalAttribute.ATTR_INSERT_STATEMENT_ID, s);
1✔
487
    }
1✔
488

489
    public void setDeleteByPrimaryKeyStatementId(String s) {
490
        internalAttributes.put(InternalAttribute.ATTR_DELETE_BY_PRIMARY_KEY_STATEMENT_ID, s);
1✔
491
    }
1✔
492

493
    public void setDeleteByExampleStatementId(String s) {
494
        internalAttributes.put(InternalAttribute.ATTR_DELETE_BY_EXAMPLE_STATEMENT_ID, s);
1✔
495
    }
1✔
496

497
    public void setCountByExampleStatementId(String s) {
498
        internalAttributes.put(InternalAttribute.ATTR_COUNT_BY_EXAMPLE_STATEMENT_ID, s);
1✔
499
    }
1✔
500

501
    public String getBlobColumnListId() {
502
        return internalAttributes.get(InternalAttribute.ATTR_BLOB_COLUMN_LIST_ID);
1✔
503
    }
504

505
    public String getBaseColumnListId() {
506
        return internalAttributes.get(InternalAttribute.ATTR_BASE_COLUMN_LIST_ID);
1✔
507
    }
508

509
    public String getExampleWhereClauseId() {
510
        return internalAttributes.get(InternalAttribute.ATTR_EXAMPLE_WHERE_CLAUSE_ID);
1✔
511
    }
512

513
    public String getMyBatis3UpdateByExampleWhereClauseId() {
514
        return internalAttributes.get(InternalAttribute.ATTR_MYBATIS3_UPDATE_BY_EXAMPLE_WHERE_CLAUSE_ID);
1✔
515
    }
516

517
    public String getResultMapWithBLOBsId() {
518
        return internalAttributes.get(InternalAttribute.ATTR_RESULT_MAP_WITH_BLOBS_ID);
1✔
519
    }
520

521
    public String getBaseResultMapId() {
522
        return internalAttributes.get(InternalAttribute.ATTR_BASE_RESULT_MAP_ID);
1✔
523
    }
524

525
    public String getUpdateByPrimaryKeyWithBLOBsStatementId() {
526
        return internalAttributes.get(InternalAttribute.ATTR_UPDATE_BY_PRIMARY_KEY_WITH_BLOBS_STATEMENT_ID);
1✔
527
    }
528

529
    public String getUpdateByPrimaryKeySelectiveStatementId() {
530
        return internalAttributes.get(InternalAttribute.ATTR_UPDATE_BY_PRIMARY_KEY_SELECTIVE_STATEMENT_ID);
1✔
531
    }
532

533
    public String getUpdateByPrimaryKeyStatementId() {
534
        return internalAttributes.get(InternalAttribute.ATTR_UPDATE_BY_PRIMARY_KEY_STATEMENT_ID);
1✔
535
    }
536

537
    public String getUpdateByExampleWithBLOBsStatementId() {
538
        return internalAttributes.get(InternalAttribute.ATTR_UPDATE_BY_EXAMPLE_WITH_BLOBS_STATEMENT_ID);
1✔
539
    }
540

541
    public String getUpdateByExampleSelectiveStatementId() {
542
        return internalAttributes.get(InternalAttribute.ATTR_UPDATE_BY_EXAMPLE_SELECTIVE_STATEMENT_ID);
1✔
543
    }
544

545
    public String getUpdateByExampleStatementId() {
546
        return internalAttributes.get(InternalAttribute.ATTR_UPDATE_BY_EXAMPLE_STATEMENT_ID);
1✔
547
    }
548

549
    public String getSelectByPrimaryKeyStatementId() {
550
        return internalAttributes.get(InternalAttribute.ATTR_SELECT_BY_PRIMARY_KEY_STATEMENT_ID);
1✔
551
    }
552

553
    public String getSelectByExampleWithBLOBsStatementId() {
554
        return internalAttributes.get(InternalAttribute.ATTR_SELECT_BY_EXAMPLE_WITH_BLOBS_STATEMENT_ID);
1✔
555
    }
556

557
    public String getSelectAllStatementId() {
558
        return internalAttributes.get(InternalAttribute.ATTR_SELECT_ALL_STATEMENT_ID);
1✔
559
    }
560

561
    public String getSelectByExampleStatementId() {
562
        return internalAttributes.get(InternalAttribute.ATTR_SELECT_BY_EXAMPLE_STATEMENT_ID);
1✔
563
    }
564

565
    public String getInsertSelectiveStatementId() {
566
        return internalAttributes.get(InternalAttribute.ATTR_INSERT_SELECTIVE_STATEMENT_ID);
1✔
567
    }
568

569
    public String getInsertStatementId() {
570
        return internalAttributes.get(InternalAttribute.ATTR_INSERT_STATEMENT_ID);
1✔
571
    }
572

573
    public String getDeleteByPrimaryKeyStatementId() {
574
        return internalAttributes.get(InternalAttribute.ATTR_DELETE_BY_PRIMARY_KEY_STATEMENT_ID);
1✔
575
    }
576

577
    public String getDeleteByExampleStatementId() {
578
        return internalAttributes.get(InternalAttribute.ATTR_DELETE_BY_EXAMPLE_STATEMENT_ID);
1✔
579
    }
580

581
    public String getCountByExampleStatementId() {
582
        return internalAttributes.get(InternalAttribute.ATTR_COUNT_BY_EXAMPLE_STATEMENT_ID);
1✔
583
    }
584

585
    public String getMyBatisDynamicSQLTableObjectName() {
586
        return internalAttributes.get(InternalAttribute.ATTR_MYBATIS_DYNAMIC_SQL_TABLE_OBJECT_NAME);
1✔
587
    }
588

589
    public void setMyBatisDynamicSQLTableObjectName(String name) {
590
        internalAttributes.put(InternalAttribute.ATTR_MYBATIS_DYNAMIC_SQL_TABLE_OBJECT_NAME, name);
1✔
591
    }
1✔
592

593
    private boolean isSubPackagesEnabled(PropertyHolder propertyHolder) {
594
        return isTrue(propertyHolder.getProperty(PropertyRegistry.ANY_ENABLE_SUB_PACKAGES));
1✔
595
    }
596

597
    protected @Nullable String calculateJavaClientInterfacePackage() {
598
        return context.getJavaClientGeneratorConfiguration()
1✔
599
                .map(c -> c.getTargetPackage()
1✔
600
                        + getFullyQualifiedTable().getSubPackageForClientOrSqlMap(isSubPackagesEnabled(c)))
1✔
601
                .orElse(null);
1✔
602
    }
603

604
    protected @Nullable String calculateDynamicSqlSupportPackage() {
605
        return context.getJavaClientGeneratorConfiguration()
1✔
606
                .map(c -> {
1✔
607
                    String packkage = c.getProperty(PropertyRegistry.CLIENT_DYNAMIC_SQL_SUPPORT_PACKAGE);
1✔
608
                    if (stringHasValue(packkage)) {
1✔
609
                        return packkage
1✔
610
                                + getFullyQualifiedTable().getSubPackageForClientOrSqlMap(isSubPackagesEnabled(c));
1✔
611
                    } else {
612
                        return calculateJavaClientInterfacePackage();
1✔
613
                    }
614
                }).orElse(null);
1✔
615
    }
616

617
    protected void calculateJavaClientAttributes() {
618
        if (context.getJavaClientGeneratorConfiguration().isEmpty()) {
1✔
619
            return;
1✔
620
        }
621

622
        StringBuilder sb = new StringBuilder();
1✔
623
        sb.append(calculateJavaClientInterfacePackage());
1✔
624
        sb.append('.');
1✔
625
        if (stringHasValue(getTableConfiguration().getMapperName())) {
1✔
626
            sb.append(getTableConfiguration().getMapperName());
1✔
627
        } else {
628
            getFullyQualifiedTable().getDomainObjectSubPackage().ifPresent(sp -> sb.append(sp).append('.'));
1✔
629
            sb.append(getFullyQualifiedTable().getDomainObjectName());
1✔
630
            sb.append("Mapper"); //$NON-NLS-1$
1✔
631
        }
632
        setMyBatis3JavaMapperType(sb.toString());
1✔
633

634
        sb.setLength(0);
1✔
635
        sb.append(calculateJavaClientInterfacePackage());
1✔
636
        sb.append('.');
1✔
637
        if (stringHasValue(getTableConfiguration().getSqlProviderName())) {
1!
638
            sb.append(getTableConfiguration().getSqlProviderName());
×
639
        } else {
640
            getFullyQualifiedTable().getDomainObjectSubPackage().ifPresent(sp -> sb.append(sp).append('.'));
1✔
641
            sb.append(getFullyQualifiedTable().getDomainObjectName());
1✔
642
            sb.append("SqlProvider"); //$NON-NLS-1$
1✔
643
        }
644
        setMyBatis3SqlProviderType(sb.toString());
1✔
645

646
        sb.setLength(0);
1✔
647
        sb.append(calculateDynamicSqlSupportPackage());
1✔
648
        sb.append('.');
1✔
649
        if (stringHasValue(getTableConfiguration().getDynamicSqlSupportClassName())) {
1✔
650
            sb.append(getTableConfiguration().getDynamicSqlSupportClassName());
1✔
651
        } else {
652
            getFullyQualifiedTable().getDomainObjectSubPackage().ifPresent(sp -> sb.append(sp).append('.'));
1✔
653
            sb.append(getFullyQualifiedTable().getDomainObjectName());
1✔
654
            sb.append("DynamicSqlSupport"); //$NON-NLS-1$
1✔
655
        }
656
        setMyBatisDynamicSqlSupportType(sb.toString());
1✔
657

658
        if (stringHasValue(getTableConfiguration().getDynamicSqlTableObjectName())) {
1✔
659
            setMyBatisDynamicSQLTableObjectName(getTableConfiguration().getDynamicSqlTableObjectName());
1✔
660
        } else {
661
            setMyBatisDynamicSQLTableObjectName(getFullyQualifiedTable().getDomainObjectName());
1✔
662
        }
663
    }
1✔
664

665
    protected String calculateJavaModelPackage() {
666
        JavaModelGeneratorConfiguration config = context.getJavaModelGeneratorConfiguration();
1✔
667

668
        return config.getTargetPackage() + getFullyQualifiedTable().getSubPackageForModel(isSubPackagesEnabled(config));
1✔
669
    }
670

671
    protected void calculateModelAttributes() {
672
        String pakkage = calculateJavaModelPackage();
1✔
673

674
        StringBuilder sb = new StringBuilder();
1✔
675
        sb.append(pakkage);
1✔
676
        sb.append('.');
1✔
677
        sb.append(getFullyQualifiedTable().getDomainObjectName());
1✔
678
        sb.append("Key"); //$NON-NLS-1$
1✔
679
        setPrimaryKeyType(sb.toString());
1✔
680

681
        sb.setLength(0);
1✔
682
        sb.append(pakkage);
1✔
683
        sb.append('.');
1✔
684
        sb.append(getFullyQualifiedTable().getDomainObjectName());
1✔
685
        setBaseRecordType(sb.toString());
1✔
686

687
        sb.setLength(0);
1✔
688
        sb.append(pakkage);
1✔
689
        sb.append('.');
1✔
690
        sb.append(getFullyQualifiedTable().getDomainObjectName());
1✔
691
        setKotlinRecordType(sb.toString());
1✔
692

693
        sb.setLength(0);
1✔
694
        sb.append(pakkage);
1✔
695
        sb.append('.');
1✔
696
        sb.append(getFullyQualifiedTable().getDomainObjectName());
1✔
697
        sb.append("WithBLOBs"); //$NON-NLS-1$
1✔
698
        setRecordWithBLOBsType(sb.toString());
1✔
699

700
        String exampleTargetPackage = calculateJavaModelExamplePackage();
1✔
701
        sb.setLength(0);
1✔
702
        sb.append(exampleTargetPackage);
1✔
703
        sb.append('.');
1✔
704
        sb.append(getFullyQualifiedTable().getDomainObjectName());
1✔
705
        sb.append("Example"); //$NON-NLS-1$
1✔
706
        setExampleType(sb.toString());
1✔
707
    }
1✔
708

709
    /**
710
     * If property exampleTargetPackage specified for example use the specified value, else
711
     * use default value (targetPackage).
712
     *
713
     * @return the calculated package
714
     */
715
    protected String calculateJavaModelExamplePackage() {
716
        JavaModelGeneratorConfiguration config = context.getJavaModelGeneratorConfiguration();
1✔
717
        String exampleTargetPackage = config.getProperty(PropertyRegistry.MODEL_GENERATOR_EXAMPLE_PACKAGE);
1✔
718
        if (!stringHasValue(exampleTargetPackage)) {
1✔
719
            return calculateJavaModelPackage();
1✔
720
        }
721

722
        return exampleTargetPackage + getFullyQualifiedTable().getSubPackageForModel(isSubPackagesEnabled(config));
1✔
723
    }
724

725
    protected String calculateSqlMapPackage() {
726
        StringBuilder sb = new StringBuilder();
1✔
727
        // config can be null if the Java client does not require XML
728
        context.getSqlMapGeneratorConfiguration().ifPresent(config -> {
1✔
729
            sb.append(config.getTargetPackage());
1✔
730
            sb.append(getFullyQualifiedTable().getSubPackageForClientOrSqlMap(isSubPackagesEnabled(config)));
1✔
731
            if (stringHasValue(getTableConfiguration().getMapperName())) {
1✔
732
                String mapperName = getTableConfiguration().getMapperName();
1✔
733
                int ind = mapperName.lastIndexOf('.');
1✔
734
                if (ind != -1) {
1✔
735
                    sb.append('.').append(mapperName, 0, ind);
1✔
736
                }
737
            } else {
1✔
738
                getFullyQualifiedTable().getDomainObjectSubPackage().ifPresent(sp -> sb.append('.').append(sp));
1✔
739
            }
740
        });
1✔
741

742
        return sb.toString();
1✔
743
    }
744

745
    protected String calculateMyBatis3XmlMapperFileName() {
746
        StringBuilder sb = new StringBuilder();
1✔
747
        if (stringHasValue(getTableConfiguration().getMapperName())) {
1✔
748
            String mapperName = getTableConfiguration().getMapperName();
1✔
749
            int ind = mapperName.lastIndexOf('.');
1✔
750
            if (ind == -1) {
1✔
751
                sb.append(mapperName);
1✔
752
            } else {
753
                sb.append(mapperName.substring(ind + 1));
1✔
754
            }
755
            sb.append(".xml"); //$NON-NLS-1$
1✔
756
        } else {
1✔
757
            sb.append(getFullyQualifiedTable().getDomainObjectName());
1✔
758
            sb.append("Mapper.xml"); //$NON-NLS-1$
1✔
759
        }
760
        return sb.toString();
1✔
761
    }
762

763
    protected String calculateMyBatis3FallbackSqlMapNamespace() {
764
        StringBuilder sb = new StringBuilder();
1✔
765
        sb.append(calculateSqlMapPackage());
1✔
766
        sb.append('.');
1✔
767
        if (stringHasValue(getTableConfiguration().getMapperName())) {
1✔
768
            sb.append(getTableConfiguration().getMapperName());
1✔
769
        } else {
770
            sb.append(getFullyQualifiedTable().getDomainObjectName());
1✔
771
            sb.append("Mapper"); //$NON-NLS-1$
1✔
772
        }
773
        return sb.toString();
1✔
774
    }
775

776
    protected String calculateSqlMapFullyQualifiedRuntimeTableName() {
777
        return getFullyQualifiedTable().getFullyQualifiedTableNameAtRuntime();
1✔
778
    }
779

780
    protected String calculateSqlMapAliasedFullyQualifiedRuntimeTableName() {
781
        return getFullyQualifiedTable().getAliasedFullyQualifiedTableNameAtRuntime();
1✔
782
    }
783

784
    public String getFullyQualifiedTableNameAtRuntime() {
785
        return internalAttributes.get(InternalAttribute.ATTR_FULLY_QUALIFIED_TABLE_NAME_AT_RUNTIME);
1✔
786
    }
787

788
    public String getAliasedFullyQualifiedTableNameAtRuntime() {
789
        return internalAttributes.get(InternalAttribute.ATTR_ALIASED_FULLY_QUALIFIED_TABLE_NAME_AT_RUNTIME);
1✔
790
    }
791

792
    /**
793
     * This method exists to give plugins the opportunity to replace the calculated rules if necessary.
794
     *
795
     * @param rules
796
     *            the new rules
797
     */
798
    public void setRules(Rules rules) {
799
        this.rules = rules;
×
800
    }
×
801

802
    public TableConfiguration getTableConfiguration() {
803
        return Objects.requireNonNull(tableConfiguration);
1✔
804
    }
805

806
    public void setPrimaryKeyType(String primaryKeyType) {
807
        internalAttributes.put(InternalAttribute.ATTR_PRIMARY_KEY_TYPE, primaryKeyType);
1✔
808
    }
1✔
809

810
    public void setBaseRecordType(String baseRecordType) {
811
        internalAttributes.put(InternalAttribute.ATTR_BASE_RECORD_TYPE, baseRecordType);
1✔
812
    }
1✔
813

814
    public void setKotlinRecordType(String kotlinRecordType) {
815
        internalAttributes.put(InternalAttribute.ATTR_KOTLIN_RECORD_TYPE, kotlinRecordType);
1✔
816
    }
1✔
817

818
    public void setRecordWithBLOBsType(String recordWithBLOBsType) {
819
        internalAttributes.put(InternalAttribute.ATTR_RECORD_WITH_BLOBS_TYPE, recordWithBLOBsType);
1✔
820
    }
1✔
821

822
    public void setExampleType(String exampleType) {
823
        internalAttributes.put(InternalAttribute.ATTR_EXAMPLE_TYPE, exampleType);
1✔
824
    }
1✔
825

826
    public void setMyBatis3FallbackSqlMapNamespace(String sqlMapNamespace) {
827
        internalAttributes.put(InternalAttribute.ATTR_MYBATIS3_FALLBACK_SQL_MAP_NAMESPACE, sqlMapNamespace);
1✔
828
    }
1✔
829

830
    public void setSqlMapFullyQualifiedRuntimeTableName(String fullyQualifiedRuntimeTableName) {
831
        internalAttributes.put(InternalAttribute.ATTR_FULLY_QUALIFIED_TABLE_NAME_AT_RUNTIME,
1✔
832
                fullyQualifiedRuntimeTableName);
833
    }
1✔
834

835
    public void setSqlMapAliasedFullyQualifiedRuntimeTableName(String aliasedFullyQualifiedRuntimeTableName) {
836
        internalAttributes.put(InternalAttribute.ATTR_ALIASED_FULLY_QUALIFIED_TABLE_NAME_AT_RUNTIME,
1✔
837
                        aliasedFullyQualifiedRuntimeTableName);
838
    }
1✔
839

840
    public String getMyBatis3XmlMapperPackage() {
841
        return internalAttributes.get(InternalAttribute.ATTR_MYBATIS3_XML_MAPPER_PACKAGE);
1✔
842
    }
843

844
    public void setMyBatis3XmlMapperPackage(String mybatis3XmlMapperPackage) {
845
        internalAttributes.put(InternalAttribute.ATTR_MYBATIS3_XML_MAPPER_PACKAGE, mybatis3XmlMapperPackage);
1✔
846
    }
1✔
847

848
    public String getMyBatis3XmlMapperFileName() {
849
        return internalAttributes.get(InternalAttribute.ATTR_MYBATIS3_XML_MAPPER_FILE_NAME);
1✔
850
    }
851

852
    public void setMyBatis3XmlMapperFileName(String mybatis3XmlMapperFileName) {
853
        internalAttributes.put(InternalAttribute.ATTR_MYBATIS3_XML_MAPPER_FILE_NAME, mybatis3XmlMapperFileName);
1✔
854
    }
1✔
855

856
    public String getMyBatis3JavaMapperType() {
857
        return internalAttributes.get(InternalAttribute.ATTR_MYBATIS3_JAVA_MAPPER_TYPE);
1✔
858
    }
859

860
    public void setMyBatis3JavaMapperType(String mybatis3JavaMapperType) {
861
        internalAttributes.put(InternalAttribute.ATTR_MYBATIS3_JAVA_MAPPER_TYPE, mybatis3JavaMapperType);
1✔
862
    }
1✔
863

864
    public String getMyBatis3SqlProviderType() {
865
        return internalAttributes.get(InternalAttribute.ATTR_MYBATIS3_SQL_PROVIDER_TYPE);
1✔
866
    }
867

868
    public void setMyBatis3SqlProviderType(String mybatis3SqlProviderType) {
869
        internalAttributes.put(InternalAttribute.ATTR_MYBATIS3_SQL_PROVIDER_TYPE, mybatis3SqlProviderType);
1✔
870
    }
1✔
871

872
    public String getMyBatisDynamicSqlSupportType() {
873
        return internalAttributes.get(InternalAttribute.ATTR_MYBATIS_DYNAMIC_SQL_SUPPORT_TYPE);
1✔
874
    }
875

876
    public void setMyBatisDynamicSqlSupportType(String s) {
877
        internalAttributes.put(InternalAttribute.ATTR_MYBATIS_DYNAMIC_SQL_SUPPORT_TYPE, s);
1✔
878
    }
1✔
879

880
    public KnownRuntime getKnownRuntime() {
881
        return knownRuntime;
1✔
882
    }
883

884
    public boolean isImmutable() {
885
        Properties properties;
886

887
        if (getTableConfiguration().getProperties().containsKey(PropertyRegistry.ANY_IMMUTABLE)) {
1✔
888
            properties = getTableConfiguration().getProperties();
1✔
889
        } else {
890
            properties = context.getJavaModelGeneratorConfiguration().getProperties();
1✔
891
        }
892

893
        return isTrue(properties.getProperty(PropertyRegistry.ANY_IMMUTABLE));
1✔
894
    }
895

896
    public boolean isConstructorBased() {
897
        if (isImmutable()) {
1✔
898
            return true;
1✔
899
        }
900

901
        Properties properties;
902

903
        if (getTableConfiguration().getProperties().containsKey(PropertyRegistry.ANY_CONSTRUCTOR_BASED)) {
1✔
904
            properties = getTableConfiguration().getProperties();
1✔
905
        } else {
906
            properties = context.getJavaModelGeneratorConfiguration().getProperties();
1✔
907
        }
908

909
        return isTrue(properties.getProperty(PropertyRegistry.ANY_CONSTRUCTOR_BASED));
1✔
910
    }
911

912
    public Context getContext() {
913
        return context;
1✔
914
    }
915

916
    public Optional<String> getRemarks() {
917
        return Optional.ofNullable(remarks);
1✔
918
    }
919

920
    public void setRemarks(String remarks) {
921
        this.remarks = remarks;
1✔
922
    }
1✔
923

924
    public String getTableType() {
925
        return Objects.requireNonNull(tableType);
1✔
926
    }
927

928
    public void setTableType(String tableType) {
929
        this.tableType = tableType;
1✔
930
    }
1✔
931

932
    public static class Builder {
1✔
933
        private @Nullable KnownRuntime knownRuntime;
934
        private @Nullable TableConfiguration tableConfiguration;
935
        private @Nullable FullyQualifiedTable fullyQualifiedTable;
936
        private @Nullable Context context;
937
        private @Nullable PluginAggregator pluginAggregator;
938

939
        public Builder withKnownRuntime(KnownRuntime knownRuntime) {
940
            this.knownRuntime = knownRuntime;
1✔
941
            return this;
1✔
942
        }
943

944
        public Builder withTableConfiguration(TableConfiguration tableConfiguration) {
945
            this.tableConfiguration = tableConfiguration;
1✔
946
            return this;
1✔
947
        }
948

949
        public Builder withFullyQualifiedTable(FullyQualifiedTable fullyQualifiedTable) {
950
            this.fullyQualifiedTable = fullyQualifiedTable;
1✔
951
            return this;
1✔
952
        }
953

954
        public Builder withContext(Context context) {
955
            this.context = context;
1✔
956
            return this;
1✔
957
        }
958

959
        public Builder withPluginAggregator(PluginAggregator pluginAggregator) {
960
            this.pluginAggregator = pluginAggregator;
1✔
961
            return this;
1✔
962
        }
963

964
        public IntrospectedTable build() {
965
            return new IntrospectedTable(this);
1✔
966
        }
967
    }
968
}
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