diff --git a/yudao-framework/yudao-spring-boot-starter-mybatis/pom.xml b/yudao-framework/yudao-spring-boot-starter-mybatis/pom.xml
index bb394b0f3..2b5915e32 100644
--- a/yudao-framework/yudao-spring-boot-starter-mybatis/pom.xml
+++ b/yudao-framework/yudao-spring-boot-starter-mybatis/pom.xml
@@ -42,6 +42,10 @@
com.oracle.database.jdbc
ojdbc8
+
+ org.postgresql
+ postgresql
+
com.alibaba
diff --git a/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/config/IdTypeEnvironmentPostProcessor.java b/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/config/IdTypeEnvironmentPostProcessor.java
new file mode 100644
index 000000000..532c02030
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/config/IdTypeEnvironmentPostProcessor.java
@@ -0,0 +1,73 @@
+package cn.iocoder.yudao.framework.mybatis.config;
+
+import cn.hutool.core.util.StrUtil;
+import cn.iocoder.yudao.framework.common.util.collection.SetUtils;
+import cn.iocoder.yudao.framework.mybatis.core.util.JdbcUtils;
+import com.baomidou.mybatisplus.annotation.DbType;
+import com.baomidou.mybatisplus.annotation.IdType;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.env.EnvironmentPostProcessor;
+import org.springframework.core.env.ConfigurableEnvironment;
+
+import java.util.Set;
+
+/**
+ * 当 IdType 为 {@link IdType#NONE} 时,根据 PRIMARY 数据源所使用的数据库,自动设置
+ *
+ * @author 芋道源码
+ */
+@Slf4j
+public class IdTypeEnvironmentPostProcessor implements EnvironmentPostProcessor {
+
+ private static final String ID_TYPE_KEY = "mybatis-plus.global-config.db-config.id-type";
+
+ private static final String DATASOURCE_DYNAMIC_KEY = "spring.datasource.dynamic";
+
+ private static final Set INPUT_ID_TYPES = SetUtils.asSet(DbType.ORACLE, DbType.ORACLE_12C,
+ DbType.POSTGRE_SQL, DbType.KINGBASE_ES, DbType.DB2, DbType.H2);
+
+ @Override
+ public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
+ // 如果非 NONE,则不进行处理
+ IdType idType = getIdType(environment);
+ if (idType != IdType.NONE) {
+ return;
+ }
+ // 如果获取不到 DbType,则不进行处理
+ DbType dbType = getDbType(environment);
+ if (dbType == null) {
+ return;
+ }
+
+ // 情况一,用户输入 ID,适合 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库
+ if (INPUT_ID_TYPES.contains(dbType)) {
+ setIdType(environment, IdType.INPUT);
+ return;
+ }
+ // 情况二,自增 ID,适合 MySQL 等直接自增的数据库
+ setIdType(environment, IdType.AUTO);
+ }
+
+ public IdType getIdType(ConfigurableEnvironment environment) {
+ return environment.getProperty(ID_TYPE_KEY, IdType.class);
+ }
+
+ public void setIdType(ConfigurableEnvironment environment, IdType idType) {
+ environment.getSystemProperties().put(ID_TYPE_KEY, idType);
+ log.info("[setIdType][修改 MyBatis Plus 的 idType 为({})]", idType);
+ }
+
+ public static DbType getDbType(ConfigurableEnvironment environment) {
+ String primary = environment.getProperty(DATASOURCE_DYNAMIC_KEY + "." + "primary");
+ if (StrUtil.isEmpty(primary)) {
+ return null;
+ }
+ String url = environment.getProperty(DATASOURCE_DYNAMIC_KEY + ".datasource." + primary + ".url");
+ if (StrUtil.isEmpty(url)) {
+ return null;
+ }
+ return JdbcUtils.getDbType(url);
+ }
+
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/config/YudaoMybatisAutoConfiguration.java b/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/config/YudaoMybatisAutoConfiguration.java
index f8eeeef87..d49ac8308 100644
--- a/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/config/YudaoMybatisAutoConfiguration.java
+++ b/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/config/YudaoMybatisAutoConfiguration.java
@@ -1,13 +1,22 @@
package cn.iocoder.yudao.framework.mybatis.config;
+import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.mybatis.core.handler.DefaultDBFieldHandler;
+import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
+import com.baomidou.mybatisplus.core.incrementer.IKeyGenerator;
+import com.baomidou.mybatisplus.extension.incrementer.H2KeyGenerator;
+import com.baomidou.mybatisplus.extension.incrementer.KingbaseKeyGenerator;
+import com.baomidou.mybatisplus.extension.incrementer.OracleKeyGenerator;
+import com.baomidou.mybatisplus.extension.incrementer.PostgreKeyGenerator;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.apache.ibatis.annotations.Mapper;
import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
+import org.springframework.core.env.ConfigurableEnvironment;
/**
* MyBaits 配置类
@@ -31,4 +40,25 @@ public class YudaoMybatisAutoConfiguration {
return new DefaultDBFieldHandler(); // 自动填充参数类
}
+ @Bean
+ @ConditionalOnProperty(prefix = "mybatis-plus.global-config.db-config", name = "id-type", havingValue = "INPUT")
+ public IKeyGenerator keyGenerator(ConfigurableEnvironment environment) {
+ DbType dbType = IdTypeEnvironmentPostProcessor.getDbType(environment);
+ if (dbType != null) {
+ switch (dbType) {
+ case POSTGRE_SQL:
+ return new PostgreKeyGenerator();
+ case ORACLE:
+ case ORACLE_12C:
+ return new OracleKeyGenerator();
+ case H2:
+ return new H2KeyGenerator();
+ case KINGBASE_ES:
+ return new KingbaseKeyGenerator();
+ }
+ }
+ // 找不到合适的 IKeyGenerator 实现类
+ throw new IllegalArgumentException(StrUtil.format("DbType{} 找不到合适的 IKeyGenerator 实现类", dbType));
+ }
+
}
diff --git a/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/util/JdbcUtils.java b/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/util/JdbcUtils.java
index afff67d2c..e9dc10f78 100644
--- a/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/util/JdbcUtils.java
+++ b/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/util/JdbcUtils.java
@@ -1,5 +1,7 @@
package cn.iocoder.yudao.framework.mybatis.core.util;
+import com.baomidou.mybatisplus.annotation.DbType;
+
import java.sql.Connection;
import java.sql.DriverManager;
@@ -26,4 +28,15 @@ public class JdbcUtils {
}
}
+ /**
+ * 获得 URL 对应的 DB 类型
+ *
+ * @param url URL
+ * @return DB 类型
+ */
+ public static DbType getDbType(String url) {
+ String name = com.alibaba.druid.util.JdbcUtils.getDbType(url, null);
+ return DbType.getDbType(name);
+ }
+
}
diff --git a/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/resources/META-INF/spring.factories b/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/resources/META-INF/spring.factories
index efd17648e..96e3d8bcd 100644
--- a/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/resources/META-INF/spring.factories
+++ b/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/resources/META-INF/spring.factories
@@ -1,3 +1,5 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
cn.iocoder.yudao.framework.datasource.config.YudaoDataSourceAutoConfiguration,\
cn.iocoder.yudao.framework.mybatis.config.YudaoMybatisAutoConfiguration
+org.springframework.boot.env.EnvironmentPostProcessor=\
+ cn.iocoder.yudao.framework.mybatis.config.IdTypeEnvironmentPostProcessor
diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/errorcode/core/generator/ErrorCodeAutoGeneratorImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/errorcode/core/generator/ErrorCodeAutoGeneratorImpl.java
index 0551e4732..db75aaa7c 100644
--- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/errorcode/core/generator/ErrorCodeAutoGeneratorImpl.java
+++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/errorcode/core/generator/ErrorCodeAutoGeneratorImpl.java
@@ -1,6 +1,7 @@
package cn.iocoder.yudao.module.system.framework.errorcode.core.generator;
import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.exceptions.ExceptionUtil;
import cn.hutool.core.util.ClassUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
@@ -57,7 +58,7 @@ public class ErrorCodeAutoGeneratorImpl implements ErrorCodeAutoGenerator {
*
* @return 错误码数组
*/
- private List parseErrorCode() {
+ private List parseErrorCode() {
// 校验 errorCodeConstantsClass 参数
if (CollUtil.isEmpty(constantsClassList)) {
log.info("[execute][未配置 yudao.error-code.constants-class-list 配置项,不进行自动写入到 system 服务中]");
@@ -67,10 +68,15 @@ public class ErrorCodeAutoGeneratorImpl implements ErrorCodeAutoGenerator {
// 解析错误码
List autoGenerateDTOs = new ArrayList<>();
constantsClassList.forEach(constantsClass -> {
- // 解析错误码枚举类
- Class> errorCodeConstantsClazz = ClassUtil.loadClass(constantsClass);
- // 解析错误码
- autoGenerateDTOs.addAll(parseErrorCode(errorCodeConstantsClazz));
+ try {
+ // 解析错误码枚举类
+ Class> errorCodeConstantsClazz = ClassUtil.loadClass(constantsClass);
+ // 解析错误码
+ autoGenerateDTOs.addAll(parseErrorCode(errorCodeConstantsClazz));
+ } catch (Exception ex) {
+ log.warn("[parseErrorCode][constantsClass({}) 加载失败({})]", constantsClass,
+ ExceptionUtil.getRootCauseMessage(ex));
+ }
});
return autoGenerateDTOs;
}
diff --git a/yudao-server/pom.xml b/yudao-server/pom.xml
index 06c5750cf..4225619ec 100644
--- a/yudao-server/pom.xml
+++ b/yudao-server/pom.xml
@@ -43,11 +43,11 @@
${revision}
-
- cn.iocoder.boot
- yudao-module-bpm-biz-flowable
- ${revision}
-
+
+
+
+
+
diff --git a/yudao-server/src/main/resources/application-dev.yaml b/yudao-server/src/main/resources/application-dev.yaml
index 0c11d2f1b..f73a9c680 100644
--- a/yudao-server/src/main/resources/application-dev.yaml
+++ b/yudao-server/src/main/resources/application-dev.yaml
@@ -36,7 +36,7 @@ spring:
time-between-eviction-runs-millis: 60000 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位:毫秒
min-evictable-idle-time-millis: 300000 # 配置一个连接在池中最小生存的时间,单位:毫秒
max-evictable-idle-time-millis: 900000 # 配置一个连接在池中最大生存的时间,单位:毫秒
- validation-query: SELECT 1 FROM DUAL # 配置检测连接是否有效
+ validation-query: SELECT 1 # 配置检测连接是否有效
test-while-idle: true
test-on-borrow: false
test-on-return: false
diff --git a/yudao-server/src/main/resources/application-local.yaml b/yudao-server/src/main/resources/application-local.yaml
index d8ce9deee..a0ede5ff9 100644
--- a/yudao-server/src/main/resources/application-local.yaml
+++ b/yudao-server/src/main/resources/application-local.yaml
@@ -36,7 +36,7 @@ spring:
time-between-eviction-runs-millis: 60000 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位:毫秒
min-evictable-idle-time-millis: 300000 # 配置一个连接在池中最小生存的时间,单位:毫秒
max-evictable-idle-time-millis: 900000 # 配置一个连接在池中最大生存的时间,单位:毫秒
- validation-query: SELECT 1 FROM DUAL # 配置检测连接是否有效
+ validation-query: SELECT 1 # 配置检测连接是否有效
test-while-idle: true
test-on-borrow: false
test-on-return: false
@@ -44,14 +44,14 @@ spring:
datasource:
master:
name: ruoyi-vue-pro
- url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.master.name}?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT
- driver-class-name: com.mysql.jdbc.Driver
+# url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.master.name}?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT # MySQL 连接的示例
+ url: jdbc:postgresql://127.0.0.1:5432/${spring.datasource.dynamic.datasource.slave.name} # PostgreSQL 连接的示例
username: root
password: 123456
slave: # 模拟从库,可根据自己需要修改
name: ruoyi-vue-pro
- url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.slave.name}?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT
- driver-class-name: com.mysql.jdbc.Driver
+# url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.slave.name}?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT # MySQL 连接的示例
+ url: jdbc:postgresql://127.0.0.1:5432/${spring.datasource.dynamic.datasource.slave.name} # PostgreSQL 连接的示例
username: root
password: 123456
diff --git a/yudao-server/src/main/resources/application.yaml b/yudao-server/src/main/resources/application.yaml
index 247af4d03..6e28775ee 100644
--- a/yudao-server/src/main/resources/application.yaml
+++ b/yudao-server/src/main/resources/application.yaml
@@ -54,7 +54,10 @@ mybatis-plus:
map-underscore-to-camel-case: true # 虽然默认为 true ,但是还是显示去指定下。
global-config:
db-config:
- id-type: AUTO # 自增 ID
+ id-type: NONE # “智能”模式,基于 IdTypeEnvironmentPostProcessor + 数据源的类型,自动适配成 AUTO、INPUT 模式。
+# id-type: AUTO # 自增 ID,适合 MySQL 等直接自增的数据库
+# id-type: INPUT # 用户输入 ID,适合 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库
+# id-type: ASSIGN_ID # 分配 ID,默认使用雪花算法。注意,Oracle、PostgreSQL、Kingbase、DB2、H2 数据库时,需要去除实体类上的 @KeySequence 注解
logic-delete-value: 1 # 逻辑已删除值(默认为 1)
logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
type-aliases-package: ${yudao.info.base-package}.module.*.dal.dataobject