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

mybatis / generator / 2027

08 Feb 2026 06:52PM UTC coverage: 89.941% (-0.02%) from 89.961%
2027

push

github

web-flow
Remove the Eclipse based Java file merger in favor of the merger in the core library (#1443)

* Remove unnecessary extra line in JavaDoc for most cases

* Support unmergeable Java files

* Generic files are never mergeable

* Remove Java merger from the Eclipse plugin

The new merger in the core project is better tested and more capable.

* Package our dependencies in a new plugin

* Remove the old core plugin

There is no need for this to be separated now. It only held the callback implementations after we removed the merger.

* Use Eclipse BND tools to keep binaries out of our source repo

* Revert a little change no longer needed

* Remove the old target platform definitions - no need to keep them around

* Remove deprecated source feature generation

Replace it with an explicit source feature

* Remove deprecated source feature generation

Replace it with an explicit source feature

* Remove unnecessary dependencies

* Restore the function where we add the Java project to the runtime classpath

This seems to have changed in more recent Eclipse versions. The project was getting added to the bootstrap classpath and not the user classpath.

* Documentation Updates

* Setup artifact signing in the release profile

* Refactor the main entry point and shell callback so that Java merging is configurable and optional

* Refactor the main entry point and shell callback so that Java merging is configurable and optional

2295 of 3073 branches covered (74.68%)

66 of 96 new or added lines in 8 files covered. (68.75%)

4 existing lines in 3 files now uncovered.

11641 of 12943 relevant lines covered (89.94%)

0.9 hits per line

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

41.95
/core/mybatis-generator-core/src/main/java/org/mybatis/generator/api/MyBatisGenerator.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.ClassloaderUtility.getCustomClassloader;
19
import static org.mybatis.generator.internal.util.messages.Messages.getString;
20

21
import java.io.BufferedWriter;
22
import java.io.File;
23
import java.io.IOException;
24
import java.io.OutputStream;
25
import java.io.OutputStreamWriter;
26
import java.nio.charset.Charset;
27
import java.nio.file.Files;
28
import java.nio.file.Path;
29
import java.nio.file.StandardOpenOption;
30
import java.sql.SQLException;
31
import java.util.ArrayList;
32
import java.util.Collection;
33
import java.util.HashSet;
34
import java.util.List;
35
import java.util.Objects;
36
import java.util.Set;
37

38
import org.jspecify.annotations.Nullable;
39
import org.mybatis.generator.codegen.CalculatedContextValues;
40
import org.mybatis.generator.codegen.GenerationEngine;
41
import org.mybatis.generator.codegen.GenerationResults;
42
import org.mybatis.generator.codegen.IntrospectionEngine;
43
import org.mybatis.generator.codegen.RootClassInfo;
44
import org.mybatis.generator.config.Configuration;
45
import org.mybatis.generator.config.Context;
46
import org.mybatis.generator.exception.InternalException;
47
import org.mybatis.generator.exception.InvalidConfigurationException;
48
import org.mybatis.generator.exception.ShellException;
49
import org.mybatis.generator.internal.DefaultShellCallback;
50
import org.mybatis.generator.internal.ObjectFactory;
51
import org.mybatis.generator.merge.java.JavaFileMerger;
52
import org.mybatis.generator.merge.java.JavaMergerFactory;
53
import org.mybatis.generator.merge.xml.XmlFileMergerJaxp;
54

55
/**
56
 * This class is the main interface to MyBatis generator. A typical execution of the tool involves these steps:
57
 * <ol>
58
 * <li>Create a Configuration object. The Configuration can be the result of a parsing the XML configuration file, or it
59
 * can be created solely in Java.</li>
60
 * <li>Create a MyBatisGenerator object</li>
61
 * <li>Call one of the generate() methods</li>
62
 * </ol>
63
 *
64
 * @author Jeff Butler
65
 *
66
 * @see org.mybatis.generator.config.xml.ConfigurationParser
67
 */
68
public class MyBatisGenerator {
69
    private static final ProgressCallback NULL_PROGRESS_CALLBACK = new ProgressCallback() { };
1✔
70
    private final Configuration configuration;
71
    private final ShellCallback shellCallback;
72
    private final ProgressCallback progressCallback;
73
    private final Set<String> contextIds;
74
    private final Set<String> fullyQualifiedTableNames;
75
    private final JavaFileMerger javaFileMerger;
76
    private final boolean isOverwriteEnabled;
77
    private final boolean isJavaFileMergeEnabled;
78

79
    private final List<GenerationResults> generationResultsList = new ArrayList<>();
1✔
80

81
    private MyBatisGenerator(Builder builder) {
1✔
82
        configuration = Objects.requireNonNull(builder.configuration, getString("RuntimeError.2")); //$NON-NLS-1$
1✔
83
        shellCallback = Objects.requireNonNullElseGet(builder.shellCallback, DefaultShellCallback::new);
1✔
84
        progressCallback = Objects.requireNonNullElse(builder.progressCallback, NULL_PROGRESS_CALLBACK);
1✔
85
        fullyQualifiedTableNames = builder.fullyQualifiedTableNames;
1✔
86
        contextIds = builder.contextIds;
1✔
87

88
        if (builder.isJavaFileMergeEnabled) {
1!
NEW
89
            isJavaFileMergeEnabled = true;
×
NEW
90
            javaFileMerger = JavaMergerFactory.defaultMerger(builder.printerConfiguration);
×
91
        } else {
92
            isJavaFileMergeEnabled = false;
1✔
93
            javaFileMerger = (newContent, existingContent) -> newContent;
1✔
94
        }
95

96
        isOverwriteEnabled = builder.isOverwriteEnabled;
1✔
97
    }
1✔
98

99
    /**
100
     * This is one of the main methods for generating code. This method is long-running, but progress can be provided
101
     * and the method can be canceled through the ProgressCallback interface. This method will not write results to
102
     * the disk. The generated objects can be retrieved from the getGeneratedJavaFiles(), getGeneratedKotlinFiles(),
103
     * getGeneratedXmlFiles(), and getGeneratedGenericFiles() methods.
104
     *
105
     * @return any warnings created during the generation process
106
     * @throws SQLException
107
     *             the SQL exception
108
     * @throws InterruptedException
109
     *             if the method is canceled through the ProgressCallback
110
     * @throws InvalidConfigurationException
111
     *             if the specified configuration is invalid
112
     */
113
    public List<String> generateOnly() throws SQLException, InterruptedException, InvalidConfigurationException {
114
        List<String> warnings = new ArrayList<>();
1✔
115
        generateFiles(warnings);
1✔
116
        progressCallback.done();
1✔
117
        return warnings;
1✔
118
    }
119

120
    /**
121
     * This is one of the main methods for generating code. This method is long-running, but progress can be provided
122
     * and the method can be canceled through the ProgressCallback interface. This method will write results to
123
     * the disk.
124
     *
125
     * @return any warnings created during the generation process
126
     * @throws SQLException
127
     *             the SQL exception
128
     * @throws IOException
129
     *             Signals that an I/O exception has occurred.
130
     * @throws InterruptedException
131
     *             if the method is canceled through the ProgressCallback
132
     * @throws InvalidConfigurationException
133
     *             if the specified configuration is invalid
134
     */
135
    public List<String> generateAndWrite() throws SQLException, IOException, InterruptedException,
136
            InvalidConfigurationException {
137
        List<String> warnings = new ArrayList<>();
×
138
        generateFiles(warnings);
×
139
        writeGeneratedFiles(warnings);
×
140
        progressCallback.done();
×
141
        return warnings;
×
142
    }
143

144
    private void generateFiles(List<String> warnings) throws SQLException, InterruptedException,
145
            InvalidConfigurationException {
146
        configuration.validate();
1✔
147
        generationResultsList.clear();
1✔
148
        ObjectFactory.reset();
1✔
149
        RootClassInfo.reset();
1✔
150

151
        setupCustomClassloader();
1✔
152
        List<Context> contextsToRun = calculateContextsToRun();
1✔
153
        List<CalculatedContextValues> contextValuesList = calculateContextValues(contextsToRun, warnings);
1✔
154
        List<ContextValuesAndTables> contextValuesAndTablesList = runAllIntrospections(contextValuesList, warnings);
1✔
155
        List<GenerationEngine> generationEngines = createGenerationEngines(contextValuesAndTablesList, warnings);
1✔
156
        runGenerationEngines(generationEngines);
1✔
157
    }
1✔
158

159
    private void setupCustomClassloader() {
160
        if (!configuration.getClassPathEntries().isEmpty()) {
1!
161
            ClassLoader classLoader = getCustomClassloader(configuration.getClassPathEntries());
×
162
            ObjectFactory.addExternalClassLoader(classLoader);
×
163
        }
164
    }
1✔
165

166
    private List<Context> calculateContextsToRun() {
167
        List<Context> contextsToRun;
168
        if (fullyQualifiedTableNames.isEmpty()) {
1!
169
            contextsToRun = configuration.getContexts();
1✔
170
        } else {
171
            contextsToRun = configuration.getContexts().stream()
×
172
                    .filter(c -> contextIds.contains(c.getId()))
×
173
                    .toList();
×
174
        }
175

176
        return contextsToRun;
1✔
177
    }
178

179
    private List<CalculatedContextValues> calculateContextValues(List<Context> contextsToRun, List<String> warnings) {
180
        return contextsToRun.stream()
1✔
181
                .map(c -> createContextValues(c, warnings))
1✔
182
                .toList();
1✔
183
    }
184

185
    private CalculatedContextValues createContextValues(Context context, List<String> warnings) {
186
        return new CalculatedContextValues.Builder()
1✔
187
                .withContext(context)
1✔
188
                .withWarnings(warnings)
1✔
189
                .build();
1✔
190
    }
191

192
    private List<ContextValuesAndTables> runAllIntrospections(List<CalculatedContextValues> contextValuesList,
193
                                                              List<String> warnings)
194
            throws SQLException, InterruptedException {
195
        int totalSteps = contextValuesList.stream()
1✔
196
                .map(CalculatedContextValues::context)
1✔
197
                .mapToInt(Context::getIntrospectionSteps)
1✔
198
                .sum();
1✔
199
        progressCallback.introspectionStarted(totalSteps);
1✔
200

201
        List<ContextValuesAndTables> contextValuesAndTablesList = new ArrayList<>();
1✔
202
        for (CalculatedContextValues contextValues : contextValuesList) {
1✔
203
            contextValuesAndTablesList.add(new ContextValuesAndTables(contextValues,
1✔
204
                    runContextIntrospection(fullyQualifiedTableNames, contextValues, warnings)));
1✔
205
        }
1✔
206

207
        return contextValuesAndTablesList;
1✔
208
    }
209

210
    private List<IntrospectedTable> runContextIntrospection(Set<String> fullyQualifiedTableNames,
211
                                                            CalculatedContextValues contextValues,
212
                                                            List<String> warnings)
213
            throws SQLException, InterruptedException {
214
        return new IntrospectionEngine.Builder()
1✔
215
                .withContextValues(contextValues)
1✔
216
                .withFullyQualifiedTableNames(fullyQualifiedTableNames)
1✔
217
                .withWarnings(warnings)
1✔
218
                .withProgressCallback(progressCallback)
1✔
219
                .build()
1✔
220
                .introspectTables();
1✔
221
    }
222

223
    private List<GenerationEngine> createGenerationEngines(List<ContextValuesAndTables> contextValuesAndTablesListList,
224
                                                           List<String> warnings) {
225
        return contextValuesAndTablesListList.stream()
1✔
226
                .map(c -> createGenerationEngine(c, warnings))
1✔
227
                .toList();
1✔
228
    }
229

230
    private GenerationEngine createGenerationEngine(ContextValuesAndTables contextValuesAndTables,
231
                                                    List<String> warnings) {
232
        return new GenerationEngine.Builder()
1✔
233
                .withContextValues(contextValuesAndTables.contextValues())
1✔
234
                .withProgressCallback(progressCallback)
1✔
235
                .withWarnings(warnings)
1✔
236
                .withIntrospectedTables(contextValuesAndTables.introspectedTables())
1✔
237
                .build();
1✔
238
    }
239

240
    private void runGenerationEngines(List<GenerationEngine> generationEngines) throws InterruptedException {
241
        // calculate the number of steps
242
        int totalSteps = generationEngines.stream().mapToInt(GenerationEngine::getGenerationSteps).sum();
1✔
243
        progressCallback.generationStarted(totalSteps);
1✔
244

245
        // now run the generators
246
        for (GenerationEngine generationEngine: generationEngines) {
1✔
247
            var generationResults = generationEngine.generate();
1✔
248
            generationResultsList.add(generationResults);
1✔
249
        }
1✔
250
    }
1✔
251

252
    private void writeGeneratedFiles(List<String> warnings) throws IOException, InterruptedException {
253
        Set<String> projects = new HashSet<>();
×
254
        int totalSteps = generationResultsList.stream().mapToInt(GenerationResults::getNumberOfGeneratedFiles).sum();
×
255
        progressCallback.saveStarted(totalSteps);
×
256

257
        for (GenerationResults generationResults : generationResultsList) {
×
258
            for (GeneratedXmlFile gxf : generationResults.generatedXmlFiles()) {
×
259
                projects.add(gxf.getTargetProject());
×
260
                writeGeneratedXmlFile(gxf, generationResults.xmlFormatter(), warnings);
×
261
            }
×
262

263
            for (GeneratedJavaFile gjf : generationResults.generatedJavaFiles()) {
×
264
                projects.add(gjf.getTargetProject());
×
265
                writeGeneratedJavaFile(gjf, generationResults.javaFormatter(), generationResults.javaFileEncoding(),
×
266
                        warnings);
267
            }
×
268

269
            for (GeneratedKotlinFile gkf : generationResults.generatedKotlinFiles()) {
×
270
                projects.add(gkf.getTargetProject());
×
271
                writeGeneratedKotlinFile(gkf, generationResults.kotlinFormatter(),
×
272
                        generationResults.kotlinFileEncoding(), warnings);
×
273
            }
×
274

275
            for (GenericGeneratedFile gf : generationResults.generatedGenericFiles()) {
×
276
                projects.add(gf.getTargetProject());
×
277
                writeGenericGeneratedFile(gf, warnings);
×
278
            }
×
279
        }
×
280

281
        for (String project : projects) {
×
282
            shellCallback.refreshProject(project);
×
283
        }
×
284
    }
×
285

286
    private void writeGeneratedJavaFile(GeneratedJavaFile gjf, JavaFormatter javaFormatter,
287
                                        @Nullable String javaFileEncoding, List<String> warnings)
288
            throws InterruptedException, IOException {
289
        Path targetFile;
290
        String source = javaFormatter.getFormattedContent(gjf.getCompilationUnit());
×
291
        try {
292
            File directory = shellCallback.getDirectory(gjf.getTargetProject(), gjf.getTargetPackage());
×
293
            targetFile = directory.toPath().resolve(gjf.getFileName());
×
294
            if (Files.exists(targetFile)) {
×
NEW
295
                if (isJavaFileMergeEnabled) {
×
NEW
296
                    source = javaFileMerger.getMergedSource(source, targetFile.toFile(), javaFileEncoding);
×
NEW
297
                } else if (isOverwriteEnabled) {
×
UNCOV
298
                    warnings.add(getString("Warning.11", targetFile.toFile().getAbsolutePath())); //$NON-NLS-1$
×
299
                } else {
300
                    targetFile = getUniqueFileName(directory, gjf.getFileName());
×
301
                    warnings.add(getString("Warning.2", targetFile.toFile().getAbsolutePath())); //$NON-NLS-1$
×
302
                }
303
            }
304

305
            progressCallback.checkCancel();
×
306
            progressCallback.startTask(getString("Progress.15", targetFile.toString())); //$NON-NLS-1$
×
307
            writeFile(targetFile.toFile(), source, javaFileEncoding);
×
308
        } catch (ShellException e) {
×
309
            warnings.add(e.getMessage());
×
310
        }
×
311
    }
×
312

313
    private void writeGeneratedKotlinFile(GeneratedKotlinFile gf, KotlinFormatter kotlinFormatter,
314
                                          @Nullable String kotlinFileEncoding, List<String> warnings)
315
            throws InterruptedException, IOException {
316
        Path targetFile;
317
        String source = kotlinFormatter.getFormattedContent(gf.getKotlinFile());
×
318
        try {
319
            File directory = shellCallback.getDirectory(gf.getTargetProject(), gf.getTargetPackage());
×
320
            targetFile = directory.toPath().resolve(gf.getFileName());
×
321
            if (Files.exists(targetFile)) {
×
NEW
322
                if (isOverwriteEnabled) {
×
323
                    warnings.add(getString("Warning.11", targetFile.toFile().getAbsolutePath())); //$NON-NLS-1$
×
324
                } else {
325
                    targetFile = getUniqueFileName(directory, gf.getFileName());
×
326
                    warnings.add(getString("Warning.2", targetFile.toFile().getAbsolutePath())); //$NON-NLS-1$
×
327
                }
328
            }
329

330
            progressCallback.checkCancel();
×
331
            progressCallback.startTask(getString("Progress.15", targetFile.toString())); //$NON-NLS-1$
×
332
            writeFile(targetFile.toFile(), source, kotlinFileEncoding);
×
333
        } catch (ShellException e) {
×
334
            warnings.add(e.getMessage());
×
335
        }
×
336
    }
×
337

338
    private void writeGenericGeneratedFile(GenericGeneratedFile gf, List<String> warnings)
339
            throws InterruptedException, IOException {
340
        Path targetFile;
341
        String source = gf.getFormattedContent();
×
342
        try {
343
            File directory = shellCallback.getDirectory(gf.getTargetProject(), gf.getTargetPackage());
×
344
            targetFile = directory.toPath().resolve(gf.getFileName());
×
345
            if (Files.exists(targetFile)) {
×
NEW
346
                if (isOverwriteEnabled) {
×
347
                    warnings.add(getString("Warning.11", targetFile.toFile().getAbsolutePath())); //$NON-NLS-1$
×
348
                } else {
349
                    targetFile = getUniqueFileName(directory, gf.getFileName());
×
350
                    warnings.add(getString("Warning.2", targetFile.toFile().getAbsolutePath())); //$NON-NLS-1$
×
351
                }
352
            }
353

354
            progressCallback.checkCancel();
×
355
            progressCallback.startTask(getString("Progress.15", targetFile.toString())); //$NON-NLS-1$
×
356
            writeFile(targetFile.toFile(), source, gf.getFileEncoding().orElse(null));
×
357
        } catch (ShellException e) {
×
358
            warnings.add(e.getMessage());
×
359
        }
×
360
    }
×
361

362
    private void writeGeneratedXmlFile(GeneratedXmlFile gxf, XmlFormatter xmlFormatter, List<String> warnings)
363
            throws InterruptedException, IOException {
364
        Path targetFile;
365
        String source = xmlFormatter.getFormattedContent(gxf.getDocument());
×
366
        try {
367
            File directory = shellCallback.getDirectory(gxf.getTargetProject(), gxf.getTargetPackage());
×
368
            targetFile = directory.toPath().resolve(gxf.getFileName());
×
369
            if (Files.exists(targetFile)) {
×
370
                if (gxf.isMergeable()) {
×
371
                    source = XmlFileMergerJaxp.getMergedSource(source, targetFile.toFile());
×
NEW
372
                } else if (isOverwriteEnabled) {
×
373
                    warnings.add(getString("Warning.11", targetFile.toFile().getAbsolutePath())); //$NON-NLS-1$
×
374
                } else {
375
                    targetFile = getUniqueFileName(directory, gxf.getFileName());
×
376
                    warnings.add(getString("Warning.2", targetFile.toFile().getAbsolutePath())); //$NON-NLS-1$
×
377
                }
378
            }
379

380
            progressCallback.checkCancel();
×
381
            progressCallback.startTask(getString("Progress.15", targetFile.toString())); //$NON-NLS-1$
×
382
            writeFile(targetFile.toFile(), source, "UTF-8"); //$NON-NLS-1$
×
383
        } catch (ShellException e) {
×
384
            warnings.add(e.getMessage());
×
385
        }
×
386
    }
×
387

388
    /**
389
     * Writes, or overwrites, the contents of the specified file.
390
     *
391
     * @param file
392
     *            the file
393
     * @param content
394
     *            the content
395
     * @param fileEncoding
396
     *            the file encoding
397
     * @throws IOException
398
     *             Signals that an I/O exception has occurred.
399
     */
400
    private void writeFile(File file, String content, @Nullable String fileEncoding) throws IOException {
401
        try (OutputStream fos = Files.newOutputStream(file.toPath(), StandardOpenOption.CREATE,
×
402
                StandardOpenOption.TRUNCATE_EXISTING)) {
403
            OutputStreamWriter osw;
404
            if (fileEncoding == null) {
×
405
                osw = new OutputStreamWriter(fos);
×
406
            } else {
407
                osw = new OutputStreamWriter(fos, Charset.forName(fileEncoding));
×
408
            }
409

410
            try (BufferedWriter bw = new BufferedWriter(osw)) {
×
411
                bw.write(content);
×
412
            }
413
        }
414
    }
×
415

416
    /**
417
     * Gets the unique file name.
418
     *
419
     * @param directory
420
     *            the directory
421
     * @param fileName
422
     *            the file name
423
     * @return the unique file name
424
     */
425
    private Path getUniqueFileName(File directory, String fileName) {
426
        Path answer = null;
×
427

428
        // try up to 1000 times to generate a unique file name
429
        StringBuilder sb = new StringBuilder();
×
430
        for (int i = 1; i < 1000; i++) {
×
431
            sb.setLength(0);
×
432
            sb.append(fileName);
×
433
            sb.append('.');
×
434
            sb.append(i);
×
435

436
            Path testFile = directory.toPath().resolve(sb.toString());
×
437
            if (Files.notExists(testFile)) {
×
438
                answer = testFile;
×
439
                break;
×
440
            }
441
        }
442

443
        if (answer == null) {
×
444
            throw new InternalException(getString("RuntimeError.3", directory.getAbsolutePath())); //$NON-NLS-1$
×
445
        }
446

447
        return answer;
×
448
    }
449

450
    /**
451
     * Returns the list of generated Java files after a call to one of the generate methods.
452
     * This is useful if you prefer to process the generated files yourself and do not want
453
     * the generator to write them to disk.
454
     *
455
     * @return the list of generated Java files
456
     */
457
    public List<GeneratedJavaFile> getGeneratedJavaFiles() {
458
        return generationResultsList.stream()
1✔
459
                .map(GenerationResults::generatedJavaFiles)
1✔
460
                .flatMap(Collection::stream)
1✔
461
                .toList();
1✔
462
    }
463

464
    /**
465
     * Returns the list of generated Kotlin files after a call to one of the generate methods.
466
     * This is useful if you prefer to process the generated files yourself and do not want
467
     * the generator to write them to disk.
468
     *
469
     * @return the list of generated Kotlin files
470
     */
471
    public List<GeneratedKotlinFile> getGeneratedKotlinFiles() {
472
        return generationResultsList.stream()
1✔
473
                .map(GenerationResults::generatedKotlinFiles)
1✔
474
                .flatMap(Collection::stream)
1✔
475
                .toList();
1✔
476
    }
477

478
    /**
479
     * Returns the list of generated XML files after a call to one of the generate methods.
480
     * This is useful if you prefer to process the generated files yourself and do not want
481
     * the generator to write them to disk.
482
     *
483
     * @return the list of generated XML files
484
     */
485
    public List<GeneratedXmlFile> getGeneratedXmlFiles() {
486
        return generationResultsList.stream()
1✔
487
                .map(GenerationResults::generatedXmlFiles)
1✔
488
                .flatMap(Collection::stream)
1✔
489
                .toList();
1✔
490
    }
491

492
    /**
493
     * Returns the list of generated generic files after a call to one of the generate methods.
494
     * This is useful if you prefer to process the generated files yourself and do not want
495
     * the generator to write them to disk.
496
     *
497
     * <p>The list will be empty unless you have used a plugin that generates generic files
498
     * or are using a custom runtime.
499
     *
500
     * @return the list of generated generic files
501
     */
502
    public List<GenericGeneratedFile> getGeneratedGenericFiles() {
503
        return generationResultsList.stream()
×
504
                .map(GenerationResults::generatedGenericFiles)
×
505
                .flatMap(Collection::stream)
×
506
                .toList();
×
507
    }
508

509
    private record ContextValuesAndTables(CalculatedContextValues contextValues,
1✔
510
                                          List<IntrospectedTable> introspectedTables) { }
511

512
    public static class Builder {
1✔
513
        private @Nullable Configuration configuration;
514
        private @Nullable ShellCallback shellCallback;
515
        private @Nullable ProgressCallback progressCallback;
516
        private final Set<String> contextIds = new HashSet<>();
1✔
517
        private final Set<String> fullyQualifiedTableNames = new HashSet<>();
1✔
518
        private boolean isOverwriteEnabled = false;
1✔
519
        private boolean isJavaFileMergeEnabled = false;
1✔
520
        private @Nullable Object printerConfiguration;
521

522
        public Builder withConfiguration(Configuration configuration) {
523
            this.configuration = configuration;
1✔
524
            return this;
1✔
525
        }
526

527
        public Builder withShellCallback(ShellCallback shellCallback) {
528
            this.shellCallback = shellCallback;
1✔
529
            return this;
1✔
530
        }
531

532
        public Builder withProgressCallback(@Nullable ProgressCallback progressCallback) {
533
            this.progressCallback = progressCallback;
×
534
            return this;
×
535
        }
536

537
        /**
538
         * Set of context IDs to use in generation. Only the contexts with an id specified in this set will run.
539
         * If the set is empty, then all contexts are run.
540
         *
541
         * @param contextIds
542
         *            a set of contextIds to use in code generation
543
         *
544
         * @return this builder
545
         */
546
        public Builder withContextIds(Set<String> contextIds) {
547
            this.contextIds.addAll(contextIds);
×
548
            return this;
×
549
        }
550

551
        /**
552
         *  Set of table names to generate. The elements of the set must be Strings that exactly match what's
553
         *  specified in the configuration. For example, if a table name = "foo" and schema = "bar", then the fully
554
         *  qualified table name is "foo.bar". If the Set is empty, then all tables in the configuration
555
         *  will be used for code generation.
556
         *
557
         * @param fullyQualifiedTableNames
558
         *            a set of table names to use in code generation
559
         *
560
         * @return this builder
561
         */
562
        public Builder withFullyQualifiedTableNames(Set<String> fullyQualifiedTableNames) {
563
            this.fullyQualifiedTableNames.addAll(fullyQualifiedTableNames);
×
564
            return this;
×
565
        }
566

567
        /**
568
         * If true, then newly generated files will overwrite existing files if there is a collision.
569
         * If false, then newly generated files will be written with a unique name when there is a collision.
570
         *
571
         * <p>The default is <code>false</code></p>
572
         *
573
         * @param overwriteEnabled where newly generated files should overwrite existing files if there is a collision
574
         * @return this builder
575
         */
576
        public Builder withOverwriteEnabled(boolean overwriteEnabled) {
577
            this.isOverwriteEnabled = overwriteEnabled;
1✔
578
            return this;
1✔
579
        }
580

581
        /**
582
         * If true, then newly generated Java files will be merged if they collide with existing files.
583
         * If false, then the {@link #withOverwriteEnabled(boolean)} value governs what happens on a collision.
584
         *
585
         * <p>The default is <code>false</code></p>
586
         *
587
         * @param javaFileMergeEnabled where the Java file merger support should be enabled
588
         * @return this builder
589
         */
590
        public Builder withJavaFileMergeEnabled(boolean javaFileMergeEnabled) {
NEW
591
            this.isJavaFileMergeEnabled = javaFileMergeEnabled;
×
NEW
592
            return this;
×
593
        }
594

595
        /**
596
         * Add a printer configuration that will be used during Java code merging. If specified, the
597
         * object must be an instance of {@link com.github.javaparser.printer.configuration.PrinterConfiguration}.
598
         * If not specified, then the default printer configuration will be used.
599
         *
600
         * @param printerConfiguration a printer configuration
601
         * @return this builder
602
         */
603
        public Builder withPrinterConfiguration(Object printerConfiguration) {
NEW
604
            this.printerConfiguration = printerConfiguration;
×
NEW
605
            return this;
×
606
        }
607

608
        public MyBatisGenerator build() {
609
            return new MyBatisGenerator(this);
1✔
610
        }
611
    }
612
}
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