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