Explorar el Código

适配 Oracle 数据库
1. 适配表名是大写的情况
2. 优化代码生成器的校验逻辑

YunaiV hace 2 años
padre
commit
2bd2313434

+ 2 - 0
yudao-module-infra/yudao-module-infra-api/src/main/java/cn/iocoder/yudao/module/infra/enums/ErrorCodeConstants.java

@@ -40,6 +40,8 @@ public interface ErrorCodeConstants {
     ErrorCode CODEGEN_COLUMN_NOT_EXISTS = new ErrorCode(1003001005, "字段义不存在");
     ErrorCode CODEGEN_SYNC_COLUMNS_NULL = new ErrorCode(1003001006, "同步的字段不存在");
     ErrorCode CODEGEN_SYNC_NONE_CHANGE = new ErrorCode(1003001007, "同步失败,不存在改变");
+    ErrorCode CODEGEN_TABLE_INFO_TABLE_COMMENT_IS_NULL = new ErrorCode(1003001008, "数据库的表注释未填写");
+    ErrorCode CODEGEN_TABLE_INFO_COLUMN_COMMENT_IS_NULL = new ErrorCode(1003001009, "数据库的表字段({})注释未填写");
 
     // ========== 字典类型(测试)1001005000 ==========
     ErrorCode TEST_DEMO_NOT_EXISTS = new ErrorCode(1001005000, "测试示例不存在");

+ 30 - 14
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/codegen/CodegenServiceImpl.java

@@ -1,6 +1,7 @@
 package cn.iocoder.yudao.module.infra.service.codegen;
 
 import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.StrUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
 import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.CodegenCreateListReqVO;
@@ -74,12 +75,7 @@ public class CodegenServiceImpl implements CodegenService {
 
     private Long createCodegen0(Long userId, Long dataSourceConfigId, TableInfo tableInfo) {
         // 校验导入的表和字段非空
-        if (tableInfo == null) {
-            throw exception(CODEGEN_IMPORT_TABLE_NULL);
-        }
-        if (CollUtil.isEmpty(tableInfo.getFields())) {
-            throw exception(CODEGEN_IMPORT_COLUMNS_NULL);
-        }
+        checkTableInfo(tableInfo);
         // 校验是否已经存在
         if (codegenTableMapper.selectByTableNameAndDataSourceConfigId(tableInfo.getName(),
                 dataSourceConfigId) != null) {
@@ -92,12 +88,34 @@ public class CodegenServiceImpl implements CodegenService {
         table.setScene(CodegenSceneEnum.ADMIN.getScene()); // 默认配置下,使用管理后台的模板
         table.setAuthor(userApi.getUser(userId).getNickname());
         codegenTableMapper.insert(table);
+
         // 构建 CodegenColumnDO 数组,插入到 DB 中
         List<CodegenColumnDO> columns = codegenBuilder.buildColumns(table.getId(), tableInfo.getFields());
+        // 如果没有主键,则使用第一个字段作为主键
+        if (!tableInfo.isHavePrimaryKey()) {
+            columns.get(0).setPrimaryKey(true);
+        }
         codegenColumnMapper.insertBatch(columns);
         return table.getId();
     }
 
+    private void checkTableInfo(TableInfo tableInfo) {
+        if (tableInfo == null) {
+            throw exception(CODEGEN_IMPORT_TABLE_NULL);
+        }
+        if (StrUtil.isEmpty(tableInfo.getComment())) {
+            throw exception(CODEGEN_TABLE_INFO_TABLE_COMMENT_IS_NULL);
+        }
+        if (CollUtil.isEmpty(tableInfo.getFields())) {
+            throw exception(CODEGEN_IMPORT_COLUMNS_NULL);
+        }
+        tableInfo.getFields().forEach(field -> {
+            if (StrUtil.isEmpty(field.getComment())) {
+                throw exception(CODEGEN_TABLE_INFO_COLUMN_COMMENT_IS_NULL, field.getName());
+            }
+        });
+    }
+
     @Override
     @Transactional(rollbackFor = Exception.class)
     public void updateCodegen(CodegenUpdateReqVO updateReqVO) {
@@ -129,12 +147,9 @@ public class CodegenServiceImpl implements CodegenService {
     }
 
     private void syncCodegen0(Long tableId, TableInfo tableInfo) {
-        // 校验导入的字段不为空
+        // 校验导入的表和字段非空
+        checkTableInfo(tableInfo);
         List<TableField> tableFields = tableInfo.getFields();
-        if (CollUtil.isEmpty(tableFields)) {
-            throw exception(CODEGEN_SYNC_COLUMNS_NULL);
-        }
-        Set<String> tableFieldNames = CollectionUtils.convertSet(tableFields, TableField::getName);
 
         // 构建 CodegenColumnDO 数组,只同步新增的字段
         List<CodegenColumnDO> codegenColumns = codegenColumnMapper.selectListByTableId(tableId);
@@ -142,6 +157,7 @@ public class CodegenServiceImpl implements CodegenService {
         // 移除已经存在的字段
         tableFields.removeIf(column -> codegenColumnNames.contains(column.getColumnName()));
         // 计算需要删除的字段
+        Set<String> tableFieldNames = CollectionUtils.convertSet(tableFields, TableField::getName);
         Set<Long> deleteColumnIds = codegenColumns.stream().filter(column -> !tableFieldNames.contains(column.getColumnName()))
                 .map(CodegenColumnDO::getId).collect(Collectors.toSet());
         if (CollUtil.isEmpty(tableFields) && CollUtil.isEmpty(deleteColumnIds)) {
@@ -206,9 +222,9 @@ public class CodegenServiceImpl implements CodegenService {
     public List<DatabaseTableRespVO> getDatabaseTableList(Long dataSourceConfigId, String name, String comment) {
         List<TableInfo> tables = databaseTableService.getTableList(dataSourceConfigId, name, comment);
         // 移除置顶前缀的表名 // TODO 未来做成可配置
-        tables.removeIf(table -> table.getName().startsWith("QRTZ_"));
-        tables.removeIf(table -> table.getName().startsWith("ACT_"));
-        tables.removeIf(table -> table.getName().startsWith("FLW_"));
+        tables.removeIf(table -> table.getName().toUpperCase().startsWith("QRTZ_"));
+        tables.removeIf(table -> table.getName().toUpperCase().startsWith("ACT_"));
+        tables.removeIf(table -> table.getName().toUpperCase().startsWith("FLW_"));
         // 移除已经生成的表
         // 移除在 Codegen 中,已经存在的
         Set<String> existsTables = CollectionUtils.convertSet(

+ 11 - 9
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenBuilder.java

@@ -105,15 +105,17 @@ public class CodegenBuilder {
      * @param table 表定义
      */
     private void initTableDefault(CodegenTableDO table) {
-        // 以 system_dept 举例子。moduleName 为 system、businessName 为 dept、className 为 SystemDept
-        // 如果不希望 System 前缀,则可以手动在【代码生成 - 修改生成配置 - 基本信息】,将实体类名称改为 Dept 即可
-        table.setModuleName(subBefore(table.getTableName(), '_', false)); // 第一个 _ 前缀的前面,作为 module 名字
-        table.setBusinessName(toCamelCase(subAfter(table.getTableName(),
-                '_', false))); // 第一步,第一个 _ 前缀的后面,作为 module 名字; 第二步,可能存在多个 _ 的情况,转换成驼峰
-        table.setClassName(upperFirst(toCamelCase( // 驼峰 + 首字母大写
-                subAfter(table.getTableName(), '_', false)))); // 第一个 _ 前缀的前面,作为 class 名字
-        table.setClassComment(subBefore(table.getTableComment(), // 去除结尾的表,作为类描述
-                '表', true));
+        // 以 system_dept 举例子。moduleName 为 system、businessName 为 dept、className 为 Dept
+        // 如果希望以 System 前缀,则可以手动在【代码生成 - 修改生成配置 - 基本信息】,将实体类名称改为 SystemDept 即可
+        String tableName = table.getTableName().toLowerCase();
+        // 第一步,_ 前缀的前面,作为 module 名字;第二步,moduleName 必须小写;
+        table.setModuleName(subBefore(tableName, '_', false).toLowerCase());
+        // 第一步,第一个 _ 前缀的后面,作为 module 名字; 第二步,可能存在多个 _ 的情况,转换成驼峰; 第三步,businessName 必须小写;
+        table.setBusinessName(toCamelCase(subAfter(tableName, '_', false)).toLowerCase());
+        // 驼峰 + 首字母大写;第一步,第一个 _ 前缀的后面,作为 class 名字;第二步,驼峰命名
+        table.setClassName(upperFirst(toCamelCase(subAfter(tableName, '_', false))));
+        // 去除结尾的表,作为类描述
+        table.setClassComment(StrUtil.removeSuffixIgnoreCase(table.getTableComment(), "表"));
         table.setTemplateType(CodegenTemplateTypeEnum.CRUD.getType());
     }
 

+ 2 - 1
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/dal/do.vm

@@ -10,7 +10,8 @@ import ${BaseDOClassName};
  *
  * @author ${table.author}
  */
-@TableName("${table.tableName}")
+@TableName("${table.tableName.toLowerCase()}")
+@KeySequence("${table.tableName.toLowerCase()}_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
 @Data
 @EqualsAndHashCode(callSuper = true)
 @ToString(callSuper = true)

+ 3 - 3
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/sql/h2.vm

@@ -1,5 +1,5 @@
 -- 将该建表 SQL 语句,添加到 yudao-module-${table.moduleName}-biz 模块的 test/resources/sql/create_tables.sql 文件里
-CREATE TABLE IF NOT EXISTS "${table.tableName}" (
+CREATE TABLE IF NOT EXISTS "${table.tableName.toLowerCase()}" (
 #foreach ($column in $columns)
 #if (${column.javaType} == 'Long')
     #set ($dataType='bigint')
@@ -24,11 +24,11 @@ CREATE TABLE IF NOT EXISTS "${table.tableName}" (
     #elseif (${column.columnName} == 'deleted')
     "deleted" bit NOT NULL DEFAULT FALSE,
     #else
-    "${column.columnName}" ${dataType}#if (${column.nullable} == false) NOT NULL#end,
+    "${column.columnName.toLowerCase()}" ${dataType}#if (${column.nullable} == false) NOT NULL#end,
     #end
     #end
 #end
-    PRIMARY KEY ("${primaryColumn.columnName}")
+    PRIMARY KEY ("${primaryColumn.columnName.toLowerCase()}")
 ) COMMENT '${table.tableComment}';
 
 -- 将该删表 SQL 语句,添加到 yudao-module-${table.moduleName}-biz 模块的 test/resources/sql/clean.sql 文件里

+ 6 - 6
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/sql/sql.vm

@@ -1,7 +1,7 @@
 -- 菜单 SQL
-INSERT INTO `system_menu`(
-    `name`, `permission`, `menu_type`, `sort`, `parent_id`,
-    `path`, `icon`, `component`, `status`
+INSERT INTO system_menu(
+    name, permission, type, sort, parent_id,
+    path, icon, component, status
 )
 VALUES (
     '${table.classComment}管理', '', 2, 0, ${table.parentMenuId},
@@ -16,9 +16,9 @@ SELECT @parentId := LAST_INSERT_ID();
 #set ($functionOps = ['query', 'create', 'update', 'delete', 'export'])
 #foreach ($functionName in $functionNames)
 #set ($index = $foreach.count - 1)
-INSERT INTO `system_menu`(
-    `name`, `permission`, `menu_type`, `sort`, `parent_id`,
-    `path`, `icon`, `component`, `status`
+INSERT INTO system_menu(
+    name, permission, type, sort, parent_id,
+    path, icon, component, status
 )
 VALUES (
     '${table.classComment}${functionName}', '${permissionPrefix}:${functionOps.get($index)}', 3, $foreach.count, @parentId,