001/*
002 *  Copyright (c) 2022-2024, Mybatis-Flex (fuhai999@gmail.com).
003 *  <p>
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  You may obtain a copy of the License at
007 *  <p>
008 *  http://www.apache.org/licenses/LICENSE-2.0
009 *  <p>
010 *  Unless required by applicable law or agreed to in writing, software
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016package com.mybatisflex.spring.boot;
017
018import com.mybatisflex.core.FlexConsts;
019import com.mybatisflex.core.FlexGlobalConfig;
020import org.apache.ibatis.io.VFS;
021import org.apache.ibatis.logging.Log;
022import org.apache.ibatis.mapping.ResultSetType;
023import org.apache.ibatis.scripting.LanguageDriver;
024import org.apache.ibatis.session.AutoMappingBehavior;
025import org.apache.ibatis.session.AutoMappingUnknownColumnBehavior;
026import org.apache.ibatis.session.Configuration;
027import org.apache.ibatis.session.ExecutorType;
028import org.apache.ibatis.session.LocalCacheScope;
029import org.apache.ibatis.type.JdbcType;
030import org.apache.ibatis.type.TypeHandler;
031import org.springframework.boot.context.properties.ConfigurationProperties;
032import org.springframework.boot.context.properties.NestedConfigurationProperty;
033import org.springframework.boot.context.properties.PropertyMapper;
034import org.springframework.core.io.Resource;
035import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
036import org.springframework.core.io.support.ResourcePatternResolver;
037
038import java.io.IOException;
039import java.util.Map;
040import java.util.Optional;
041import java.util.Properties;
042import java.util.Set;
043import java.util.stream.Stream;
044
045/**
046 * Mybatis-Flex 的配置属性。
047 * 参考:https://github.com/mybatis/spring-boot-starter/blob/master/mybatis-spring-boot-autoconfigure/src/main/java/org/mybatis/spring/boot/autoconfigure/MybatisProperties.java
048 *
049 * @author Eddú Meléndez
050 * @author Kazuki Shimizu
051 * @author micahel
052 * @author 王帅
053 */
054@ConfigurationProperties(prefix = "mybatis-flex")
055public class MybatisFlexProperties {
056
057    private static final ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver();
058
059    private String defaultDatasourceKey;
060
061    /**
062     * <p>多数据源的配置。
063     *
064     * <p>
065     * mybatis-flex.datasource.ds1.url=***<br>
066     * mybatis-flex.datasource.ds2.url=***
067     */
068    private Map<String, Map<String, String>> datasource;
069
070    /**
071     * 全局配置。
072     */
073    private GlobalConfig globalConfig;
074
075    /**
076     * MyBatis-Flex-Admin 配置。
077     */
078    private AdminConfig adminConfig;
079
080    /**
081     * Location of MyBatis xml config file.
082     */
083    private String configLocation;
084
085    /**
086     * Locations of MyBatis mapper files.
087     */
088    private String[] mapperLocations = new String[]{"classpath*:/mapper/**/*.xml"};
089
090    /**
091     * Packages to search type aliases. (Package delimiters are ",; \t\n")
092     */
093    private String typeAliasesPackage;
094
095    /**
096     * The super class for filtering type alias. If this not specifies, the MyBatis deal as type alias all classes that
097     * searched from typeAliasesPackage.
098     */
099    private Class<?> typeAliasesSuperType;
100
101    /**
102     * Packages to search for type handlers. (Package delimiters are ",; \t\n")
103     */
104    private String typeHandlersPackage;
105
106    /**
107     * Indicates whether perform presence check of the MyBatis xml config file.
108     */
109    private boolean checkConfigLocation = false;
110
111    /**
112     * Execution mode for {@link org.mybatis.spring.SqlSessionTemplate}.
113     */
114    private ExecutorType executorType;
115
116    /**
117     * The default scripting language driver class. (Available when use together with mybatis-spring 2.0.2+)
118     */
119    private Class<? extends LanguageDriver> defaultScriptingLanguageDriver;
120
121    /**
122     * Externalized properties for MyBatis configuration.
123     */
124    private Properties configurationProperties;
125
126    /**
127     * A Configuration object for customize default settings. If {@link #configLocation} is specified, this property is
128     * not used.
129     */
130    private CoreConfiguration configuration;
131
132    /**
133     * A Configuration object for seata
134     */
135    private SeataConfig seataConfig;
136
137    public SeataConfig getSeataConfig() {
138        return seataConfig;
139    }
140
141    public void setSeataConfig(SeataConfig seataConfig) {
142        this.seataConfig = seataConfig;
143    }
144
145    public Map<String, Map<String, String>> getDatasource() {
146        return datasource;
147    }
148
149    public void setDatasource(Map<String, Map<String, String>> datasource) {
150        this.datasource = datasource;
151    }
152
153    public GlobalConfig getGlobalConfig() {
154        return globalConfig;
155    }
156
157    public void setGlobalConfig(GlobalConfig globalConfig) {
158        this.globalConfig = globalConfig;
159    }
160
161    public AdminConfig getAdminConfig() {
162        return adminConfig;
163    }
164
165    public void setAdminConfig(AdminConfig adminConfig) {
166        this.adminConfig = adminConfig;
167    }
168
169    public String getDefaultDatasourceKey() {
170        return defaultDatasourceKey;
171    }
172
173    public void setDefaultDatasourceKey(String defaultDatasourceKey) {
174        this.defaultDatasourceKey = defaultDatasourceKey;
175    }
176
177    /**
178     * @since 1.1.0
179     */
180    public String getConfigLocation() {
181        return this.configLocation;
182    }
183
184    /**
185     * @since 1.1.0
186     */
187    public void setConfigLocation(String configLocation) {
188        this.configLocation = configLocation;
189    }
190
191    public String[] getMapperLocations() {
192        return this.mapperLocations;
193    }
194
195    public void setMapperLocations(String[] mapperLocations) {
196        this.mapperLocations = mapperLocations;
197    }
198
199    public String getTypeHandlersPackage() {
200        return this.typeHandlersPackage;
201    }
202
203    public void setTypeHandlersPackage(String typeHandlersPackage) {
204        this.typeHandlersPackage = typeHandlersPackage;
205    }
206
207    public String getTypeAliasesPackage() {
208        return this.typeAliasesPackage;
209    }
210
211    public void setTypeAliasesPackage(String typeAliasesPackage) {
212        this.typeAliasesPackage = typeAliasesPackage;
213    }
214
215    /**
216     * @since 1.3.3
217     */
218    public Class<?> getTypeAliasesSuperType() {
219        return typeAliasesSuperType;
220    }
221
222    /**
223     * @since 1.3.3
224     */
225    public void setTypeAliasesSuperType(Class<?> typeAliasesSuperType) {
226        this.typeAliasesSuperType = typeAliasesSuperType;
227    }
228
229    public boolean isCheckConfigLocation() {
230        return this.checkConfigLocation;
231    }
232
233    public void setCheckConfigLocation(boolean checkConfigLocation) {
234        this.checkConfigLocation = checkConfigLocation;
235    }
236
237    public ExecutorType getExecutorType() {
238        return this.executorType;
239    }
240
241    public void setExecutorType(ExecutorType executorType) {
242        this.executorType = executorType;
243    }
244
245    /**
246     * @since 2.1.0
247     */
248    public Class<? extends LanguageDriver> getDefaultScriptingLanguageDriver() {
249        return defaultScriptingLanguageDriver;
250    }
251
252    /**
253     * @since 2.1.0
254     */
255    public void setDefaultScriptingLanguageDriver(Class<? extends LanguageDriver> defaultScriptingLanguageDriver) {
256        this.defaultScriptingLanguageDriver = defaultScriptingLanguageDriver;
257    }
258
259    /**
260     * @since 1.2.0
261     */
262    public Properties getConfigurationProperties() {
263        return configurationProperties;
264    }
265
266    /**
267     * @since 1.2.0
268     */
269    public void setConfigurationProperties(Properties configurationProperties) {
270        this.configurationProperties = configurationProperties;
271    }
272
273    public CoreConfiguration getConfiguration() {
274        return configuration;
275    }
276
277    public void setConfiguration(CoreConfiguration configuration) {
278        this.configuration = configuration;
279    }
280
281    public Resource[] resolveMapperLocations() {
282        return Stream.of(Optional.ofNullable(this.mapperLocations).orElse(new String[0]))
283            .flatMap(location -> Stream.of(getResources(location))).toArray(Resource[]::new);
284    }
285
286    private Resource[] getResources(String location) {
287        try {
288            return resourceResolver.getResources(location);
289        } catch (IOException e) {
290            return new Resource[0];
291        }
292    }
293
294    /**
295     * The configuration properties for mybatis core module.
296     *
297     * @since 3.0.0
298     */
299    public static class CoreConfiguration {
300
301        /**
302         * Allows using RowBounds on nested statements. If allow, set the false. Default is false.
303         */
304        private Boolean safeRowBoundsEnabled;
305
306        /**
307         * Allows using ResultHandler on nested statements. If allow, set the false. Default is true.
308         */
309        private Boolean safeResultHandlerEnabled;
310
311        /**
312         * Enables automatic mapping from classic database column names A_COLUMN to camel case classic Java property names
313         * aColumn. Default is true.
314         */
315        private Boolean mapUnderscoreToCamelCase = true;
316
317        /**
318         * When enabled, any method call will load all the lazy properties of the object. Otherwise, each property is loaded
319         * on demand (see also lazyLoadTriggerMethods). Default is false.
320         */
321        private Boolean aggressiveLazyLoading;
322
323        /**
324         * Allows or disallows multiple ResultSets to be returned from a single statement (compatible driver required).
325         * Default is true.
326         */
327        private Boolean multipleResultSetsEnabled;
328
329        /**
330         * Allows JDBC support for generated keys. A compatible driver is required. This setting forces generated keys to be
331         * used if set to true, as some drivers deny compatibility but still work (e.g. Derby). Default is false.
332         */
333        private Boolean useGeneratedKeys;
334
335        /**
336         * Uses the column label instead of the column name. Different drivers behave differently in this respect. Refer to
337         * the driver documentation, or test out both modes to determine how your driver behaves. Default is true.
338         */
339        private Boolean useColumnLabel;
340
341        /**
342         * Globally enables or disables any caches configured in any mapper under this configuration. Default is true.
343         */
344        private Boolean cacheEnabled;
345
346        /**
347         * Specifies if setters or map's put method will be called when a retrieved value is null. It is useful when you
348         * rely on Map.keySet() or null value initialization. Note primitives such as (int,boolean,etc.) will not be set to
349         * null. Default is false.
350         */
351        private Boolean callSettersOnNulls;
352
353        /**
354         * Allow referencing statement parameters by their actual names declared in the method signature. To use this
355         * feature, your project must be compiled in Java 8 with -parameters option. Default is true.
356         */
357        private Boolean useActualParamName;
358
359        /**
360         * MyBatis, by default, returns null when all the columns of a returned row are NULL. When this setting is enabled,
361         * MyBatis returns an empty instance instead. Note that it is also applied to nested results (i.e. collectioin and
362         * association). Default is false.
363         */
364        private Boolean returnInstanceForEmptyRow;
365
366        /**
367         * Removes extra whitespace characters from the SQL. Note that this also affects literal strings in SQL. Default is
368         * false.
369         */
370        private Boolean shrinkWhitespacesInSql;
371
372        /**
373         * Specifies the default value of 'nullable' attribute on 'foreach' tag. Default is false.
374         */
375        private Boolean nullableOnForEach;
376
377        /**
378         * When applying constructor auto-mapping, argument name is used to search the column to map instead of relying on
379         * the column order. Default is false.
380         */
381        private Boolean argNameBasedConstructorAutoMapping;
382
383        /**
384         * Globally enables or disables lazy loading. When enabled, all relations will be lazily loaded. This value can be
385         * superseded for a specific relation by using the fetchType attribute on it. Default is False.
386         */
387        private Boolean lazyLoadingEnabled;
388
389        /**
390         * Sets the number of seconds the driver will wait for a response from the database.
391         */
392        private Integer defaultStatementTimeout;
393
394        /**
395         * Sets the driver a hint as to control fetching size for return results. This parameter value can be override by a
396         * query setting.
397         */
398        private Integer defaultFetchSize;
399
400        /**
401         * MyBatis uses local cache to prevent circular references and speed up repeated nested queries. By default
402         * (SESSION) all queries executed during a session are cached. If localCacheScope=STATEMENT local session will be
403         * used just for statement execution, no data will be shared between two different calls to the same SqlSession.
404         * Default is SESSION.
405         */
406        private LocalCacheScope localCacheScope;
407
408        /**
409         * Specifies the JDBC type for null values when no specific JDBC type was provided for the parameter. Some drivers
410         * require specifying the column JDBC type but others work with generic values like NULL, VARCHAR or OTHER. Default
411         * is OTHER.
412         */
413        private JdbcType jdbcTypeForNull;
414
415        /**
416         * Specifies a scroll strategy when omit it per statement settings.
417         */
418        private ResultSetType defaultResultSetType;
419
420        /**
421         * Configures the default executor. SIMPLE executor does nothing special. REUSE executor reuses prepared statements.
422         * BATCH executor reuses statements and batches updates. Default is SIMPLE.
423         */
424        private ExecutorType defaultExecutorType;
425
426        /**
427         * Specifies if and how MyBatis should automatically map columns to fields/properties. NONE disables auto-mapping.
428         * PARTIAL will only auto-map results with no nested result mappings defined inside. FULL will auto-map result
429         * mappings of any complexity (containing nested or otherwise). Default is PARTIAL.
430         */
431        private AutoMappingBehavior autoMappingBehavior;
432
433        /**
434         * Specify the behavior when detects an unknown column (or unknown property type) of automatic mapping target.
435         * Default is NONE.
436         */
437        private AutoMappingUnknownColumnBehavior autoMappingUnknownColumnBehavior;
438
439        /**
440         * Specifies the prefix string that MyBatis will add to the logger names.
441         */
442        private String logPrefix;
443
444        /**
445         * Specifies which Object's methods trigger a lazy load. Default is [equals,clone,hashCode,toString].
446         */
447        private Set<String> lazyLoadTriggerMethods;
448
449        /**
450         * Specifies which logging implementation MyBatis should use. If this setting is not present logging implementation
451         * will be autodiscovered.
452         */
453        private Class<? extends Log> logImpl;
454
455        /**
456         * Specifies VFS implementations.
457         */
458        private Class<? extends VFS> vfsImpl;
459
460        /**
461         * Specifies an sql provider class that holds provider method. This class apply to the type(or value) attribute on
462         * sql provider annotation(e.g. @SelectProvider), when these attribute was omitted.
463         */
464        private Class<?> defaultSqlProviderType;
465
466        /**
467         * Specifies the TypeHandler used by default for Enum.
468         */
469        Class<? extends TypeHandler> defaultEnumTypeHandler;
470
471        /**
472         * Specifies the class that provides an instance of Configuration. The returned Configuration instance is used to
473         * load lazy properties of deserialized objects. This class must have a method with a signature static Configuration
474         * getConfiguration().
475         */
476        private Class<?> configurationFactory;
477
478        /**
479         * Specify any configuration variables.
480         */
481        private Properties variables;
482
483        public Boolean getSafeRowBoundsEnabled() {
484            return safeRowBoundsEnabled;
485        }
486
487        public void setSafeRowBoundsEnabled(Boolean safeRowBoundsEnabled) {
488            this.safeRowBoundsEnabled = safeRowBoundsEnabled;
489        }
490
491        public Boolean getSafeResultHandlerEnabled() {
492            return safeResultHandlerEnabled;
493        }
494
495        public void setSafeResultHandlerEnabled(Boolean safeResultHandlerEnabled) {
496            this.safeResultHandlerEnabled = safeResultHandlerEnabled;
497        }
498
499        public Boolean getMapUnderscoreToCamelCase() {
500            return mapUnderscoreToCamelCase;
501        }
502
503        public void setMapUnderscoreToCamelCase(Boolean mapUnderscoreToCamelCase) {
504            this.mapUnderscoreToCamelCase = mapUnderscoreToCamelCase;
505        }
506
507        public Boolean getAggressiveLazyLoading() {
508            return aggressiveLazyLoading;
509        }
510
511        public void setAggressiveLazyLoading(Boolean aggressiveLazyLoading) {
512            this.aggressiveLazyLoading = aggressiveLazyLoading;
513        }
514
515        public Boolean getMultipleResultSetsEnabled() {
516            return multipleResultSetsEnabled;
517        }
518
519        public void setMultipleResultSetsEnabled(Boolean multipleResultSetsEnabled) {
520            this.multipleResultSetsEnabled = multipleResultSetsEnabled;
521        }
522
523        public Boolean getUseGeneratedKeys() {
524            return useGeneratedKeys;
525        }
526
527        public void setUseGeneratedKeys(Boolean useGeneratedKeys) {
528            this.useGeneratedKeys = useGeneratedKeys;
529        }
530
531        public Boolean getUseColumnLabel() {
532            return useColumnLabel;
533        }
534
535        public void setUseColumnLabel(Boolean useColumnLabel) {
536            this.useColumnLabel = useColumnLabel;
537        }
538
539        public Boolean getCacheEnabled() {
540            return cacheEnabled;
541        }
542
543        public void setCacheEnabled(Boolean cacheEnabled) {
544            this.cacheEnabled = cacheEnabled;
545        }
546
547        public Boolean getCallSettersOnNulls() {
548            return callSettersOnNulls;
549        }
550
551        public void setCallSettersOnNulls(Boolean callSettersOnNulls) {
552            this.callSettersOnNulls = callSettersOnNulls;
553        }
554
555        public Boolean getUseActualParamName() {
556            return useActualParamName;
557        }
558
559        public void setUseActualParamName(Boolean useActualParamName) {
560            this.useActualParamName = useActualParamName;
561        }
562
563        public Boolean getReturnInstanceForEmptyRow() {
564            return returnInstanceForEmptyRow;
565        }
566
567        public void setReturnInstanceForEmptyRow(Boolean returnInstanceForEmptyRow) {
568            this.returnInstanceForEmptyRow = returnInstanceForEmptyRow;
569        }
570
571        public Boolean getShrinkWhitespacesInSql() {
572            return shrinkWhitespacesInSql;
573        }
574
575        public void setShrinkWhitespacesInSql(Boolean shrinkWhitespacesInSql) {
576            this.shrinkWhitespacesInSql = shrinkWhitespacesInSql;
577        }
578
579        public Boolean getNullableOnForEach() {
580            return nullableOnForEach;
581        }
582
583        public void setNullableOnForEach(Boolean nullableOnForEach) {
584            this.nullableOnForEach = nullableOnForEach;
585        }
586
587        public Boolean getArgNameBasedConstructorAutoMapping() {
588            return argNameBasedConstructorAutoMapping;
589        }
590
591        public void setArgNameBasedConstructorAutoMapping(Boolean argNameBasedConstructorAutoMapping) {
592            this.argNameBasedConstructorAutoMapping = argNameBasedConstructorAutoMapping;
593        }
594
595        public String getLogPrefix() {
596            return logPrefix;
597        }
598
599        public void setLogPrefix(String logPrefix) {
600            this.logPrefix = logPrefix;
601        }
602
603        public Class<? extends Log> getLogImpl() {
604            return logImpl;
605        }
606
607        public void setLogImpl(Class<? extends Log> logImpl) {
608            this.logImpl = logImpl;
609        }
610
611        public Class<? extends VFS> getVfsImpl() {
612            return vfsImpl;
613        }
614
615        public void setVfsImpl(Class<? extends VFS> vfsImpl) {
616            this.vfsImpl = vfsImpl;
617        }
618
619        public Class<?> getDefaultSqlProviderType() {
620            return defaultSqlProviderType;
621        }
622
623        public void setDefaultSqlProviderType(Class<?> defaultSqlProviderType) {
624            this.defaultSqlProviderType = defaultSqlProviderType;
625        }
626
627        public LocalCacheScope getLocalCacheScope() {
628            return localCacheScope;
629        }
630
631        public void setLocalCacheScope(LocalCacheScope localCacheScope) {
632            this.localCacheScope = localCacheScope;
633        }
634
635        public JdbcType getJdbcTypeForNull() {
636            return jdbcTypeForNull;
637        }
638
639        public void setJdbcTypeForNull(JdbcType jdbcTypeForNull) {
640            this.jdbcTypeForNull = jdbcTypeForNull;
641        }
642
643        public Set<String> getLazyLoadTriggerMethods() {
644            return lazyLoadTriggerMethods;
645        }
646
647        public void setLazyLoadTriggerMethods(Set<String> lazyLoadTriggerMethods) {
648            this.lazyLoadTriggerMethods = lazyLoadTriggerMethods;
649        }
650
651        public Integer getDefaultStatementTimeout() {
652            return defaultStatementTimeout;
653        }
654
655        public void setDefaultStatementTimeout(Integer defaultStatementTimeout) {
656            this.defaultStatementTimeout = defaultStatementTimeout;
657        }
658
659        public Integer getDefaultFetchSize() {
660            return defaultFetchSize;
661        }
662
663        public void setDefaultFetchSize(Integer defaultFetchSize) {
664            this.defaultFetchSize = defaultFetchSize;
665        }
666
667        public ResultSetType getDefaultResultSetType() {
668            return defaultResultSetType;
669        }
670
671        public void setDefaultResultSetType(ResultSetType defaultResultSetType) {
672            this.defaultResultSetType = defaultResultSetType;
673        }
674
675        public ExecutorType getDefaultExecutorType() {
676            return defaultExecutorType;
677        }
678
679        public void setDefaultExecutorType(ExecutorType defaultExecutorType) {
680            this.defaultExecutorType = defaultExecutorType;
681        }
682
683        public AutoMappingBehavior getAutoMappingBehavior() {
684            return autoMappingBehavior;
685        }
686
687        public void setAutoMappingBehavior(AutoMappingBehavior autoMappingBehavior) {
688            this.autoMappingBehavior = autoMappingBehavior;
689        }
690
691        public AutoMappingUnknownColumnBehavior getAutoMappingUnknownColumnBehavior() {
692            return autoMappingUnknownColumnBehavior;
693        }
694
695        public void setAutoMappingUnknownColumnBehavior(AutoMappingUnknownColumnBehavior autoMappingUnknownColumnBehavior) {
696            this.autoMappingUnknownColumnBehavior = autoMappingUnknownColumnBehavior;
697        }
698
699        public Properties getVariables() {
700            return variables;
701        }
702
703        public void setVariables(Properties variables) {
704            this.variables = variables;
705        }
706
707        public Boolean getLazyLoadingEnabled() {
708            return lazyLoadingEnabled;
709        }
710
711        public void setLazyLoadingEnabled(Boolean lazyLoadingEnabled) {
712            this.lazyLoadingEnabled = lazyLoadingEnabled;
713        }
714
715        public Class<?> getConfigurationFactory() {
716            return configurationFactory;
717        }
718
719        public void setConfigurationFactory(Class<?> configurationFactory) {
720            this.configurationFactory = configurationFactory;
721        }
722
723        public Class<? extends TypeHandler> getDefaultEnumTypeHandler() {
724            return defaultEnumTypeHandler;
725        }
726
727        public void setDefaultEnumTypeHandler(Class<? extends TypeHandler> defaultEnumTypeHandler) {
728            this.defaultEnumTypeHandler = defaultEnumTypeHandler;
729        }
730
731        void applyTo(Configuration target) {
732            PropertyMapper mapper = PropertyMapper.get().alwaysApplyingWhenNonNull();
733            mapper.from(getSafeRowBoundsEnabled()).to(target::setSafeRowBoundsEnabled);
734            mapper.from(getSafeResultHandlerEnabled()).to(target::setSafeResultHandlerEnabled);
735            mapper.from(getMapUnderscoreToCamelCase()).to(target::setMapUnderscoreToCamelCase);
736            mapper.from(getAggressiveLazyLoading()).to(target::setAggressiveLazyLoading);
737            mapper.from(getMultipleResultSetsEnabled()).to(target::setMultipleResultSetsEnabled);
738            mapper.from(getUseGeneratedKeys()).to(target::setUseGeneratedKeys);
739            mapper.from(getUseColumnLabel()).to(target::setUseColumnLabel);
740            mapper.from(getCacheEnabled()).to(target::setCacheEnabled);
741            mapper.from(getCallSettersOnNulls()).to(target::setCallSettersOnNulls);
742            mapper.from(getUseActualParamName()).to(target::setUseActualParamName);
743            mapper.from(getReturnInstanceForEmptyRow()).to(target::setReturnInstanceForEmptyRow);
744            mapper.from(getShrinkWhitespacesInSql()).to(target::setShrinkWhitespacesInSql);
745            mapper.from(getNullableOnForEach()).to(target::setNullableOnForEach);
746            mapper.from(getArgNameBasedConstructorAutoMapping()).to(target::setArgNameBasedConstructorAutoMapping);
747            mapper.from(getLazyLoadingEnabled()).to(target::setLazyLoadingEnabled);
748            mapper.from(getLogPrefix()).to(target::setLogPrefix);
749            mapper.from(getLazyLoadTriggerMethods()).to(target::setLazyLoadTriggerMethods);
750            mapper.from(getDefaultStatementTimeout()).to(target::setDefaultStatementTimeout);
751            mapper.from(getDefaultFetchSize()).to(target::setDefaultFetchSize);
752            mapper.from(getLocalCacheScope()).to(target::setLocalCacheScope);
753            mapper.from(getJdbcTypeForNull()).to(target::setJdbcTypeForNull);
754            mapper.from(getDefaultResultSetType()).to(target::setDefaultResultSetType);
755            mapper.from(getDefaultExecutorType()).to(target::setDefaultExecutorType);
756            mapper.from(getAutoMappingBehavior()).to(target::setAutoMappingBehavior);
757            mapper.from(getAutoMappingUnknownColumnBehavior()).to(target::setAutoMappingUnknownColumnBehavior);
758            mapper.from(getVariables()).to(target::setVariables);
759            mapper.from(getLogImpl()).to(target::setLogImpl);
760            mapper.from(getVfsImpl()).to(target::setVfsImpl);
761            mapper.from(getDefaultSqlProviderType()).to(target::setDefaultSqlProviderType);
762            mapper.from(getConfigurationFactory()).to(target::setConfigurationFactory);
763            mapper.from(getDefaultEnumTypeHandler()).to(target::setDefaultEnumTypeHandler);
764        }
765
766    }
767
768    /**
769     * {@link com.mybatisflex.core.FlexGlobalConfig} 配置。
770     *
771     * @author 王帅
772     * @since 2023-06-21
773     */
774    public static class GlobalConfig {
775
776        /**
777         * 启动是否打印 banner 和 版本号。
778         */
779        private boolean printBanner = true;
780
781
782        /**
783         * 全局的 ID 生成策略配置,当 @Id 未配置 或者 配置 KeyType 为 None 时
784         * 使用当前全局配置。
785         */
786        @NestedConfigurationProperty
787        private FlexGlobalConfig.KeyConfig keyConfig;
788
789        /**
790         * 逻辑删除数据存在标记值。
791         */
792        private Object normalValueOfLogicDelete = FlexConsts.LOGIC_DELETE_NORMAL;
793
794        /**
795         * 逻辑删除数据删除标记值。
796         */
797        private Object deletedValueOfLogicDelete = FlexConsts.LOGIC_DELETE_DELETED;
798
799
800        /**
801         * 默认的分页查询时的每页数据量。
802         */
803        private int defaultPageSize = 10;
804
805
806        /**
807         * 默认的 Relation 注解查询深度。
808         */
809        private int defaultRelationQueryDepth = 2;
810
811        /**
812         * 默认的逻辑删除字段。
813         */
814        private String logicDeleteColumn;
815
816        /**
817         * 默认的多租户字段。
818         */
819        private String tenantColumn;
820
821        /**
822         * 默认的乐观锁字段。
823         */
824        private String versionColumn;
825
826        /**
827         * 全局忽略 @Table 中配置的 schema
828         */
829        private boolean ignoreSchema = false;
830
831        public boolean isPrintBanner() {
832            return printBanner;
833        }
834
835        public void setPrintBanner(boolean printBanner) {
836            this.printBanner = printBanner;
837        }
838
839        public FlexGlobalConfig.KeyConfig getKeyConfig() {
840            return keyConfig;
841        }
842
843        public void setKeyConfig(FlexGlobalConfig.KeyConfig keyConfig) {
844            this.keyConfig = keyConfig;
845        }
846
847        public Object getNormalValueOfLogicDelete() {
848            return normalValueOfLogicDelete;
849        }
850
851        public void setNormalValueOfLogicDelete(Object normalValueOfLogicDelete) {
852            this.normalValueOfLogicDelete = normalValueOfLogicDelete;
853        }
854
855        public Object getDeletedValueOfLogicDelete() {
856            return deletedValueOfLogicDelete;
857        }
858
859        public void setDeletedValueOfLogicDelete(Object deletedValueOfLogicDelete) {
860            this.deletedValueOfLogicDelete = deletedValueOfLogicDelete;
861        }
862
863        public int getDefaultPageSize() {
864            return defaultPageSize;
865        }
866
867        public void setDefaultPageSize(int defaultPageSize) {
868            this.defaultPageSize = defaultPageSize;
869        }
870
871        public int getDefaultRelationQueryDepth() {
872            return defaultRelationQueryDepth;
873        }
874
875        public void setDefaultRelationQueryDepth(int defaultRelationQueryDepth) {
876            this.defaultRelationQueryDepth = defaultRelationQueryDepth;
877        }
878
879        public String getLogicDeleteColumn() {
880            return logicDeleteColumn;
881        }
882
883        public void setLogicDeleteColumn(String logicDeleteColumn) {
884            this.logicDeleteColumn = logicDeleteColumn;
885        }
886
887        public String getTenantColumn() {
888            return tenantColumn;
889        }
890
891        public void setTenantColumn(String tenantColumn) {
892            this.tenantColumn = tenantColumn;
893        }
894
895        public String getVersionColumn() {
896            return versionColumn;
897        }
898
899        public void setVersionColumn(String versionColumn) {
900            this.versionColumn = versionColumn;
901        }
902
903        public boolean isIgnoreSchema() {
904            return ignoreSchema;
905        }
906
907        public void setIgnoreSchema(boolean ignoreSchema) {
908            this.ignoreSchema = ignoreSchema;
909        }
910
911        void applyTo(FlexGlobalConfig target) {
912            PropertyMapper mapper = PropertyMapper.get().alwaysApplyingWhenNonNull();
913            mapper.from(isPrintBanner()).to(target::setPrintBanner);
914            mapper.from(getKeyConfig()).to(target::setKeyConfig);
915            mapper.from(getNormalValueOfLogicDelete()).to(target::setNormalValueOfLogicDelete);
916            mapper.from(getDeletedValueOfLogicDelete()).to(target::setDeletedValueOfLogicDelete);
917            mapper.from(getDefaultPageSize()).to(target::setDefaultPageSize);
918            mapper.from(getDefaultRelationQueryDepth()).to(target::setDefaultRelationQueryDepth);
919            mapper.from(getLogicDeleteColumn()).to(target::setLogicDeleteColumn);
920            mapper.from(getVersionColumn()).to(target::setVersionColumn);
921            mapper.from(getTenantColumn()).to(target::setTenantColumn);
922            mapper.from(isIgnoreSchema()).to(target::setIgnoreSchema);
923        }
924
925    }
926
927    /**
928     * MyBatis Flex Admin 配置。
929     *
930     * @author 王帅
931     * @since 2023-07-02
932     */
933    public static class AdminConfig {
934
935        /**
936         * 启用服务。
937         */
938        private boolean enable;
939
940        /**
941         * 连接端点。
942         */
943        private String endpoint;
944
945        /**
946         * 秘密密钥。
947         */
948        private String secretKey;
949
950        public boolean isEnable() {
951            return enable;
952        }
953
954        public void setEnable(boolean enable) {
955            this.enable = enable;
956        }
957
958        public String getEndpoint() {
959            return endpoint;
960        }
961
962        public void setEndpoint(String endpoint) {
963            this.endpoint = endpoint;
964        }
965
966        public String getSecretKey() {
967            return secretKey;
968        }
969
970        public void setSecretKey(String secretKey) {
971            this.secretKey = secretKey;
972        }
973
974    }
975
976    /**
977     * Seata 配置
978     *
979     * @author life
980     */
981    public static class SeataConfig {
982
983        /**
984         * 是否开启
985         */
986        private boolean enable = false;
987
988        /**
989         * 事务模式支持,只支持XA或者AT
990         */
991        private SeataMode seataMode = SeataMode.AT;
992
993        public boolean isEnable() {
994            return enable;
995        }
996
997        public void setEnable(boolean enable) {
998            this.enable = enable;
999        }
1000
1001        public SeataMode getSeataMode() {
1002            return seataMode;
1003        }
1004
1005        public void setSeataMode(SeataMode seataMode) {
1006            this.seataMode = seataMode;
1007        }
1008
1009    }
1010
1011    /**
1012     * @author life
1013     */
1014    public enum SeataMode {
1015
1016        XA,
1017
1018        AT
1019
1020    }
1021
1022}