Commit b34e2691f82023e0b1b43ec8014f715fb21a2f73
1 parent
f1069aa3
支持主流数据库的代码生成
Showing
30 changed files
with
270 additions
and
1018 deletions
yudao-dependencies/pom.xml
| ... | ... | @@ -25,6 +25,7 @@ |
| 25 | 25 | <mysql.version>5.1.46</mysql.version> |
| 26 | 26 | <druid.version>1.2.8</druid.version> |
| 27 | 27 | <mybatis-plus.version>3.4.3.4</mybatis-plus.version> |
| 28 | + <mybatis-plus-generator.version>3.5.2</mybatis-plus-generator.version> | |
| 28 | 29 | <dynamic-datasource.version>3.5.0</dynamic-datasource.version> |
| 29 | 30 | <redisson.version>3.17.0</redisson.version> |
| 30 | 31 | <!-- Config 配置中心相关 --> |
| ... | ... | @@ -195,6 +196,11 @@ |
| 195 | 196 | </dependency> |
| 196 | 197 | <dependency> |
| 197 | 198 | <groupId>com.baomidou</groupId> |
| 199 | + <artifactId>mybatis-plus-generator</artifactId> <!-- 代码生成器,使用它解析表结构 --> | |
| 200 | + <version>${mybatis-plus-generator.version}</version> | |
| 201 | + </dependency> | |
| 202 | + <dependency> | |
| 203 | + <groupId>com.baomidou</groupId> | |
| 198 | 204 | <artifactId>dynamic-datasource-spring-boot-starter</artifactId> <!-- 多数据源 --> |
| 199 | 205 | <version>${dynamic-datasource.version}</version> |
| 200 | 206 | </dependency> | ... | ... |
yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/util/JdbcUtils.java
| 1 | 1 | package cn.iocoder.yudao.framework.mybatis.core.util; |
| 2 | 2 | |
| 3 | -import com.baomidou.mybatisplus.annotation.DbType; | |
| 4 | -import lombok.SneakyThrows; | |
| 5 | -import org.springframework.dao.DataAccessException; | |
| 6 | -import org.springframework.jdbc.core.JdbcTemplate; | |
| 7 | -import org.springframework.jdbc.core.RowCallbackHandler; | |
| 8 | -import org.springframework.jdbc.core.RowMapper; | |
| 9 | - | |
| 10 | -import java.sql.*; | |
| 11 | -import java.util.ArrayList; | |
| 12 | -import java.util.List; | |
| 3 | +import java.sql.Connection; | |
| 4 | +import java.sql.DriverManager; | |
| 13 | 5 | |
| 14 | 6 | /** |
| 15 | 7 | * JDBC 工具类 |
| ... | ... | @@ -34,52 +26,4 @@ public class JdbcUtils { |
| 34 | 26 | } |
| 35 | 27 | } |
| 36 | 28 | |
| 37 | - /** | |
| 38 | - * 获得连接 | |
| 39 | - * | |
| 40 | - * @param url 数据源连接 | |
| 41 | - * @param username 账号 | |
| 42 | - * @param password 密码 | |
| 43 | - * @return 是否正确 | |
| 44 | - */ | |
| 45 | - @SneakyThrows | |
| 46 | - public static Connection getConnection(String url, String username, String password) { | |
| 47 | - return DriverManager.getConnection(url, username, password); | |
| 48 | - } | |
| 49 | - | |
| 50 | - /** | |
| 51 | - * 执行指定 SQL,返回查询列表 | |
| 52 | - * | |
| 53 | - * 参考 {@link JdbcTemplate#query(String, RowMapper)} 实现,主要考虑 JdbcTemplate 不支持使用指定 Connection 查询 | |
| 54 | - * | |
| 55 | - * @param connection 数据库连接 | |
| 56 | - * @param sql SQL | |
| 57 | - * @param handler 行处理器 | |
| 58 | - * @return 列表 | |
| 59 | - */ | |
| 60 | - @SneakyThrows | |
| 61 | - public static <T> List<T> query(Connection connection, String sql, RowMapper<T> handler) { | |
| 62 | - try (PreparedStatement ps = connection.prepareStatement(sql); | |
| 63 | - ResultSet rs = ps.executeQuery()) { | |
| 64 | - // 处理结果 | |
| 65 | - List<T> result = new ArrayList<>(); | |
| 66 | - int rowNum = 0; | |
| 67 | - while (rs.next()) { | |
| 68 | - result.add(handler.mapRow(rs, rowNum++)); | |
| 69 | - } | |
| 70 | - return result; | |
| 71 | - } | |
| 72 | - } | |
| 73 | - | |
| 74 | - /** | |
| 75 | - * 获得 URL 对应的 DB 类型 | |
| 76 | - * | |
| 77 | - * @param url URL | |
| 78 | - * @return DB 类型 | |
| 79 | - */ | |
| 80 | - public static DbType getDbType(String url) { | |
| 81 | - String name = com.alibaba.druid.util.JdbcUtils.getDbType(url, null); | |
| 82 | - return DbType.getDbType(name); | |
| 83 | - } | |
| 84 | - | |
| 85 | 29 | } | ... | ... |
yudao-module-infra/yudao-module-infra-biz/pom.xml
| ... | ... | @@ -47,6 +47,10 @@ |
| 47 | 47 | <groupId>cn.iocoder.boot</groupId> |
| 48 | 48 | <artifactId>yudao-spring-boot-starter-mybatis</artifactId> |
| 49 | 49 | </dependency> |
| 50 | + <dependency> | |
| 51 | + <groupId>com.baomidou</groupId> | |
| 52 | + <artifactId>mybatis-plus-generator</artifactId> <!-- 代码生成器,使用它解析表结构 --> | |
| 53 | + </dependency> | |
| 50 | 54 | |
| 51 | 55 | <dependency> |
| 52 | 56 | <groupId>cn.iocoder.boot</groupId> | ... | ... |
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/CodegenController.java
| ... | ... | @@ -4,19 +4,18 @@ import cn.hutool.core.io.IoUtil; |
| 4 | 4 | import cn.hutool.core.util.ZipUtil; |
| 5 | 5 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 6 | 6 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 7 | +import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils; | |
| 8 | +import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.CodegenCreateListReqVO; | |
| 7 | 9 | import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.CodegenDetailRespVO; |
| 8 | 10 | import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.CodegenPreviewRespVO; |
| 9 | 11 | import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.CodegenUpdateReqVO; |
| 10 | 12 | import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.table.CodegenTablePageReqVO; |
| 11 | 13 | import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.table.CodegenTableRespVO; |
| 12 | -import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.table.SchemaTableRespVO; | |
| 14 | +import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.table.DatabaseTableRespVO; | |
| 13 | 15 | import cn.iocoder.yudao.module.infra.convert.codegen.CodegenConvert; |
| 14 | 16 | import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenColumnDO; |
| 15 | 17 | import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenTableDO; |
| 16 | -import cn.iocoder.yudao.module.infra.dal.dataobject.db.DatabaseTableDO; | |
| 17 | 18 | import cn.iocoder.yudao.module.infra.service.codegen.CodegenService; |
| 18 | -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | |
| 19 | -import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils; | |
| 20 | 19 | import io.swagger.annotations.Api; |
| 21 | 20 | import io.swagger.annotations.ApiImplicitParam; |
| 22 | 21 | import io.swagger.annotations.ApiImplicitParams; |
| ... | ... | @@ -33,7 +32,6 @@ import java.io.ByteArrayOutputStream; |
| 33 | 32 | import java.io.IOException; |
| 34 | 33 | import java.util.List; |
| 35 | 34 | import java.util.Map; |
| 36 | -import java.util.Set; | |
| 37 | 35 | |
| 38 | 36 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| 39 | 37 | import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; |
| ... | ... | @@ -51,20 +49,15 @@ public class CodegenController { |
| 51 | 49 | @ApiOperation(value = "获得数据库自带的表定义列表", notes = "会过滤掉已经导入 Codegen 的表") |
| 52 | 50 | @ApiImplicitParams({ |
| 53 | 51 | @ApiImplicitParam(name = "dataSourceConfigId", value = "数据源配置的编号", required = true, example = "1", dataTypeClass = Long.class), |
| 54 | - @ApiImplicitParam(name = "tableName", value = "表名,模糊匹配", example = "yudao", dataTypeClass = String.class), | |
| 55 | - @ApiImplicitParam(name = "tableComment", value = "描述,模糊匹配", example = "芋道", dataTypeClass = String.class) | |
| 52 | + @ApiImplicitParam(name = "name", value = "表名,模糊匹配", example = "yudao", dataTypeClass = String.class), | |
| 53 | + @ApiImplicitParam(name = "comment", value = "描述,模糊匹配", example = "芋道", dataTypeClass = String.class) | |
| 56 | 54 | }) |
| 57 | 55 | @PreAuthorize("@ss.hasPermission('infra:codegen:query')") |
| 58 | - public CommonResult<List<SchemaTableRespVO>> getSchemaTableList( | |
| 56 | + public CommonResult<List<DatabaseTableRespVO>> getDatabaseTableList( | |
| 59 | 57 | @RequestParam(value = "dataSourceConfigId") Long dataSourceConfigId, |
| 60 | - @RequestParam(value = "tableName", required = false) String tableName, | |
| 61 | - @RequestParam(value = "tableComment", required = false) String tableComment) { | |
| 62 | - // 获得数据库自带的表定义列表 | |
| 63 | - List<DatabaseTableDO> schemaTables = codegenService.getSchemaTableList(dataSourceConfigId, tableName, tableComment); | |
| 64 | - // 移除在 Codegen 中,已经存在的 | |
| 65 | - Set<String> existsTables = CollectionUtils.convertSet(codegenService.getCodeGenTableList(), CodegenTableDO::getTableName); | |
| 66 | - schemaTables.removeIf(table -> existsTables.contains(table.getTableName())); | |
| 67 | - return success(CodegenConvert.INSTANCE.convertList04(schemaTables)); | |
| 58 | + @RequestParam(value = "name", required = false) String name, | |
| 59 | + @RequestParam(value = "comment", required = false) String comment) { | |
| 60 | + return success(codegenService.getDatabaseTableList(dataSourceConfigId, name, comment)); | |
| 68 | 61 | } |
| 69 | 62 | |
| 70 | 63 | @GetMapping("/table/page") |
| ... | ... | @@ -87,19 +80,10 @@ public class CodegenController { |
| 87 | 80 | } |
| 88 | 81 | |
| 89 | 82 | @ApiOperation("基于数据库的表结构,创建代码生成器的表和字段定义") |
| 90 | - @ApiImplicitParam(name = "tableNames", value = "表名数组", required = true, example = "sys_user", dataTypeClass = List.class) | |
| 91 | - @PostMapping("/create-list-from-db") | |
| 92 | - @PreAuthorize("@ss.hasPermission('infra:codegen:create')") | |
| 93 | - public CommonResult<List<Long>> createCodegenListFromDB(@RequestParam("tableNames") List<String> tableNames) { | |
| 94 | - return success(codegenService.createCodegenListFromDB(getLoginUserId(), tableNames)); | |
| 95 | - } | |
| 96 | - | |
| 97 | - @ApiOperation("基于 SQL 建表语句,创建代码生成器的表和字段定义") | |
| 98 | - @ApiImplicitParam(name = "sql", value = "SQL 建表语句", required = true, example = "sql", dataTypeClass = String.class) | |
| 99 | - @PostMapping("/create-list-from-sql") | |
| 83 | + @PostMapping("/create-list") | |
| 100 | 84 | @PreAuthorize("@ss.hasPermission('infra:codegen:create')") |
| 101 | - public CommonResult<Long> createCodegenListFromSQL(@RequestParam("sql") String sql) { | |
| 102 | - return success(codegenService.createCodegenListFromSQL(getLoginUserId(), sql)); | |
| 85 | + public CommonResult<List<Long>> createCodegenList(@Valid @RequestBody CodegenCreateListReqVO reqVO) { | |
| 86 | + return success(codegenService.createCodegenList(getLoginUserId(), reqVO)); | |
| 103 | 87 | } |
| 104 | 88 | |
| 105 | 89 | @ApiOperation("更新数据库的表和字段定义") |
| ... | ... | @@ -119,19 +103,6 @@ public class CodegenController { |
| 119 | 103 | return success(true); |
| 120 | 104 | } |
| 121 | 105 | |
| 122 | - @ApiOperation("基于 SQL 建表语句,同步数据库的表和字段定义") | |
| 123 | - @PutMapping("/sync-from-sql") | |
| 124 | - @ApiImplicitParams({ | |
| 125 | - @ApiImplicitParam(name = "tableId", value = "表编号", required = true, example = "1024", dataTypeClass = Long.class), | |
| 126 | - @ApiImplicitParam(name = "sql", value = "SQL 建表语句", required = true, example = "sql", dataTypeClass = String.class) | |
| 127 | - }) | |
| 128 | - @PreAuthorize("@ss.hasPermission('infra:codegen:update')") | |
| 129 | - public CommonResult<Boolean> syncCodegenFromSQL(@RequestParam("tableId") Long tableId, | |
| 130 | - @RequestParam("sql") String sql) { | |
| 131 | - codegenService.syncCodegenFromSQL(tableId, sql); | |
| 132 | - return success(true); | |
| 133 | - } | |
| 134 | - | |
| 135 | 106 | @ApiOperation("删除数据库的表和字段定义") |
| 136 | 107 | @DeleteMapping("/delete") |
| 137 | 108 | @ApiImplicitParam(name = "tableId", value = "表编号", required = true, example = "1024", dataTypeClass = Long.class) | ... | ... |
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/CodegenCreateListReqVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.infra.controller.admin.codegen.vo; | |
| 2 | + | |
| 3 | +import io.swagger.annotations.ApiModel; | |
| 4 | +import io.swagger.annotations.ApiModelProperty; | |
| 5 | +import lombok.Data; | |
| 6 | + | |
| 7 | +import javax.validation.constraints.NotNull; | |
| 8 | +import java.util.List; | |
| 9 | + | |
| 10 | +@ApiModel("管理后台 - 基于数据库的表结构,创建代码生成器的表和字段定义 Request VO") | |
| 11 | +@Data | |
| 12 | +public class CodegenCreateListReqVO { | |
| 13 | + | |
| 14 | + @ApiModelProperty(value = "数据源配置的编号", required = true, example = "1") | |
| 15 | + @NotNull(message = "数据源配置的编号不能为空") | |
| 16 | + private Long dataSourceConfigId; | |
| 17 | + | |
| 18 | + @ApiModelProperty(value = "表名数组", required = true, example = "[1, 2, 3]") | |
| 19 | + @NotNull(message = "表名数组不能为空") | |
| 20 | + private List<String> tableNames; | |
| 21 | + | |
| 22 | +} | ... | ... |
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/table/CodegenTableBaseVO.java
| ... | ... | @@ -12,10 +12,6 @@ import javax.validation.constraints.NotNull; |
| 12 | 12 | @Data |
| 13 | 13 | public class CodegenTableBaseVO { |
| 14 | 14 | |
| 15 | - @ApiModelProperty(value = "导入类型", required = true, example = "1", notes = "参见 CodegenImportTypeEnum 枚举") | |
| 16 | - @NotNull(message = "导入类型不能为空") | |
| 17 | - private Integer importType; | |
| 18 | - | |
| 19 | 15 | @ApiModelProperty(value = "生成场景", required = true, example = "1", notes = "参见 CodegenSceneEnum 枚举") |
| 20 | 16 | @NotNull(message = "导入类型不能为空") |
| 21 | 17 | private Integer scene; | ... | ... |
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/table/CodegenTableRespVO.java
| ... | ... | @@ -17,6 +17,9 @@ public class CodegenTableRespVO extends CodegenTableBaseVO { |
| 17 | 17 | @ApiModelProperty(value = "编号", required = true, example = "1") |
| 18 | 18 | private Long id; |
| 19 | 19 | |
| 20 | + @ApiModelProperty(value = "主键编号", required = true, example = "1024") | |
| 21 | + private Integer dataSourceConfigId; | |
| 22 | + | |
| 20 | 23 | @ApiModelProperty(value = "创建时间", required = true) |
| 21 | 24 | private Date createTime; |
| 22 | 25 | ... | ... |
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/table/SchemaTableRespVO.java renamed to yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/table/DatabaseTableRespVO.java
| ... | ... | @@ -4,22 +4,14 @@ import io.swagger.annotations.ApiModel; |
| 4 | 4 | import io.swagger.annotations.ApiModelProperty; |
| 5 | 5 | import lombok.Data; |
| 6 | 6 | |
| 7 | -import java.util.Date; | |
| 8 | - | |
| 9 | -@ApiModel("管理后台 - 数据字典的表定义 Response VO") | |
| 7 | +@ApiModel("管理后台 - 数据库的表定义 Response VO") | |
| 10 | 8 | @Data |
| 11 | -public class SchemaTableRespVO { | |
| 12 | - | |
| 13 | - @ApiModelProperty(value = "数据库", required = true, example = "yudao") | |
| 14 | - private String tableSchema; | |
| 9 | +public class DatabaseTableRespVO { | |
| 15 | 10 | |
| 16 | 11 | @ApiModelProperty(value = "表名称", required = true, example = "yuanma") |
| 17 | - private String tableName; | |
| 12 | + private String name; | |
| 18 | 13 | |
| 19 | 14 | @ApiModelProperty(value = "表描述", required = true, example = "芋道源码") |
| 20 | - private String tableComment; | |
| 21 | - | |
| 22 | - @ApiModelProperty(value = "创建时间", required = true) | |
| 23 | - private Date createTime; | |
| 15 | + private String comment; | |
| 24 | 16 | |
| 25 | 17 | } | ... | ... |
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/convert/codegen/CodegenConvert.java
| ... | ... | @@ -6,12 +6,14 @@ import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.CodegenPreviewR |
| 6 | 6 | import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.CodegenUpdateReqVO; |
| 7 | 7 | import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.column.CodegenColumnRespVO; |
| 8 | 8 | import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.table.CodegenTableRespVO; |
| 9 | -import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.table.SchemaTableRespVO; | |
| 9 | +import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.table.DatabaseTableRespVO; | |
| 10 | 10 | import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenColumnDO; |
| 11 | 11 | import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenTableDO; |
| 12 | -import cn.iocoder.yudao.module.infra.dal.dataobject.db.DatabaseColumnDO; | |
| 13 | -import cn.iocoder.yudao.module.infra.dal.dataobject.db.DatabaseTableDO; | |
| 12 | +import com.baomidou.mybatisplus.generator.config.po.TableField; | |
| 13 | +import com.baomidou.mybatisplus.generator.config.po.TableInfo; | |
| 14 | 14 | import org.mapstruct.Mapper; |
| 15 | +import org.mapstruct.Mapping; | |
| 16 | +import org.mapstruct.Mappings; | |
| 15 | 17 | import org.mapstruct.factory.Mappers; |
| 16 | 18 | |
| 17 | 19 | import java.util.List; |
| ... | ... | @@ -23,13 +25,27 @@ public interface CodegenConvert { |
| 23 | 25 | |
| 24 | 26 | CodegenConvert INSTANCE = Mappers.getMapper(CodegenConvert.class); |
| 25 | 27 | |
| 26 | - // ========== InformationSchemaTableDO 和 InformationSchemaColumnDO 相关 ========== | |
| 28 | + // ========== TableInfo 相关 ========== | |
| 27 | 29 | |
| 28 | - CodegenTableDO convert(DatabaseTableDO bean); | |
| 30 | + @Mappings({ | |
| 31 | + @Mapping(source = "name", target = "tableName"), | |
| 32 | + @Mapping(source = "comment", target = "tableComment"), | |
| 33 | + }) | |
| 34 | + CodegenTableDO convert(TableInfo bean); | |
| 29 | 35 | |
| 30 | - List<CodegenColumnDO> convertList(List<DatabaseColumnDO> list); | |
| 36 | + List<CodegenColumnDO> convertList(List<TableField> list); | |
| 31 | 37 | |
| 32 | - CodegenTableRespVO convert(DatabaseColumnDO bean); | |
| 38 | + @Mappings({ | |
| 39 | + @Mapping(source = "name", target = "columnName"), | |
| 40 | + @Mapping(source = "type", target = "dataType"), | |
| 41 | + @Mapping(source = "comment", target = "columnComment"), | |
| 42 | + @Mapping(source = "metaInfo.nullable", target = "nullable"), | |
| 43 | + @Mapping(source = "keyFlag", target = "primaryKey"), | |
| 44 | + @Mapping(source = "keyIdentityFlag", target = "autoIncrement"), | |
| 45 | + @Mapping(source = "columnType.type", target = "javaType"), | |
| 46 | + @Mapping(source = "propertyName", target = "javaField"), | |
| 47 | + }) | |
| 48 | + CodegenColumnDO convert(TableField bean); | |
| 33 | 49 | |
| 34 | 50 | // ========== CodegenTableDO 相关 ========== |
| 35 | 51 | |
| ... | ... | @@ -47,7 +63,7 @@ public interface CodegenConvert { |
| 47 | 63 | |
| 48 | 64 | List<CodegenColumnDO> convertList03(List<CodegenUpdateReqVO.Column> columns); |
| 49 | 65 | |
| 50 | - List<SchemaTableRespVO> convertList04(List<DatabaseTableDO> list); | |
| 66 | + List<DatabaseTableRespVO> convertList04(List<TableInfo> list); | |
| 51 | 67 | |
| 52 | 68 | // ========== 其它 ========== |
| 53 | 69 | ... | ... |
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/dataobject/codegen/CodegenTableDO.java
| 1 | 1 | package cn.iocoder.yudao.module.infra.dal.dataobject.codegen; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; |
| 4 | +import cn.iocoder.yudao.module.infra.dal.dataobject.db.DataSourceConfigDO; | |
| 4 | 5 | import cn.iocoder.yudao.module.infra.enums.codegen.CodegenSceneEnum; |
| 5 | 6 | import cn.iocoder.yudao.module.infra.enums.codegen.CodegenTemplateTypeEnum; |
| 6 | 7 | import com.baomidou.mybatisplus.annotation.TableName; |
| ... | ... | @@ -25,11 +26,11 @@ public class CodegenTableDO extends BaseDO { |
| 25 | 26 | private Long id; |
| 26 | 27 | |
| 27 | 28 | /** |
| 28 | - * 导入类型 | |
| 29 | + * 数据源编号 | |
| 29 | 30 | * |
| 30 | - * 枚举 {@link CodegenTemplateTypeEnum} | |
| 31 | + * 关联 {@link DataSourceConfigDO#getId()} | |
| 31 | 32 | */ |
| 32 | - private Integer importType; | |
| 33 | + private Long dataSourceConfigId; | |
| 33 | 34 | /** |
| 34 | 35 | * 生成场景 |
| 35 | 36 | * | ... | ... |
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/dataobject/db/DatabaseColumnDO.java deleted
| 1 | -package cn.iocoder.yudao.module.infra.dal.dataobject.db; | |
| 2 | - | |
| 3 | -import com.baomidou.mybatisplus.annotation.TableField; | |
| 4 | -import com.baomidou.mybatisplus.annotation.TableName; | |
| 5 | -import lombok.Builder; | |
| 6 | -import lombok.Data; | |
| 7 | - | |
| 8 | -/** | |
| 9 | - * MySQL 数据库中的 column 字段定义 | |
| 10 | - * | |
| 11 | - * @author 芋道源码 | |
| 12 | - */ | |
| 13 | -@Data | |
| 14 | -@Builder | |
| 15 | -public class DatabaseColumnDO { | |
| 16 | - | |
| 17 | - /** | |
| 18 | - * 表名称 | |
| 19 | - */ | |
| 20 | - private String tableName; | |
| 21 | - /** | |
| 22 | - * 字段名 | |
| 23 | - */ | |
| 24 | - private String columnName; | |
| 25 | - /** | |
| 26 | - * 字段类型 | |
| 27 | - */ | |
| 28 | - private String dataType; | |
| 29 | - /** | |
| 30 | - * 字段描述 | |
| 31 | - */ | |
| 32 | - private String columnComment; | |
| 33 | - /** | |
| 34 | - * 是否允许为空 | |
| 35 | - */ | |
| 36 | - private Boolean nullable; | |
| 37 | - /** | |
| 38 | - * 是否主键 | |
| 39 | - */ | |
| 40 | - private Boolean primaryKey; | |
| 41 | - /** | |
| 42 | - * 是否自增 | |
| 43 | - */ | |
| 44 | - private Boolean autoIncrement; | |
| 45 | - /** | |
| 46 | - * 排序字段 | |
| 47 | - */ | |
| 48 | - private Integer ordinalPosition; | |
| 49 | - | |
| 50 | -} |
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/dataobject/db/DatabaseTableDO.java deleted
| 1 | -package cn.iocoder.yudao.module.infra.dal.dataobject.db; | |
| 2 | - | |
| 3 | -import lombok.Builder; | |
| 4 | -import lombok.Data; | |
| 5 | - | |
| 6 | -import java.util.Date; | |
| 7 | - | |
| 8 | -/** | |
| 9 | - * MySQL 数据库中的 table 表定义 | |
| 10 | - * | |
| 11 | - * @author 芋道源码 | |
| 12 | - */ | |
| 13 | -@Data | |
| 14 | -@Builder | |
| 15 | -public class DatabaseTableDO { | |
| 16 | - | |
| 17 | - /** | |
| 18 | - * 表名称 | |
| 19 | - */ | |
| 20 | - private String tableName; | |
| 21 | - /** | |
| 22 | - * 表描述 | |
| 23 | - */ | |
| 24 | - private String tableComment; | |
| 25 | - /** | |
| 26 | - * 创建时间 | |
| 27 | - */ | |
| 28 | - private Date createTime; | |
| 29 | - | |
| 30 | -} |
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/codegen/CodegenTableMapper.java
| ... | ... | @@ -3,16 +3,18 @@ package cn.iocoder.yudao.module.infra.dal.mysql.codegen; |
| 3 | 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 4 | 4 | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; |
| 5 | 5 | import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX; |
| 6 | -import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenTableDO; | |
| 7 | 6 | import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.table.CodegenTablePageReqVO; |
| 8 | -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; | |
| 7 | +import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenTableDO; | |
| 9 | 8 | import org.apache.ibatis.annotations.Mapper; |
| 10 | 9 | |
| 10 | +import java.util.List; | |
| 11 | + | |
| 11 | 12 | @Mapper |
| 12 | 13 | public interface CodegenTableMapper extends BaseMapperX<CodegenTableDO> { |
| 13 | 14 | |
| 14 | - default CodegenTableDO selectByTableName(String tableName) { | |
| 15 | - return selectOne(new QueryWrapper<CodegenTableDO>().eq("table_name", tableName)); | |
| 15 | + default CodegenTableDO selectByTableNameAndDataSourceConfigId(String tableName, Long dataSourceConfigId) { | |
| 16 | + return selectOne(CodegenTableDO::getTableName, tableName, | |
| 17 | + CodegenTableDO::getDataSourceConfigId, dataSourceConfigId); | |
| 16 | 18 | } |
| 17 | 19 | |
| 18 | 20 | default PageResult<CodegenTableDO> selectPage(CodegenTablePageReqVO pageReqVO) { |
| ... | ... | @@ -22,4 +24,8 @@ public interface CodegenTableMapper extends BaseMapperX<CodegenTableDO> { |
| 22 | 24 | .betweenIfPresent("create_time", pageReqVO.getBeginCreateTime(), pageReqVO.getEndCreateTime())); |
| 23 | 25 | } |
| 24 | 26 | |
| 27 | + default List<CodegenTableDO> selectListByDataSourceConfigId(Long dataSourceConfigId) { | |
| 28 | + return selectList(CodegenTableDO::getDataSourceConfigId, dataSourceConfigId); | |
| 29 | + } | |
| 30 | + | |
| 25 | 31 | } | ... | ... |
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/db/DatabaseTableDAO.java deleted
| 1 | -package cn.iocoder.yudao.module.infra.dal.mysql.db; | |
| 2 | - | |
| 3 | -import cn.hutool.core.collection.CollUtil; | |
| 4 | -import cn.iocoder.yudao.module.infra.dal.dataobject.db.DatabaseColumnDO; | |
| 5 | -import cn.iocoder.yudao.module.infra.dal.dataobject.db.DatabaseTableDO; | |
| 6 | -import com.baomidou.mybatisplus.annotation.DbType; | |
| 7 | - | |
| 8 | -import java.sql.Connection; | |
| 9 | -import java.util.List; | |
| 10 | - | |
| 11 | -/** | |
| 12 | - * 数据库 Table DAO 接口 | |
| 13 | - * | |
| 14 | - * @author 芋道源码 | |
| 15 | - */ | |
| 16 | -public interface DatabaseTableDAO { | |
| 17 | - | |
| 18 | - /** | |
| 19 | - * 获得表列表,基于表名称 + 表描述进行模糊匹配 | |
| 20 | - * | |
| 21 | - * @param connection 数据库连接 | |
| 22 | - * @param tableNameLike 表名称,模糊匹配 | |
| 23 | - * @param tableCommentLike 表描述,模糊匹配 | |
| 24 | - * @return 表列表 | |
| 25 | - */ | |
| 26 | - List<DatabaseTableDO> selectTableList(Connection connection, String tableNameLike, String tableCommentLike); | |
| 27 | - | |
| 28 | - /** | |
| 29 | - * 获得指定表名 | |
| 30 | - * | |
| 31 | - * @param connection 数据库连接 | |
| 32 | - * @param tableName 表名称 | |
| 33 | - * @return 表 | |
| 34 | - */ | |
| 35 | - default DatabaseTableDO selectTable(Connection connection, String tableName) { | |
| 36 | - // 考虑到对性能没有要求,直接查询列表,然后内存过滤到记录 | |
| 37 | - List<DatabaseTableDO> tables = selectTableList(connection, tableName, null); | |
| 38 | - return CollUtil.findOne(tables, table -> table.getTableName().equalsIgnoreCase(tableName)); | |
| 39 | - } | |
| 40 | - | |
| 41 | - /** | |
| 42 | - * 获得指定表的字段列表 | |
| 43 | - * | |
| 44 | - * @param connection 数据库连接 | |
| 45 | - * @param tableName 表名称 | |
| 46 | - * @return 字段列表 | |
| 47 | - */ | |
| 48 | - List<DatabaseColumnDO> selectColumnList(Connection connection, String tableName); | |
| 49 | - | |
| 50 | - /** | |
| 51 | - * 获得数据库的类型 | |
| 52 | - * | |
| 53 | - * @return 数据库的类型 | |
| 54 | - */ | |
| 55 | - DbType getType(); | |
| 56 | - | |
| 57 | -} |
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/db/DatabaseTableMySQLDAOImpl.java deleted
| 1 | -package cn.iocoder.yudao.module.infra.dal.mysql.db; | |
| 2 | - | |
| 3 | -import cn.hutool.core.util.StrUtil; | |
| 4 | -import cn.iocoder.yudao.framework.mybatis.core.util.JdbcUtils; | |
| 5 | -import cn.iocoder.yudao.module.infra.dal.dataobject.db.DatabaseColumnDO; | |
| 6 | -import cn.iocoder.yudao.module.infra.dal.dataobject.db.DatabaseTableDO; | |
| 7 | -import com.baomidou.mybatisplus.annotation.DbType; | |
| 8 | -import org.springframework.stereotype.Repository; | |
| 9 | - | |
| 10 | -import java.sql.Connection; | |
| 11 | -import java.util.List; | |
| 12 | - | |
| 13 | -/** | |
| 14 | - * {@link DatabaseTableDAO} 的 MySQL 实现类 | |
| 15 | - * | |
| 16 | - * @author 芋道源码 | |
| 17 | - */ | |
| 18 | -@Repository | |
| 19 | -public class DatabaseTableMySQLDAOImpl implements DatabaseTableDAO { | |
| 20 | - | |
| 21 | - @Override | |
| 22 | - public List<DatabaseTableDO> selectTableList(Connection connection, String tableNameLike, String tableCommentLike) { | |
| 23 | - // 拼接 SQL | |
| 24 | - String sql = "SELECT table_name, table_comment, create_time" + | |
| 25 | - " FROM information_schema.TABLES" + | |
| 26 | - " WHERE table_schema = (SELECT DATABASE())"; | |
| 27 | - if (StrUtil.isNotEmpty(tableNameLike)) { | |
| 28 | - sql += StrUtil.format(" AND table_name LIKE '%{}%'", tableNameLike); | |
| 29 | - } | |
| 30 | - if (StrUtil.isNotEmpty(tableCommentLike)) { | |
| 31 | - sql += StrUtil.format(" AND table_comment LIKE '%{}%'", tableCommentLike); | |
| 32 | - } | |
| 33 | - // 执行并返回结果 | |
| 34 | - return JdbcUtils.query(connection, sql, (rs, rowNum) -> DatabaseTableDO.builder() | |
| 35 | - .tableName(rs.getString("table_name")) | |
| 36 | - .tableComment(rs.getString("table_comment")) | |
| 37 | - .createTime(rs.getDate("create_time")) | |
| 38 | - .build()); | |
| 39 | - } | |
| 40 | - | |
| 41 | - @Override | |
| 42 | - public List<DatabaseColumnDO> selectColumnList(Connection connection, String tableName) { | |
| 43 | - // 拼接 SQL | |
| 44 | - String sql = "SELECT table_name, column_name, data_type, column_comment, ordinal_position," + | |
| 45 | - " (CASE WHEN is_nullable = 'yes' THEN '1' ELSE '0' END) AS nullable," + | |
| 46 | - " (CASE WHEN column_key = 'PRI' THEN '1' ELSE '0' END) AS primary_key," + | |
| 47 | - " (CASE WHEN extra = 'auto_increment' THEN '1' ELSE '0' END) AS auto_increment" + | |
| 48 | - " FROM information_schema.COLUMNS" + | |
| 49 | - " WHERE table_schema = (SELECT DATABASE())" + | |
| 50 | - String.format(" AND table_name = '%s'", tableName); | |
| 51 | - // 执行并返回结果 | |
| 52 | - return JdbcUtils.query(connection, sql, (rs, rowNum) -> DatabaseColumnDO.builder() | |
| 53 | - .tableName(rs.getString("table_name")) | |
| 54 | - .columnName(rs.getString("column_name")) | |
| 55 | - .dataType(rs.getString("data_type")) | |
| 56 | - .columnComment(rs.getString("column_comment")) | |
| 57 | - .nullable(rs.getBoolean("nullable")) | |
| 58 | - .primaryKey(rs.getBoolean("primary_key")) | |
| 59 | - .autoIncrement(rs.getBoolean("auto_increment")) | |
| 60 | - .ordinalPosition(rs.getInt("ordinal_position")) | |
| 61 | - .build()); | |
| 62 | - } | |
| 63 | - | |
| 64 | - @Override | |
| 65 | - public DbType getType() { | |
| 66 | - return DbType.MYSQL; | |
| 67 | - } | |
| 68 | - | |
| 69 | -} |
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/db/DatabaseTableOracleDAOImpl.java deleted
| 1 | -package cn.iocoder.yudao.module.infra.dal.mysql.db; | |
| 2 | - | |
| 3 | -import cn.hutool.core.util.StrUtil; | |
| 4 | -import cn.iocoder.yudao.framework.mybatis.core.util.JdbcUtils; | |
| 5 | -import cn.iocoder.yudao.module.infra.dal.dataobject.db.DatabaseColumnDO; | |
| 6 | -import cn.iocoder.yudao.module.infra.dal.dataobject.db.DatabaseTableDO; | |
| 7 | -import com.baomidou.mybatisplus.annotation.DbType; | |
| 8 | -import org.springframework.stereotype.Repository; | |
| 9 | - | |
| 10 | -import java.sql.Connection; | |
| 11 | -import java.util.List; | |
| 12 | - | |
| 13 | -/** | |
| 14 | - * {@link DatabaseTableDAO} 的 Oracle 实现类 | |
| 15 | - * | |
| 16 | - * @author 芋道源码 | |
| 17 | - */ | |
| 18 | -@Repository | |
| 19 | -public class DatabaseTableOracleDAOImpl implements DatabaseTableDAO { | |
| 20 | - | |
| 21 | - @Override | |
| 22 | - public List<DatabaseTableDO> selectTableList(Connection connection, String tableNameLike, String tableCommentLike) { | |
| 23 | - // 拼接 SQL | |
| 24 | - String sql = "SELECT tbl.table_name, col.comments, obj.created" + | |
| 25 | - " FROM user_tables tbl, user_tab_comments col, user_objects obj" + | |
| 26 | - " WHERE tbl.table_name = col.table_name" + | |
| 27 | - " AND tbl.table_name = obj.object_name" + | |
| 28 | - " AND obj.object_type = 'TABLE'"; | |
| 29 | - if (StrUtil.isNotEmpty(tableNameLike)) { | |
| 30 | - sql += StrUtil.format(" AND tbl.table_name LIKE '%{}%'", tableNameLike); | |
| 31 | - } | |
| 32 | - if (StrUtil.isNotEmpty(tableCommentLike)) { | |
| 33 | - sql += StrUtil.format(" AND col.comments LIKE '%{}%'", tableCommentLike); | |
| 34 | - } | |
| 35 | - // 执行并返回结果 | |
| 36 | - return JdbcUtils.query(connection, sql, (rs, rowNum) -> DatabaseTableDO.builder() | |
| 37 | - .tableName(rs.getString("table_name")) | |
| 38 | - .tableComment(rs.getString("comments")) | |
| 39 | - .createTime(rs.getDate("created")) | |
| 40 | - .build()); | |
| 41 | - } | |
| 42 | - | |
| 43 | - @Override | |
| 44 | - public List<DatabaseColumnDO> selectColumnList(Connection connection, String tableName) { | |
| 45 | - // 拼接 SQL | |
| 46 | - String sql = String.format("SELECT table_name, column_name, data_type, comments, column_id," + | |
| 47 | - " (CASE WHEN nullable = 'Y' THEN '1' ELSE '0' END) AS nullable," + | |
| 48 | - " (CASE WHEN constraint_type = 'P' THEN '1' ELSE '0' END) AS primary_key" + | |
| 49 | - " FROM" + | |
| 50 | - " (" + | |
| 51 | - " SELECT col.*, comments, constraint_type," + | |
| 52 | - " row_number ( ) over ( partition BY col.column_name ORDER BY constraint_type DESC ) AS row_flag" + | |
| 53 | - " FROM user_tab_columns col" + | |
| 54 | - " LEFT JOIN user_col_comments ON user_col_comments.table_name = col.table_name" + | |
| 55 | - " AND user_col_comments.column_name = col.column_name" + | |
| 56 | - " LEFT JOIN user_cons_columns ON user_cons_columns.table_name = col.table_name" + | |
| 57 | - " AND user_cons_columns.column_name = col.column_name" + | |
| 58 | - " LEFT JOIN user_constraints ON user_constraints.constraint_name = user_cons_columns.constraint_name" + | |
| 59 | - " WHERE col.table_name = '%s'" + | |
| 60 | - " )" + | |
| 61 | - "WHERE row_flag = 1", tableName); | |
| 62 | - // 执行并返回结果 | |
| 63 | - return JdbcUtils.query(connection, sql, (rs, rowNum) -> DatabaseColumnDO.builder() | |
| 64 | - .tableName(rs.getString("table_name")) | |
| 65 | - .columnName(rs.getString("column_name")) | |
| 66 | - .dataType(rs.getString("data_type")) | |
| 67 | - .columnComment(rs.getString("comments")) | |
| 68 | - .nullable(rs.getBoolean("nullable")) | |
| 69 | - .primaryKey(rs.getBoolean("primary_key")) | |
| 70 | - .autoIncrement(false) // TODO 芋艿:oracle??? | |
| 71 | - .ordinalPosition(rs.getInt("column_id")) | |
| 72 | - .build()); | |
| 73 | - } | |
| 74 | - | |
| 75 | - @Override | |
| 76 | - public DbType getType() { | |
| 77 | - return DbType.ORACLE; | |
| 78 | - } | |
| 79 | - | |
| 80 | -} |
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/db/DatabaseTablePostgreSQLDAOImpl.java deleted
| 1 | -package cn.iocoder.yudao.module.infra.dal.mysql.db; | |
| 2 | - | |
| 3 | -import cn.hutool.core.util.StrUtil; | |
| 4 | -import cn.iocoder.yudao.framework.mybatis.core.util.JdbcUtils; | |
| 5 | -import cn.iocoder.yudao.module.infra.dal.dataobject.db.DatabaseColumnDO; | |
| 6 | -import cn.iocoder.yudao.module.infra.dal.dataobject.db.DatabaseTableDO; | |
| 7 | -import com.baomidou.mybatisplus.annotation.DbType; | |
| 8 | -import org.springframework.stereotype.Repository; | |
| 9 | - | |
| 10 | -import java.sql.Connection; | |
| 11 | -import java.util.List; | |
| 12 | - | |
| 13 | -/** | |
| 14 | - * {@link DatabaseTableDAO} 的 PostgreSQL 实现类 | |
| 15 | - * | |
| 16 | - * @author 芋道源码 | |
| 17 | - */ | |
| 18 | -@Repository | |
| 19 | -public class DatabaseTablePostgreSQLDAOImpl implements DatabaseTableDAO { | |
| 20 | - | |
| 21 | - @Override | |
| 22 | - public List<DatabaseTableDO> selectTableList(Connection connection, String tableNameLike, String tableCommentLike) { | |
| 23 | - // 拼接 SQL | |
| 24 | - String sql = "SELECT tbl.tablename, obj_description(c.oid)" + | |
| 25 | - " FROM pg_tables tbl, pg_class c" + | |
| 26 | - " WHERE tbl.schemaname = CURRENT_SCHEMA()" + | |
| 27 | - " AND tbl.tablename = c.relname"; | |
| 28 | - if (StrUtil.isNotEmpty(tableNameLike)) { | |
| 29 | - sql += StrUtil.format(" AND tbl.tablename LIKE '%{}%'", tableNameLike); | |
| 30 | - } | |
| 31 | - if (StrUtil.isNotEmpty(tableCommentLike)) { | |
| 32 | - sql += StrUtil.format(" AND obj_description(c.oid) LIKE '%{}%'", tableCommentLike); | |
| 33 | - } | |
| 34 | - // 执行并返回结果 | |
| 35 | - return JdbcUtils.query(connection, sql, (rs, rowNum) -> DatabaseTableDO.builder() | |
| 36 | - .tableName(rs.getString("tablename")) | |
| 37 | - .tableComment(rs.getString("obj_description")) | |
| 38 | - .build()); | |
| 39 | - } | |
| 40 | - | |
| 41 | - @Override | |
| 42 | - public List<DatabaseColumnDO> selectColumnList(Connection connection, String tableName) { | |
| 43 | - // 拼接 SQL | |
| 44 | - String sql = "SELECT table_name, column_name, data_type, column_comment, ordinal_position," + | |
| 45 | - " (CASE WHEN is_nullable = 'yes' THEN '1' ELSE '0' END) AS nullable," + | |
| 46 | - " (CASE WHEN column_key = 'PRI' THEN '1' ELSE '0' END) AS primary_key," + | |
| 47 | - " (CASE WHEN extra = 'auto_increment' THEN '1' ELSE '0' END) AS auto_increment" + | |
| 48 | - " FROM information_schema.COLUMNS" + | |
| 49 | - " WHERE table_schema = (SELECT DATABASE())" + | |
| 50 | - String.format(" AND table_name = '%s'", tableName); | |
| 51 | - // 执行并返回结果 | |
| 52 | - return JdbcUtils.query(connection, sql, (rs, rowNum) -> DatabaseColumnDO.builder() | |
| 53 | - .tableName(rs.getString("table_name")) | |
| 54 | - .columnName(rs.getString("column_name")) | |
| 55 | - .dataType(rs.getString("data_type")) | |
| 56 | - .columnComment(rs.getString("column_comment")) | |
| 57 | - .nullable(rs.getBoolean("nullable")) | |
| 58 | - .primaryKey(rs.getBoolean("primary_key")) | |
| 59 | - .autoIncrement(rs.getBoolean("auto_increment")) | |
| 60 | - .ordinalPosition(rs.getInt("ordinal_position")) | |
| 61 | - .build()); | |
| 62 | - } | |
| 63 | - | |
| 64 | - @Override | |
| 65 | - public DbType getType() { | |
| 66 | - return DbType.MYSQL; | |
| 67 | - } | |
| 68 | - | |
| 69 | -} |
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/enums/codegen/CodegenImportTypeEnum.java deleted
| 1 | -package cn.iocoder.yudao.module.infra.enums.codegen; | |
| 2 | - | |
| 3 | -import lombok.AllArgsConstructor; | |
| 4 | -import lombok.Getter; | |
| 5 | - | |
| 6 | -/** | |
| 7 | - * 代码生成的导入类型 | |
| 8 | - * | |
| 9 | - * @author 芋道源码 | |
| 10 | - */ | |
| 11 | -@AllArgsConstructor | |
| 12 | -@Getter | |
| 13 | -public enum CodegenImportTypeEnum { | |
| 14 | - | |
| 15 | - DB(1), // 从 information_schema 的 table 和 columns 表导入 | |
| 16 | - SQL(2); // 基于建表 SQL 语句导入 | |
| 17 | - | |
| 18 | - /** | |
| 19 | - * 类型 | |
| 20 | - */ | |
| 21 | - private final Integer type; | |
| 22 | - | |
| 23 | -} |
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/codegen/CodegenService.java
| 1 | 1 | package cn.iocoder.yudao.module.infra.service.codegen; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 4 | +import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.CodegenCreateListReqVO; | |
| 4 | 5 | import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.CodegenUpdateReqVO; |
| 5 | 6 | import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.table.CodegenTablePageReqVO; |
| 7 | +import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.table.DatabaseTableRespVO; | |
| 6 | 8 | import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenColumnDO; |
| 7 | 9 | import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenTableDO; |
| 8 | -import cn.iocoder.yudao.module.infra.dal.dataobject.db.DatabaseTableDO; | |
| 9 | 10 | |
| 10 | 11 | import java.util.List; |
| 11 | 12 | import java.util.Map; |
| ... | ... | @@ -18,31 +19,13 @@ import java.util.Map; |
| 18 | 19 | public interface CodegenService { |
| 19 | 20 | |
| 20 | 21 | /** |
| 21 | - * 基于 SQL 建表语句,创建代码生成器的表定义 | |
| 22 | - * | |
| 23 | - * @param userId 用户编号 | |
| 24 | - * @param sql SQL 建表语句 | |
| 25 | - * @return 创建的表定义的编号 | |
| 26 | - */ | |
| 27 | - Long createCodegenListFromSQL(Long userId, String sql); | |
| 28 | - | |
| 29 | - /** | |
| 30 | 22 | * 基于数据库的表结构,创建代码生成器的表定义 |
| 31 | 23 | * |
| 32 | 24 | * @param userId 用户编号 |
| 33 | - * @param tableName 表名称 | |
| 34 | - * @return 创建的表定义的编号 | |
| 35 | - */ | |
| 36 | - Long createCodegen(Long userId, String tableName); | |
| 37 | - | |
| 38 | - /** | |
| 39 | - * 基于 {@link #createCodegen(Long, String)} 的批量创建 | |
| 40 | - * | |
| 41 | - * @param userId 用户编号 | |
| 42 | - * @param tableNames 表名称数组 | |
| 25 | + * @param reqVO 表信息 | |
| 43 | 26 | * @return 创建的表定义的编号数组 |
| 44 | 27 | */ |
| 45 | - List<Long> createCodegenListFromDB(Long userId, List<String> tableNames); | |
| 28 | + List<Long> createCodegenList(Long userId, CodegenCreateListReqVO reqVO); | |
| 46 | 29 | |
| 47 | 30 | /** |
| 48 | 31 | * 更新数据库的表和字段定义 |
| ... | ... | @@ -59,14 +42,6 @@ public interface CodegenService { |
| 59 | 42 | void syncCodegenFromDB(Long tableId); |
| 60 | 43 | |
| 61 | 44 | /** |
| 62 | - * 基于 SQL 建表语句,同步数据库的表和字段定义 | |
| 63 | - * | |
| 64 | - * @param tableId 表编号 | |
| 65 | - * @param sql SQL 建表语句 | |
| 66 | - */ | |
| 67 | - void syncCodegenFromSQL(Long tableId, String sql); | |
| 68 | - | |
| 69 | - /** | |
| 70 | 45 | * 删除数据库的表和字段定义 |
| 71 | 46 | * |
| 72 | 47 | * @param tableId 数据编号 |
| ... | ... | @@ -90,13 +65,6 @@ public interface CodegenService { |
| 90 | 65 | CodegenTableDO getCodegenTablePage(Long id); |
| 91 | 66 | |
| 92 | 67 | /** |
| 93 | - * 获得全部表定义 | |
| 94 | - * | |
| 95 | - * @return 表定义数组 | |
| 96 | - */ | |
| 97 | - List<CodegenTableDO> getCodeGenTableList(); | |
| 98 | - | |
| 99 | - /** | |
| 100 | 68 | * 获得指定表的字段定义数组 |
| 101 | 69 | * |
| 102 | 70 | * @param tableId 表编号 |
| ... | ... | @@ -116,11 +84,11 @@ public interface CodegenService { |
| 116 | 84 | * 获得数据库自带的表定义列表 |
| 117 | 85 | * |
| 118 | 86 | * |
| 119 | - * @param dataSourceConfigId | |
| 120 | - * @param tableName 表名称 | |
| 121 | - * @param tableComment 表描述 | |
| 87 | + * @param dataSourceConfigId 数据源的配置编号 | |
| 88 | + * @param name 表名称 | |
| 89 | + * @param comment 表描述 | |
| 122 | 90 | * @return 表定义列表 |
| 123 | 91 | */ |
| 124 | - List<DatabaseTableDO> getSchemaTableList(Long dataSourceConfigId, String tableName, String tableComment); | |
| 92 | + List<DatabaseTableRespVO> getDatabaseTableList(Long dataSourceConfigId, String name, String comment); | |
| 125 | 93 | |
| 126 | 94 | } | ... | ... |
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/codegen/CodegenServiceImpl.java
| ... | ... | @@ -3,22 +3,21 @@ package cn.iocoder.yudao.module.infra.service.codegen; |
| 3 | 3 | import cn.hutool.core.collection.CollUtil; |
| 4 | 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 5 | 5 | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; |
| 6 | +import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.CodegenCreateListReqVO; | |
| 6 | 7 | import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.CodegenUpdateReqVO; |
| 7 | 8 | import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.table.CodegenTablePageReqVO; |
| 9 | +import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.table.DatabaseTableRespVO; | |
| 8 | 10 | import cn.iocoder.yudao.module.infra.convert.codegen.CodegenConvert; |
| 9 | 11 | import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenColumnDO; |
| 10 | 12 | import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenTableDO; |
| 11 | -import cn.iocoder.yudao.module.infra.dal.dataobject.db.DatabaseColumnDO; | |
| 12 | -import cn.iocoder.yudao.module.infra.dal.dataobject.db.DatabaseTableDO; | |
| 13 | 13 | import cn.iocoder.yudao.module.infra.dal.mysql.codegen.CodegenColumnMapper; |
| 14 | 14 | import cn.iocoder.yudao.module.infra.dal.mysql.codegen.CodegenTableMapper; |
| 15 | -import cn.iocoder.yudao.module.infra.enums.codegen.CodegenImportTypeEnum; | |
| 16 | 15 | import cn.iocoder.yudao.module.infra.service.codegen.inner.CodegenBuilder; |
| 17 | 16 | import cn.iocoder.yudao.module.infra.service.codegen.inner.CodegenEngine; |
| 18 | -import cn.iocoder.yudao.module.infra.service.codegen.inner.CodegenSQLParser; | |
| 19 | 17 | import cn.iocoder.yudao.module.infra.service.db.DatabaseTableService; |
| 20 | 18 | import cn.iocoder.yudao.module.system.api.user.AdminUserApi; |
| 21 | -import org.apache.commons.collections4.KeyValue; | |
| 19 | +import com.baomidou.mybatisplus.generator.config.po.TableField; | |
| 20 | +import com.baomidou.mybatisplus.generator.config.po.TableInfo; | |
| 22 | 21 | import org.springframework.stereotype.Service; |
| 23 | 22 | import org.springframework.transaction.annotation.Transactional; |
| 24 | 23 | |
| ... | ... | @@ -56,66 +55,48 @@ public class CodegenServiceImpl implements CodegenService { |
| 56 | 55 | @Resource |
| 57 | 56 | private CodegenEngine codegenEngine; |
| 58 | 57 | |
| 59 | - private Long createCodegen0(Long userId, CodegenImportTypeEnum importType, | |
| 60 | - DatabaseTableDO schemaTable, List<DatabaseColumnDO> schemaColumns) { | |
| 58 | + @Override | |
| 59 | + @Transactional(rollbackFor = Exception.class) | |
| 60 | + public List<Long> createCodegenList(Long userId, CodegenCreateListReqVO reqVO) { | |
| 61 | + List<Long> ids = new ArrayList<>(reqVO.getTableNames().size()); | |
| 62 | + // 遍历添加。虽然效率会低一点,但是没必要做成完全批量,因为不会这么大量 | |
| 63 | + reqVO.getTableNames().forEach(tableName -> ids.add(createCodegen(userId, reqVO.getDataSourceConfigId(), tableName))); | |
| 64 | + return ids; | |
| 65 | + } | |
| 66 | + | |
| 67 | + public Long createCodegen(Long userId, Long dataSourceConfigId, String tableName) { | |
| 68 | + // 从数据库中,获得数据库表结构 | |
| 69 | + TableInfo tableInfo = databaseTableService.getTable(dataSourceConfigId, tableName); | |
| 70 | + // 导入 | |
| 71 | + return createCodegen0(userId, dataSourceConfigId, tableInfo); | |
| 72 | + } | |
| 73 | + | |
| 74 | + private Long createCodegen0(Long userId, Long dataSourceConfigId, TableInfo tableInfo) { | |
| 61 | 75 | // 校验导入的表和字段非空 |
| 62 | - if (schemaTable == null) { | |
| 76 | + if (tableInfo == null) { | |
| 63 | 77 | throw exception(CODEGEN_IMPORT_TABLE_NULL); |
| 64 | 78 | } |
| 65 | - if (CollUtil.isEmpty(schemaColumns)) { | |
| 79 | + if (CollUtil.isEmpty(tableInfo.getFields())) { | |
| 66 | 80 | throw exception(CODEGEN_IMPORT_COLUMNS_NULL); |
| 67 | 81 | } |
| 68 | 82 | // 校验是否已经存在 |
| 69 | - if (codegenTableMapper.selectByTableName(schemaTable.getTableName()) != null) { | |
| 83 | + if (codegenTableMapper.selectByTableNameAndDataSourceConfigId(tableInfo.getName(), | |
| 84 | + dataSourceConfigId) != null) { | |
| 70 | 85 | throw exception(CODEGEN_TABLE_EXISTS); |
| 71 | 86 | } |
| 72 | 87 | |
| 73 | 88 | // 构建 CodegenTableDO 对象,插入到 DB 中 |
| 74 | - CodegenTableDO table = codegenBuilder.buildTable(schemaTable); | |
| 75 | - table.setImportType(importType.getType()); | |
| 89 | + CodegenTableDO table = codegenBuilder.buildTable(tableInfo); | |
| 90 | + table.setDataSourceConfigId(dataSourceConfigId); | |
| 76 | 91 | table.setAuthor(userApi.getUser(userId).getNickname()); |
| 77 | 92 | codegenTableMapper.insert(table); |
| 78 | 93 | // 构建 CodegenColumnDO 数组,插入到 DB 中 |
| 79 | - List<CodegenColumnDO> columns = codegenBuilder.buildColumns(table.getId(), schemaColumns); | |
| 94 | + List<CodegenColumnDO> columns = codegenBuilder.buildColumns(table.getId(), tableInfo.getFields()); | |
| 80 | 95 | codegenColumnMapper.insertBatch(columns); |
| 81 | 96 | return table.getId(); |
| 82 | 97 | } |
| 83 | 98 | |
| 84 | 99 | @Override |
| 85 | - public Long createCodegenListFromSQL(Long userId, String sql) { | |
| 86 | - // 从 SQL 中,获得数据库表结构 | |
| 87 | - DatabaseTableDO schemaTable; | |
| 88 | - List<DatabaseColumnDO> schemaColumns; | |
| 89 | - try { | |
| 90 | - KeyValue<DatabaseTableDO, List<DatabaseColumnDO>> result = CodegenSQLParser.parse(sql); | |
| 91 | - schemaTable = result.getKey(); | |
| 92 | - schemaColumns = result.getValue(); | |
| 93 | - } catch (Exception ex) { | |
| 94 | - throw exception(CODEGEN_PARSE_SQL_ERROR); | |
| 95 | - } | |
| 96 | - // 导入 | |
| 97 | - return this.createCodegen0(userId, CodegenImportTypeEnum.SQL, schemaTable, schemaColumns); | |
| 98 | - } | |
| 99 | - | |
| 100 | - @Override | |
| 101 | - public Long createCodegen(Long userId, String tableName) { | |
| 102 | - // 从数据库中,获得数据库表结构 | |
| 103 | - DatabaseTableDO schemaTable = databaseTableService.getTable(9L, tableName); | |
| 104 | - List<DatabaseColumnDO> schemaColumns = databaseTableService.getColumnList(9L, tableName); | |
| 105 | - // 导入 | |
| 106 | - return this.createCodegen0(userId, CodegenImportTypeEnum.DB, schemaTable, schemaColumns); | |
| 107 | - } | |
| 108 | - | |
| 109 | - @Override | |
| 110 | - @Transactional(rollbackFor = Exception.class) | |
| 111 | - public List<Long> createCodegenListFromDB(Long userId, List<String> tableNames) { | |
| 112 | - List<Long> ids = new ArrayList<>(tableNames.size()); | |
| 113 | - // 遍历添加。虽然效率会低一点,但是没必要做成完全批量,因为不会这么大量 | |
| 114 | - tableNames.forEach(tableName -> ids.add(createCodegen(userId, tableName))); | |
| 115 | - return ids; | |
| 116 | - } | |
| 117 | - | |
| 118 | - @Override | |
| 119 | 100 | @Transactional(rollbackFor = Exception.class) |
| 120 | 101 | public void updateCodegen(CodegenUpdateReqVO updateReqVO) { |
| 121 | 102 | // 校验是否已经存在 |
| ... | ... | @@ -140,54 +121,33 @@ public class CodegenServiceImpl implements CodegenService { |
| 140 | 121 | throw exception(CODEGEN_TABLE_NOT_EXISTS); |
| 141 | 122 | } |
| 142 | 123 | // 从数据库中,获得数据库表结构 |
| 143 | - List<DatabaseColumnDO> schemaColumns = databaseTableService.getColumnList(0L, table.getTableName()); | |
| 144 | - | |
| 124 | + TableInfo tableInfo = databaseTableService.getTable(table.getDataSourceConfigId(), table.getTableName()); | |
| 145 | 125 | // 执行同步 |
| 146 | - this.syncCodegen0(tableId, schemaColumns); | |
| 126 | + syncCodegen0(tableId, tableInfo); | |
| 147 | 127 | } |
| 148 | 128 | |
| 149 | - @Override | |
| 150 | - @Transactional(rollbackFor = Exception.class) | |
| 151 | - public void syncCodegenFromSQL(Long tableId, String sql) { | |
| 152 | - // 校验是否已经存在 | |
| 153 | - CodegenTableDO table = codegenTableMapper.selectById(tableId); | |
| 154 | - if (table == null) { | |
| 155 | - throw exception(CODEGEN_TABLE_NOT_EXISTS); | |
| 156 | - } | |
| 157 | - // 从 SQL 中,获得数据库表结构 | |
| 158 | - List<DatabaseColumnDO> schemaColumns; | |
| 159 | - try { | |
| 160 | - KeyValue<DatabaseTableDO, List<DatabaseColumnDO>> result = CodegenSQLParser.parse(sql); | |
| 161 | - schemaColumns = result.getValue(); | |
| 162 | - } catch (Exception ex) { | |
| 163 | - throw exception(CODEGEN_PARSE_SQL_ERROR); | |
| 164 | - } | |
| 165 | - | |
| 166 | - // 执行同步 | |
| 167 | - this.syncCodegen0(tableId, schemaColumns); | |
| 168 | - } | |
| 169 | - | |
| 170 | - private void syncCodegen0(Long tableId, List<DatabaseColumnDO> schemaColumns) { | |
| 129 | + private void syncCodegen0(Long tableId, TableInfo tableInfo) { | |
| 171 | 130 | // 校验导入的字段不为空 |
| 172 | - if (CollUtil.isEmpty(schemaColumns)) { | |
| 131 | + List<TableField> tableFields = tableInfo.getFields(); | |
| 132 | + if (CollUtil.isEmpty(tableFields)) { | |
| 173 | 133 | throw exception(CODEGEN_SYNC_COLUMNS_NULL); |
| 174 | 134 | } |
| 175 | - Set<String> schemaColumnNames = CollectionUtils.convertSet(schemaColumns, DatabaseColumnDO::getColumnName); | |
| 135 | + Set<String> tableFieldNames = CollectionUtils.convertSet(tableFields, TableField::getName); | |
| 176 | 136 | |
| 177 | 137 | // 构建 CodegenColumnDO 数组,只同步新增的字段 |
| 178 | 138 | List<CodegenColumnDO> codegenColumns = codegenColumnMapper.selectListByTableId(tableId); |
| 179 | 139 | Set<String> codegenColumnNames = CollectionUtils.convertSet(codegenColumns, CodegenColumnDO::getColumnName); |
| 180 | 140 | // 移除已经存在的字段 |
| 181 | - schemaColumns.removeIf(column -> codegenColumnNames.contains(column.getColumnName())); | |
| 141 | + tableFields.removeIf(column -> codegenColumnNames.contains(column.getColumnName())); | |
| 182 | 142 | // 计算需要删除的字段 |
| 183 | - Set<Long> deleteColumnIds = codegenColumns.stream().filter(column -> !schemaColumnNames.contains(column.getColumnName())) | |
| 143 | + Set<Long> deleteColumnIds = codegenColumns.stream().filter(column -> !tableFieldNames.contains(column.getColumnName())) | |
| 184 | 144 | .map(CodegenColumnDO::getId).collect(Collectors.toSet()); |
| 185 | - if (CollUtil.isEmpty(schemaColumns) && CollUtil.isEmpty(deleteColumnIds)) { | |
| 145 | + if (CollUtil.isEmpty(tableFields) && CollUtil.isEmpty(deleteColumnIds)) { | |
| 186 | 146 | throw exception(CODEGEN_SYNC_NONE_CHANGE); |
| 187 | 147 | } |
| 188 | 148 | |
| 189 | 149 | // 插入新增的字段 |
| 190 | - List<CodegenColumnDO> columns = codegenBuilder.buildColumns(tableId, schemaColumns); | |
| 150 | + List<CodegenColumnDO> columns = codegenBuilder.buildColumns(tableId, tableFields); | |
| 191 | 151 | codegenColumnMapper.insertBatch(columns); |
| 192 | 152 | // 删除不存在的字段 |
| 193 | 153 | if (CollUtil.isNotEmpty(deleteColumnIds)) { |
| ... | ... | @@ -220,11 +180,6 @@ public class CodegenServiceImpl implements CodegenService { |
| 220 | 180 | } |
| 221 | 181 | |
| 222 | 182 | @Override |
| 223 | - public List<CodegenTableDO> getCodeGenTableList() { | |
| 224 | - return codegenTableMapper.selectList(); | |
| 225 | - } | |
| 226 | - | |
| 227 | - @Override | |
| 228 | 183 | public List<CodegenColumnDO> getCodegenColumnListByTableId(Long tableId) { |
| 229 | 184 | return codegenColumnMapper.selectListByTableId(tableId); |
| 230 | 185 | } |
| ... | ... | @@ -246,13 +201,18 @@ public class CodegenServiceImpl implements CodegenService { |
| 246 | 201 | } |
| 247 | 202 | |
| 248 | 203 | @Override |
| 249 | - public List<DatabaseTableDO> getSchemaTableList(Long dataSourceConfigId, String tableName, String tableComment) { | |
| 250 | - List<DatabaseTableDO> tables = databaseTableService.getTableList(dataSourceConfigId, tableName, tableComment); | |
| 251 | - // TODO 强制移除 Quartz 的表,未来做成可配置 | |
| 252 | - tables.removeIf(table -> table.getTableName().startsWith("QRTZ_")); | |
| 253 | - tables.removeIf(table -> table.getTableName().startsWith("ACT_")); | |
| 254 | - tables.removeIf(table -> table.getTableName().startsWith("FLW_")); | |
| 255 | - return tables; | |
| 204 | + public List<DatabaseTableRespVO> getDatabaseTableList(Long dataSourceConfigId, String name, String comment) { | |
| 205 | + List<TableInfo> tables = databaseTableService.getTableList(dataSourceConfigId, name, comment); | |
| 206 | + // 移除置顶前缀的表名 // TODO 未来做成可配置 | |
| 207 | + tables.removeIf(table -> table.getName().startsWith("QRTZ_")); | |
| 208 | + tables.removeIf(table -> table.getName().startsWith("ACT_")); | |
| 209 | + tables.removeIf(table -> table.getName().startsWith("FLW_")); | |
| 210 | + // 移除已经生成的表 | |
| 211 | + // 移除在 Codegen 中,已经存在的 | |
| 212 | + Set<String> existsTables = CollectionUtils.convertSet( | |
| 213 | + codegenTableMapper.selectListByDataSourceConfigId(dataSourceConfigId), CodegenTableDO::getTableName); | |
| 214 | + tables.removeIf(table -> existsTables.contains(table.getName())); | |
| 215 | + return CodegenConvert.INSTANCE.convertList04(tables); | |
| 256 | 216 | } |
| 257 | 217 | |
| 258 | 218 | } | ... | ... |
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenBuilder.java
| ... | ... | @@ -7,23 +7,22 @@ import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; |
| 7 | 7 | import cn.iocoder.yudao.module.infra.convert.codegen.CodegenConvert; |
| 8 | 8 | import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenColumnDO; |
| 9 | 9 | import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenTableDO; |
| 10 | -import cn.iocoder.yudao.module.infra.dal.dataobject.db.DatabaseColumnDO; | |
| 11 | -import cn.iocoder.yudao.module.infra.dal.dataobject.db.DatabaseTableDO; | |
| 12 | 10 | import cn.iocoder.yudao.module.infra.enums.codegen.CodegenColumnHtmlTypeEnum; |
| 13 | 11 | import cn.iocoder.yudao.module.infra.enums.codegen.CodegenColumnListConditionEnum; |
| 14 | 12 | import cn.iocoder.yudao.module.infra.enums.codegen.CodegenTemplateTypeEnum; |
| 13 | +import com.baomidou.mybatisplus.generator.config.po.TableField; | |
| 14 | +import com.baomidou.mybatisplus.generator.config.po.TableInfo; | |
| 15 | 15 | import com.google.common.collect.Sets; |
| 16 | 16 | import org.springframework.stereotype.Component; |
| 17 | 17 | |
| 18 | -import java.math.BigDecimal; | |
| 19 | 18 | import java.util.*; |
| 20 | 19 | |
| 21 | 20 | import static cn.hutool.core.text.CharSequenceUtil.*; |
| 22 | 21 | |
| 23 | 22 | /** |
| 24 | 23 | * 代码生成器的 Builder,负责: |
| 25 | - * 1. 将数据库的表 {@link DatabaseTableDO} 定义,构建成 {@link CodegenTableDO} | |
| 26 | - * 2. 将数据库的列 {@link DatabaseColumnDO} 构定义,建成 {@link CodegenColumnDO} | |
| 24 | + * 1. 将数据库的表 {@link TableInfo} 定义,构建成 {@link CodegenTableDO} | |
| 25 | + * 2. 将数据库的列 {@link TableField} 构定义,建成 {@link CodegenColumnDO} | |
| 27 | 26 | */ |
| 28 | 27 | @Component |
| 29 | 28 | public class CodegenBuilder { |
| ... | ... | @@ -82,24 +81,6 @@ public class CodegenBuilder { |
| 82 | 81 | */ |
| 83 | 82 | private static final Set<String> LIST_OPERATION_RESULT_EXCLUDE_COLUMN = Sets.newHashSet(); |
| 84 | 83 | |
| 85 | - /** | |
| 86 | - * Java 类型与 MySQL 类型的映射关系 | |
| 87 | - */ | |
| 88 | - private static final Map<String, Set<String>> javaTypeMappings = MapUtil.<String, Set<String>>builder() | |
| 89 | - .put(Boolean.class.getSimpleName(), Sets.newHashSet("bit")) | |
| 90 | - .put(Integer.class.getSimpleName(), Sets.newHashSet( | |
| 91 | - "tinyint", "smallint", "mediumint", "int", "integer")) | |
| 92 | - .put(Long.class.getSimpleName(), Sets.newHashSet("bigint", "number")) | |
| 93 | - .put(Double.class.getSimpleName(), Sets.newHashSet("float", "double")) | |
| 94 | - .put(BigDecimal.class.getSimpleName(), Sets.newHashSet("decimal", "numeric")) | |
| 95 | - .put(String.class.getSimpleName(), Sets.newHashSet( | |
| 96 | - "tinytext", "text", "mediumtext", "longtext", "nclob", // 长文本 | |
| 97 | - "char", "varchar", "nvarchar", "varchar2", "nvarchar2", // 短文本 | |
| 98 | - "json")) // 特殊文本 | |
| 99 | - .put(Date.class.getSimpleName(), Sets.newHashSet("datetime", "time", "date", "timestamp")) | |
| 100 | - .put("byte[]", Sets.newHashSet("blob")) | |
| 101 | - .build(); | |
| 102 | - | |
| 103 | 84 | static { |
| 104 | 85 | Arrays.stream(ReflectUtil.getFields(BaseDO.class)).forEach(field -> BASE_DO_FIELDS.add(field.getName())); |
| 105 | 86 | BASE_DO_FIELDS.add(TENANT_ID_FIELD); |
| ... | ... | @@ -112,8 +93,8 @@ public class CodegenBuilder { |
| 112 | 93 | LIST_OPERATION_RESULT_EXCLUDE_COLUMN.remove("createTime"); // 创建时间,还是需要返回的 |
| 113 | 94 | } |
| 114 | 95 | |
| 115 | - public CodegenTableDO buildTable(DatabaseTableDO schemaTable) { | |
| 116 | - CodegenTableDO table = CodegenConvert.INSTANCE.convert(schemaTable); | |
| 96 | + public CodegenTableDO buildTable(TableInfo tableInfo) { | |
| 97 | + CodegenTableDO table = CodegenConvert.INSTANCE.convert(tableInfo); | |
| 117 | 98 | initTableDefault(table); |
| 118 | 99 | return table; |
| 119 | 100 | } |
| ... | ... | @@ -136,43 +117,19 @@ public class CodegenBuilder { |
| 136 | 117 | table.setTemplateType(CodegenTemplateTypeEnum.CRUD.getType()); |
| 137 | 118 | } |
| 138 | 119 | |
| 139 | - public List<CodegenColumnDO> buildColumns(Long tableId, List<DatabaseColumnDO> schemaColumns) { | |
| 140 | - List<CodegenColumnDO> columns = CodegenConvert.INSTANCE.convertList(schemaColumns); | |
| 120 | + public List<CodegenColumnDO> buildColumns(Long tableId, List<TableField> tableFields) { | |
| 121 | + List<CodegenColumnDO> columns = CodegenConvert.INSTANCE.convertList(tableFields); | |
| 122 | + int index = 1; | |
| 141 | 123 | for (CodegenColumnDO column : columns) { |
| 142 | 124 | column.setTableId(tableId); |
| 143 | - initColumnDefault(column); | |
| 125 | + column.setOrdinalPosition(index++); | |
| 126 | + // 初始化 Column 列的默认字段 | |
| 127 | + processColumnOperation(column); // 处理 CRUD 相关的字段的默认值 | |
| 128 | + processColumnUI(column); // 处理 UI 相关的字段的默认值 | |
| 144 | 129 | } |
| 145 | 130 | return columns; |
| 146 | 131 | } |
| 147 | 132 | |
| 148 | - /** | |
| 149 | - * 初始化 Column 列的默认字段 | |
| 150 | - * | |
| 151 | - * @param column 列定义 | |
| 152 | - */ | |
| 153 | - private void initColumnDefault(CodegenColumnDO column) { | |
| 154 | - // 处理 Java 相关的字段的默认值 | |
| 155 | - processColumnJava(column); | |
| 156 | - // 处理 CRUD 相关的字段的默认值 | |
| 157 | - processColumnOperation(column); | |
| 158 | - // 处理 UI 相关的字段的默认值 | |
| 159 | - processColumnUI(column); | |
| 160 | - } | |
| 161 | - | |
| 162 | - private void processColumnJava(CodegenColumnDO column) { | |
| 163 | - // 处理 javaField 字段 | |
| 164 | - column.setJavaField(toCamelCase(column.getColumnName())); | |
| 165 | - // 处理 dataType 字段 | |
| 166 | - String dataType = column.getDataType().toLowerCase(); | |
| 167 | - javaTypeMappings.entrySet().stream() | |
| 168 | - .filter(entry -> entry.getValue().contains(dataType)) | |
| 169 | - .findFirst().ifPresent(entry -> column.setJavaType(entry.getKey())); | |
| 170 | - if (column.getJavaType() == null) { | |
| 171 | - throw new IllegalStateException(String.format("column(%s) 的数据库类型(%s) 找不到匹配的 Java 类型", | |
| 172 | - column.getColumnName(), column.getJavaType())); | |
| 173 | - } | |
| 174 | - } | |
| 175 | - | |
| 176 | 133 | private void processColumnOperation(CodegenColumnDO column) { |
| 177 | 134 | // 处理 createOperation 字段 |
| 178 | 135 | column.setCreateOperation(!CREATE_OPERATION_EXCLUDE_COLUMN.contains(column.getJavaField()) | ... | ... |
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenSQLParser.java deleted
| 1 | -package cn.iocoder.yudao.module.infra.service.codegen.inner; | |
| 2 | - | |
| 3 | -import cn.hutool.core.collection.CollUtil; | |
| 4 | -import cn.iocoder.yudao.module.infra.dal.dataobject.db.DatabaseColumnDO; | |
| 5 | -import cn.iocoder.yudao.module.infra.dal.dataobject.db.DatabaseTableDO; | |
| 6 | -import com.alibaba.druid.DbType; | |
| 7 | -import com.alibaba.druid.sql.ast.expr.SQLCharExpr; | |
| 8 | -import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition; | |
| 9 | -import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement; | |
| 10 | -import com.alibaba.druid.sql.ast.statement.SQLPrimaryKey; | |
| 11 | -import com.alibaba.druid.sql.ast.statement.SQLTableElement; | |
| 12 | -import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCreateTableStatement; | |
| 13 | -import com.alibaba.druid.sql.repository.SchemaRepository; | |
| 14 | -import org.apache.commons.collections4.KeyValue; | |
| 15 | -import org.apache.commons.collections4.keyvalue.DefaultKeyValue; | |
| 16 | - | |
| 17 | -import java.util.ArrayList; | |
| 18 | -import java.util.List; | |
| 19 | -import java.util.Objects; | |
| 20 | - | |
| 21 | -import static com.alibaba.druid.sql.SQLUtils.normalize; | |
| 22 | - | |
| 23 | -/** | |
| 24 | - * SQL 解析器,将创建表的 SQL,解析成 {@link DatabaseTableDO} 和 {@link DatabaseColumnDO} 对象, | |
| 25 | - * 后续可以基于它们,生成代码~ | |
| 26 | - * | |
| 27 | - * @author 芋道源码 | |
| 28 | - */ | |
| 29 | -public class CodegenSQLParser { | |
| 30 | - | |
| 31 | - /** | |
| 32 | - * 解析建表 SQL 语句,返回 {@link DatabaseTableDO} 和 {@link DatabaseColumnDO} 对象 | |
| 33 | - * | |
| 34 | - * @param sql 建表 SQL 语句 | |
| 35 | - * @return 解析结果 | |
| 36 | - */ | |
| 37 | - public static KeyValue<DatabaseTableDO, List<DatabaseColumnDO>> parse(String sql) { | |
| 38 | - // 解析 SQL 成 Statement | |
| 39 | - SQLCreateTableStatement statement = parseCreateSQL(sql); | |
| 40 | - // 解析 Table 表 | |
| 41 | - DatabaseTableDO table = parseTable(statement); | |
| 42 | - // 解析 Column 字段 | |
| 43 | - List<DatabaseColumnDO> columns = parseColumns(statement); | |
| 44 | - columns.forEach(column -> column.setTableName(table.getTableName())); | |
| 45 | - // 返回 | |
| 46 | - return new DefaultKeyValue<>(table, columns); | |
| 47 | - } | |
| 48 | - | |
| 49 | - /** | |
| 50 | - * 使用 Druid 工具,建表 SQL 语句 | |
| 51 | - * | |
| 52 | - * @param sql 建表 SQL 语句 | |
| 53 | - * @return 创建 Statement | |
| 54 | - */ | |
| 55 | - private static SQLCreateTableStatement parseCreateSQL(String sql) { | |
| 56 | - // 解析 SQL | |
| 57 | - SchemaRepository repository = new SchemaRepository(DbType.mysql); | |
| 58 | - repository.console(sql); | |
| 59 | - // 获得该表对应的 MySqlCreateTableStatement 对象 | |
| 60 | - String tableName = CollUtil.getFirst(repository.getDefaultSchema().getObjects()).getName(); | |
| 61 | - return (MySqlCreateTableStatement) repository.findTable(tableName).getStatement(); | |
| 62 | - } | |
| 63 | - | |
| 64 | - private static DatabaseTableDO parseTable(SQLCreateTableStatement statement) { | |
| 65 | - return DatabaseTableDO.builder() | |
| 66 | - .tableName(statement.getTableSource().getTableName(true)) | |
| 67 | - .tableComment(getCommentText(statement)) | |
| 68 | - .build(); | |
| 69 | - } | |
| 70 | - | |
| 71 | - private static String getCommentText(SQLCreateTableStatement statement) { | |
| 72 | - if (statement == null || statement.getComment() == null) { | |
| 73 | - return ""; | |
| 74 | - } | |
| 75 | - return ((SQLCharExpr) statement.getComment()).getText(); | |
| 76 | - } | |
| 77 | - | |
| 78 | - private static List<DatabaseColumnDO> parseColumns(SQLCreateTableStatement statement) { | |
| 79 | - List<DatabaseColumnDO> columns = new ArrayList<>(); | |
| 80 | - statement.getTableElementList().forEach(element -> parseColumn(columns, element)); | |
| 81 | - return columns; | |
| 82 | - } | |
| 83 | - | |
| 84 | - private static void parseColumn(List<DatabaseColumnDO> columns, SQLTableElement element) { | |
| 85 | - // 处理主键 | |
| 86 | - if (element instanceof SQLPrimaryKey) { | |
| 87 | - parsePrimaryKey(columns, (SQLPrimaryKey) element); | |
| 88 | - return; | |
| 89 | - } | |
| 90 | - // 处理字段定义 | |
| 91 | - if (element instanceof SQLColumnDefinition) { | |
| 92 | - parseColumnDefinition(columns, (SQLColumnDefinition) element); | |
| 93 | - } | |
| 94 | - } | |
| 95 | - | |
| 96 | - private static void parsePrimaryKey(List<DatabaseColumnDO> columns, SQLPrimaryKey primaryKey) { | |
| 97 | - String columnName = normalize(primaryKey.getColumns().get(0).toString()); // 暂时不考虑联合主键 | |
| 98 | - // 匹配 columns 主键字段,设置为 primary | |
| 99 | - columns.stream().filter(column -> column.getColumnName().equals(columnName)) | |
| 100 | - .forEach(column -> column.setPrimaryKey(true)); | |
| 101 | - } | |
| 102 | - | |
| 103 | - private static void parseColumnDefinition(List<DatabaseColumnDO> columns, SQLColumnDefinition definition) { | |
| 104 | - String text = definition.toString().toUpperCase(); | |
| 105 | - columns.add(DatabaseColumnDO.builder() | |
| 106 | - .columnName(normalize(definition.getColumnName())) | |
| 107 | - .dataType(definition.getDataType().toString()) | |
| 108 | - .columnComment(Objects.isNull(definition.getComment()) ? "" | |
| 109 | - : normalize(definition.getComment().toString())) | |
| 110 | - .nullable(!text.contains(" NOT NULL")) | |
| 111 | - .primaryKey(false) | |
| 112 | - .autoIncrement(text.contains("AUTO_INCREMENT")) | |
| 113 | - .ordinalPosition(columns.size() + 1) | |
| 114 | - .build()); | |
| 115 | - } | |
| 116 | - | |
| 117 | -} |
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/db/DataSourceConfigService.java
| ... | ... | @@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.infra.service.db; |
| 3 | 3 | import cn.iocoder.yudao.module.infra.controller.admin.db.vo.DataSourceConfigCreateReqVO; |
| 4 | 4 | import cn.iocoder.yudao.module.infra.controller.admin.db.vo.DataSourceConfigUpdateReqVO; |
| 5 | 5 | import cn.iocoder.yudao.module.infra.dal.dataobject.db.DataSourceConfigDO; |
| 6 | -import cn.iocoder.yudao.module.infra.dal.dataobject.db.DatabaseTableDO; | |
| 7 | 6 | |
| 8 | 7 | import javax.validation.Valid; |
| 9 | 8 | import java.util.List; | ... | ... |
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/db/DatabaseTableService.java
| 1 | 1 | package cn.iocoder.yudao.module.infra.service.db; |
| 2 | 2 | |
| 3 | -import cn.iocoder.yudao.module.infra.dal.dataobject.db.DatabaseColumnDO; | |
| 4 | -import cn.iocoder.yudao.module.infra.dal.dataobject.db.DatabaseTableDO; | |
| 5 | 3 | import com.baomidou.mybatisplus.generator.config.po.TableInfo; |
| 6 | 4 | |
| 7 | 5 | import java.util.List; |
| ... | ... | @@ -17,11 +15,11 @@ public interface DatabaseTableService { |
| 17 | 15 | * 获得表列表,基于表名称 + 表描述进行模糊匹配 |
| 18 | 16 | * |
| 19 | 17 | * @param dataSourceConfigId 数据源配置的编号 |
| 20 | - * @param tableNameLike 表名称,模糊匹配 | |
| 21 | - * @param tableCommentLike 表描述,模糊匹配 | |
| 18 | + * @param nameLike 表名称,模糊匹配 | |
| 19 | + * @param commentLike 表描述,模糊匹配 | |
| 22 | 20 | * @return 表列表 |
| 23 | 21 | */ |
| 24 | - List<DatabaseTableDO> getTableList(Long dataSourceConfigId, String tableNameLike, String tableCommentLike); | |
| 22 | + List<TableInfo> getTableList(Long dataSourceConfigId, String nameLike, String commentLike); | |
| 25 | 23 | |
| 26 | 24 | /** |
| 27 | 25 | * 获得指定表名 |
| ... | ... | @@ -30,35 +28,6 @@ public interface DatabaseTableService { |
| 30 | 28 | * @param tableName 表名称 |
| 31 | 29 | * @return 表 |
| 32 | 30 | */ |
| 33 | - DatabaseTableDO getTable(Long dataSourceConfigId, String tableName); | |
| 34 | - | |
| 35 | - /** | |
| 36 | - * 获得指定表的字段列表 | |
| 37 | - * | |
| 38 | - * @param dataSourceConfigId 数据源配置的编号 | |
| 39 | - * @param tableName 表名称 | |
| 40 | - * @return 字段列表 | |
| 41 | - */ | |
| 42 | - List<DatabaseColumnDO> getColumnList(Long dataSourceConfigId, String tableName); | |
| 43 | - | |
| 44 | - | |
| 45 | - /** | |
| 46 | - * 获得表列表,基于表名称 + 表描述进行模糊匹配 | |
| 47 | - * | |
| 48 | - * @param dataSourceConfigId 数据源配置的编号 | |
| 49 | - * @param tableNameLike 表名称,模糊匹配 | |
| 50 | - * @param tableCommentLike 表描述,模糊匹配 | |
| 51 | - * @return 表列表 | |
| 52 | - */ | |
| 53 | - List<TableInfo> getTableList2(Long dataSourceConfigId, String tableNameLike, String tableCommentLike); | |
| 54 | - | |
| 55 | - /** | |
| 56 | - * 获得指定表名 | |
| 57 | - * | |
| 58 | - * @param dataSourceConfigId 数据源配置的编号 | |
| 59 | - * @param tableName 表名称 | |
| 60 | - * @return 表 | |
| 61 | - */ | |
| 62 | - TableInfo getTable2(Long dataSourceConfigId, String tableName); | |
| 31 | + TableInfo getTable(Long dataSourceConfigId, String tableName); | |
| 63 | 32 | |
| 64 | 33 | } | ... | ... |
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/db/DatabaseTableServiceImpl.java
| ... | ... | @@ -2,20 +2,20 @@ package cn.iocoder.yudao.module.infra.service.db; |
| 2 | 2 | |
| 3 | 3 | import cn.hutool.core.collection.CollUtil; |
| 4 | 4 | import cn.hutool.core.lang.Assert; |
| 5 | -import cn.iocoder.yudao.framework.mybatis.core.util.JdbcUtils; | |
| 5 | +import cn.hutool.core.util.StrUtil; | |
| 6 | 6 | import cn.iocoder.yudao.module.infra.dal.dataobject.db.DataSourceConfigDO; |
| 7 | -import cn.iocoder.yudao.module.infra.dal.dataobject.db.DatabaseColumnDO; | |
| 8 | -import cn.iocoder.yudao.module.infra.dal.dataobject.db.DatabaseTableDO; | |
| 9 | -import cn.iocoder.yudao.module.infra.dal.mysql.db.DatabaseTableDAO; | |
| 10 | -import com.baomidou.mybatisplus.annotation.DbType; | |
| 7 | +import com.baomidou.mybatisplus.generator.config.DataSourceConfig; | |
| 8 | +import com.baomidou.mybatisplus.generator.config.GlobalConfig; | |
| 9 | +import com.baomidou.mybatisplus.generator.config.StrategyConfig; | |
| 10 | +import com.baomidou.mybatisplus.generator.config.builder.ConfigBuilder; | |
| 11 | 11 | import com.baomidou.mybatisplus.generator.config.po.TableInfo; |
| 12 | -import lombok.SneakyThrows; | |
| 12 | +import com.baomidou.mybatisplus.generator.config.rules.DateType; | |
| 13 | 13 | import org.springframework.stereotype.Service; |
| 14 | 14 | |
| 15 | 15 | import javax.annotation.Resource; |
| 16 | -import java.sql.Connection; | |
| 17 | 16 | import java.util.Comparator; |
| 18 | 17 | import java.util.List; |
| 18 | +import java.util.stream.Collectors; | |
| 19 | 19 | |
| 20 | 20 | /** |
| 21 | 21 | * 数据库表 Service 实现类 |
| ... | ... | @@ -28,61 +28,38 @@ public class DatabaseTableServiceImpl implements DatabaseTableService { |
| 28 | 28 | @Resource |
| 29 | 29 | private DataSourceConfigService dataSourceConfigService; |
| 30 | 30 | |
| 31 | - @Resource | |
| 32 | - private List<DatabaseTableDAO> databaseTableDAOs; | |
| 33 | - | |
| 34 | - @Override | |
| 35 | - @SneakyThrows | |
| 36 | - public List<DatabaseTableDO> getTableList(Long dataSourceConfigId, String tableNameLike, String tableCommentLike) { | |
| 37 | - try (Connection connection = getConnection(dataSourceConfigId)) { | |
| 38 | - return getDatabaseTableDAO(dataSourceConfigId).selectTableList(connection, tableNameLike, tableCommentLike); | |
| 39 | - } | |
| 40 | - } | |
| 41 | - | |
| 42 | - @Override | |
| 43 | - @SneakyThrows | |
| 44 | - public DatabaseTableDO getTable(Long dataSourceConfigId, String tableName) { | |
| 45 | - try (Connection connection = getConnection(dataSourceConfigId)) { | |
| 46 | - return getDatabaseTableDAO(dataSourceConfigId).selectTable(connection, tableName); | |
| 47 | - } | |
| 48 | - } | |
| 49 | - | |
| 50 | - @Override | |
| 51 | - @SneakyThrows | |
| 52 | - public List<DatabaseColumnDO> getColumnList(Long dataSourceConfigId, String tableName) { | |
| 53 | - try (Connection connection = getConnection(dataSourceConfigId)) { | |
| 54 | - List<DatabaseColumnDO> columns = getDatabaseTableDAO(dataSourceConfigId).selectColumnList(connection, tableName); | |
| 55 | - columns.sort(Comparator.comparing(DatabaseColumnDO::getOrdinalPosition)); | |
| 56 | - return columns; | |
| 57 | - } | |
| 58 | - } | |
| 59 | - | |
| 60 | 31 | @Override |
| 61 | - public List<TableInfo> getTableList2(Long dataSourceConfigId, String tableNameLike, String tableCommentLike) { | |
| 62 | - return null; | |
| 32 | + public List<TableInfo> getTableList(Long dataSourceConfigId, String nameLike, String commentLike) { | |
| 33 | + List<TableInfo> tables = getTableList0(dataSourceConfigId, null); | |
| 34 | + return tables.stream().filter(tableInfo -> (StrUtil.isEmpty(nameLike) || tableInfo.getName().contains(nameLike)) | |
| 35 | + && (StrUtil.isEmpty(commentLike) || tableInfo.getComment().contains(commentLike))) | |
| 36 | + .collect(Collectors.toList()); | |
| 63 | 37 | } |
| 64 | 38 | |
| 65 | 39 | @Override |
| 66 | - public TableInfo getTable2(Long dataSourceConfigId, String tableName) { | |
| 67 | - return null; | |
| 40 | + public TableInfo getTable(Long dataSourceConfigId, String name) { | |
| 41 | + return CollUtil.getFirst(getTableList0(dataSourceConfigId, name)); | |
| 68 | 42 | } |
| 69 | 43 | |
| 70 | - private Connection getConnection(Long dataSourceConfigId) { | |
| 44 | + public List<TableInfo> getTableList0(Long dataSourceConfigId, String name) { | |
| 45 | + // 获得数据源配置 | |
| 71 | 46 | DataSourceConfigDO config = dataSourceConfigService.getDataSourceConfig(dataSourceConfigId); |
| 72 | 47 | Assert.notNull(config, "数据源({}) 不存在!", dataSourceConfigId); |
| 73 | - return JdbcUtils.getConnection(config.getUrl(), config.getUsername(), config.getPassword()); | |
| 74 | - } | |
| 75 | 48 | |
| 76 | - private DatabaseTableDAO getDatabaseTableDAO(Long dataSourceConfigId) { | |
| 77 | - DataSourceConfigDO config = dataSourceConfigService.getDataSourceConfig(dataSourceConfigId); | |
| 78 | - Assert.notNull(config, "数据源({}) 不存在!", dataSourceConfigId); | |
| 79 | - // 获得 dbType | |
| 80 | - DbType dbType = JdbcUtils.getDbType(config.getUrl()); | |
| 81 | - Assert.notNull(config, "数据源类型({}) 不存在!", config.getUrl()); | |
| 82 | - // 获得 DatabaseTableDAO | |
| 83 | - DatabaseTableDAO dao = CollUtil.findOne(databaseTableDAOs, databaseTableDAO -> databaseTableDAO.getType().equals(dbType)); | |
| 84 | - Assert.notNull(dao, "DAO({}) 查找不到实现!", dbType); | |
| 85 | - return dao; | |
| 49 | + // 使用 MyBatis Plus Generator 解析表结构 | |
| 50 | + DataSourceConfig dataSourceConfig = new DataSourceConfig.Builder(config.getUrl(), config.getUsername(), | |
| 51 | + config.getPassword()).build(); | |
| 52 | + StrategyConfig.Builder strategyConfig = new StrategyConfig.Builder(); | |
| 53 | + if (StrUtil.isNotEmpty(name)) { | |
| 54 | + strategyConfig.addInclude(name); | |
| 55 | + } | |
| 56 | + GlobalConfig globalConfig = new GlobalConfig.Builder().dateType(DateType.ONLY_DATE).build(); // 只使用 Date 类型,不使用 LocalDate | |
| 57 | + ConfigBuilder builder = new ConfigBuilder(null, dataSourceConfig, strategyConfig.build(), | |
| 58 | + null, globalConfig, null); | |
| 59 | + // 按照名字排序 | |
| 60 | + List<TableInfo> tables = builder.getTableInfoList(); | |
| 61 | + tables.sort(Comparator.comparing(TableInfo::getName)); | |
| 62 | + return tables; | |
| 86 | 63 | } |
| 87 | 64 | |
| 88 | 65 | } | ... | ... |
yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/DefaultDatabaseQueryTest.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.infra.service; | |
| 2 | + | |
| 3 | +import com.baomidou.mybatisplus.generator.IDatabaseQuery.DefaultDatabaseQuery; | |
| 4 | +import com.baomidou.mybatisplus.generator.config.DataSourceConfig; | |
| 5 | +import com.baomidou.mybatisplus.generator.config.builder.ConfigBuilder; | |
| 6 | +import com.baomidou.mybatisplus.generator.config.po.TableInfo; | |
| 7 | + | |
| 8 | +import java.util.List; | |
| 9 | + | |
| 10 | +public class DefaultDatabaseQueryTest { | |
| 11 | + | |
| 12 | + public static void main(String[] args) { | |
| 13 | + DataSourceConfig dataSourceConfig = new DataSourceConfig.Builder("jdbc:oracle:thin:@127.0.0.1:1521:xe", | |
| 14 | + "root", "123456").build(); | |
| 15 | +// StrategyConfig strategyConfig = new StrategyConfig.Builder().build(); | |
| 16 | + | |
| 17 | + ConfigBuilder builder = new ConfigBuilder(null, dataSourceConfig, null, null, null, null); | |
| 18 | + | |
| 19 | + DefaultDatabaseQuery query = new DefaultDatabaseQuery(builder); | |
| 20 | + | |
| 21 | + long time = System.currentTimeMillis(); | |
| 22 | + List<TableInfo> tableInfos = query.queryTables(); | |
| 23 | + System.out.println(tableInfos.size()); | |
| 24 | + System.out.println(System.currentTimeMillis() - time); | |
| 25 | + } | |
| 26 | + | |
| 27 | +} | ... | ... |
yudao-ui-admin/src/api/infra/codegen.js
| ... | ... | @@ -73,26 +73,11 @@ export function getSchemaTableList(query) { |
| 73 | 73 | } |
| 74 | 74 | |
| 75 | 75 | // 基于数据库的表结构,创建代码生成器的表定义 |
| 76 | -export function createCodegenListFromDB(tableNames) { | |
| 76 | +export function createCodegenList(data) { | |
| 77 | 77 | return request({ |
| 78 | - url: '/infra/codegen/create-list-from-db', | |
| 78 | + url: '/infra/codegen/create-list', | |
| 79 | 79 | method: 'post', |
| 80 | - headers:{ | |
| 81 | - 'Content-type': 'application/x-www-form-urlencoded' | |
| 82 | - }, | |
| 83 | - data: 'tableNames=' + tableNames | |
| 84 | - }) | |
| 85 | -} | |
| 86 | - | |
| 87 | -// 基于 SQL 建表语句,创建代码生成器的表定义 | |
| 88 | -export function createCodegenListFromSQL(data) { | |
| 89 | - return request({ | |
| 90 | - url: '/infra/codegen/create-list-from-sql', | |
| 91 | - method: 'post', | |
| 92 | - headers:{ | |
| 93 | - 'Content-type': 'application/x-www-form-urlencoded' | |
| 94 | - }, | |
| 95 | - data: 'sql=' + data.sql, | |
| 80 | + data: data | |
| 96 | 81 | }) |
| 97 | 82 | } |
| 98 | 83 | ... | ... |
yudao-ui-admin/src/views/infra/codegen/editTable.vue
yudao-ui-admin/src/views/infra/codegen/importTable.vue
| ... | ... | @@ -8,11 +8,11 @@ |
| 8 | 8 | :key="config.id" :label="config.name" :value="config.id"/> |
| 9 | 9 | </el-select> |
| 10 | 10 | </el-form-item> |
| 11 | - <el-form-item label="表名称" prop="tableName"> | |
| 12 | - <el-input v-model="queryParams.tableName" placeholder="请输入表名称" clearable @keyup.enter.native="handleQuery" /> | |
| 11 | + <el-form-item label="表名称" prop="name"> | |
| 12 | + <el-input v-model="queryParams.name" placeholder="请输入表名称" clearable @keyup.enter.native="handleQuery" /> | |
| 13 | 13 | </el-form-item> |
| 14 | - <el-form-item label="表描述" prop="tableComment"> | |
| 15 | - <el-input v-model="queryParams.tableComment" placeholder="请输入表描述" clearable @keyup.enter.native="handleQuery"/> | |
| 14 | + <el-form-item label="表描述" prop="comment"> | |
| 15 | + <el-input v-model="queryParams.comment" placeholder="请输入表描述" clearable @keyup.enter.native="handleQuery"/> | |
| 16 | 16 | </el-form-item> |
| 17 | 17 | <el-form-item> |
| 18 | 18 | <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button> |
| ... | ... | @@ -20,15 +20,11 @@ |
| 20 | 20 | </el-form-item> |
| 21 | 21 | </el-form> |
| 22 | 22 | <el-row> |
| 23 | - <el-table @row-click="clickRow" ref="table" :data="dbTableList" @selection-change="handleSelectionChange" height="260px"> | |
| 23 | + <el-table v-loading="loading" @row-click="clickRow" ref="table" :data="dbTableList" | |
| 24 | + @selection-change="handleSelectionChange" height="260px"> | |
| 24 | 25 | <el-table-column type="selection" width="55" /> |
| 25 | - <el-table-column prop="tableName" label="表名称" :show-overflow-tooltip="true" /> | |
| 26 | - <el-table-column prop="tableComment" label="表描述" :show-overflow-tooltip="true" /> | |
| 27 | - <el-table-column prop="createTime" label="创建时间"> | |
| 28 | - <template slot-scope="scope"> | |
| 29 | - <span>{{ parseTime(scope.row.createTime) }}</span> | |
| 30 | - </template> | |
| 31 | - </el-table-column> | |
| 26 | + <el-table-column prop="name" label="表名称" :show-overflow-tooltip="true" /> | |
| 27 | + <el-table-column prop="comment" label="表描述" :show-overflow-tooltip="true" /> | |
| 32 | 28 | </el-table> |
| 33 | 29 | </el-row> |
| 34 | 30 | <div slot="footer" class="dialog-footer"> |
| ... | ... | @@ -39,12 +35,14 @@ |
| 39 | 35 | </template> |
| 40 | 36 | |
| 41 | 37 | <script> |
| 42 | -import { getSchemaTableList, createCodegenListFromDB } from "@/api/infra/codegen"; | |
| 38 | +import { getSchemaTableList, createCodegenList } from "@/api/infra/codegen"; | |
| 43 | 39 | import {getDataSourceConfigList} from "@/api/infra/dataSourceConfig"; |
| 44 | 40 | export default { |
| 45 | 41 | data() { |
| 46 | 42 | return { |
| 47 | 43 | // 遮罩层 |
| 44 | + loading: false, | |
| 45 | + // 遮罩层 | |
| 48 | 46 | visible: false, |
| 49 | 47 | // 选中数组值 |
| 50 | 48 | tables: [], |
| ... | ... | @@ -55,8 +53,8 @@ export default { |
| 55 | 53 | // 查询参数 |
| 56 | 54 | queryParams: { |
| 57 | 55 | dataSourceConfigId: undefined, |
| 58 | - tableName: undefined, | |
| 59 | - tableComment: undefined, | |
| 56 | + name: undefined, | |
| 57 | + comment: undefined, | |
| 60 | 58 | }, |
| 61 | 59 | // 数据源列表 |
| 62 | 60 | dataSourceConfigs: [], |
| ... | ... | @@ -79,12 +77,15 @@ export default { |
| 79 | 77 | }, |
| 80 | 78 | // 多选框选中数据 |
| 81 | 79 | handleSelectionChange(selection) { |
| 82 | - this.tables = selection.map(item => item.tableName); | |
| 80 | + this.tables = selection.map(item => item.name); | |
| 83 | 81 | }, |
| 84 | 82 | // 查询表数据 |
| 85 | 83 | getList() { |
| 84 | + this.loading = true; | |
| 86 | 85 | getSchemaTableList(this.queryParams).then(res => { |
| 87 | 86 | this.dbTableList = res.data; |
| 87 | + }).finally(() => { | |
| 88 | + this.loading = false; | |
| 88 | 89 | }); |
| 89 | 90 | }, |
| 90 | 91 | /** 搜索按钮操作 */ |
| ... | ... | @@ -99,7 +100,10 @@ export default { |
| 99 | 100 | }, |
| 100 | 101 | /** 导入按钮操作 */ |
| 101 | 102 | handleImportTable() { |
| 102 | - createCodegenListFromDB(this.tables.join(",")).then(res => { | |
| 103 | + createCodegenList({ | |
| 104 | + dataSourceConfigId: this.queryParams.dataSourceConfigId, | |
| 105 | + tableNames: this.tables | |
| 106 | + }).then(res => { | |
| 103 | 107 | this.$modal.msgSuccess("导入成功"); |
| 104 | 108 | this.visible = false; |
| 105 | 109 | this.$emit("ok"); | ... | ... |
yudao-ui-admin/src/views/infra/codegen/index.vue
| ... | ... | @@ -26,29 +26,28 @@ |
| 26 | 26 | <el-row :gutter="10" class="mb8"> |
| 27 | 27 | <el-col :span="1.5"> |
| 28 | 28 | <el-button type="info" plain icon="el-icon-upload" size="mini" @click="openImportTable" |
| 29 | - v-hasPermi="['infra:codegen:create']">基于 DB 导入</el-button> | |
| 30 | - <el-button type="info" plain icon="el-icon-upload" size="mini" @click="openImportSQL" | |
| 31 | - v-hasPermi="['infra:codegen:create']">基于 SQL 导入</el-button> | |
| 29 | + v-hasPermi="['infra:codegen:create']">导入</el-button> | |
| 32 | 30 | </el-col> |
| 33 | 31 | <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar> |
| 34 | 32 | </el-row> |
| 35 | 33 | |
| 36 | 34 | <!-- 列表 --> |
| 37 | 35 | <el-table v-loading="loading" :data="tableList"> |
| 38 | - <el-table-column label="表名称" align="center" prop="tableName" :show-overflow-tooltip="true" width="200"/> | |
| 36 | + <el-table-column label="数据源" align="center" :formatter="dataSourceConfigNameFormat"/> | |
| 37 | + <el-table-column label="表名称" align="center" prop="tableName" width="200"/> | |
| 39 | 38 | <el-table-column label="表描述" align="center" prop="tableComment" :show-overflow-tooltip="true" width="120"/> |
| 40 | - <el-table-column label="实体" align="center" prop="className" :show-overflow-tooltip="true" width="200"/> | |
| 41 | - <el-table-column label="创建时间" align="center" prop="createTime" width="160"> | |
| 39 | + <el-table-column label="实体" align="center" prop="className" width="200"/> | |
| 40 | + <el-table-column label="创建时间" align="center" prop="createTime" width="180"> | |
| 42 | 41 | <template slot-scope="scope"> |
| 43 | 42 | <span>{{ parseTime(scope.row.createTime) }}</span> |
| 44 | 43 | </template> |
| 45 | 44 | </el-table-column> |
| 46 | - <el-table-column label="更新时间" align="center" prop="createTime" width="160"> | |
| 45 | + <el-table-column label="更新时间" align="center" prop="createTime" width="180"> | |
| 47 | 46 | <template slot-scope="scope"> |
| 48 | 47 | <span>{{ parseTime(scope.row.updateTime) }}</span> |
| 49 | 48 | </template> |
| 50 | 49 | </el-table-column> |
| 51 | - <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> | |
| 50 | + <el-table-column label="操作" align="center" width="300px" class-name="small-padding fixed-width"> | |
| 52 | 51 | <template slot-scope="scope"> |
| 53 | 52 | <el-button type="text" size="small" icon="el-icon-view" @click="handlePreview(scope.row)" v-hasPermi="['infra:codegen:preview']">预览</el-button> |
| 54 | 53 | <el-button type="text" size="small" icon="el-icon-edit" @click="handleEditTable(scope.row)" v-hasPermi="['infra:codegen:update']">编辑</el-button> |
| ... | ... | @@ -81,23 +80,6 @@ |
| 81 | 80 | |
| 82 | 81 | <!-- 基于 DB 导入 --> |
| 83 | 82 | <import-table ref="import" @ok="handleQuery" /> |
| 84 | - | |
| 85 | - <!-- 基于 SQL 导入 --> | |
| 86 | - <el-dialog :title="importSQL.title" :visible.sync="importSQL.open" width="800px" append-to-body> | |
| 87 | - <el-form ref="importSQLForm" :model="importSQL.form" :rules="importSQL.rules" label-width="120px"> | |
| 88 | - <el-row> | |
| 89 | - <el-col :span="12"> | |
| 90 | - <el-form-item label="建表 SQL 语句" prop="sql"> | |
| 91 | - <el-input v-model="importSQL.form.sql" type="textarea" rows="30" style="width: 650px;" placeholder="请输入建 SQL 语句" /> | |
| 92 | - </el-form-item> | |
| 93 | - </el-col> | |
| 94 | - </el-row> | |
| 95 | - </el-form> | |
| 96 | - <div slot="footer" class="dialog-footer"> | |
| 97 | - <el-button type="primary" @click="submitImportSQLForm">确 定</el-button> | |
| 98 | - <el-button @click="cancel">取 消</el-button> | |
| 99 | - </div> | |
| 100 | - </el-dialog> | |
| 101 | 83 | </div> |
| 102 | 84 | </template> |
| 103 | 85 | |
| ... | ... | @@ -109,6 +91,7 @@ import importTable from "./importTable"; |
| 109 | 91 | // 代码高亮插件 |
| 110 | 92 | import hljs from "highlight.js/lib/highlight"; |
| 111 | 93 | import "highlight.js/styles/github-gist.css"; |
| 94 | +import {getDataSourceConfigList} from "@/api/infra/dataSourceConfig"; | |
| 112 | 95 | hljs.registerLanguage("java", require("highlight.js/lib/languages/java")); |
| 113 | 96 | hljs.registerLanguage("xml", require("highlight.js/lib/languages/xml")); |
| 114 | 97 | hljs.registerLanguage("html", require("highlight.js/lib/languages/xml")); |
| ... | ... | @@ -150,21 +133,16 @@ export default { |
| 150 | 133 | data: {}, |
| 151 | 134 | activeName: "", |
| 152 | 135 | }, |
| 153 | - // 基于 SQL 导入 | |
| 154 | - importSQL: { | |
| 155 | - open: false, | |
| 156 | - title: "", | |
| 157 | - form: { | |
| 158 | - | |
| 159 | - }, | |
| 160 | - rules: { | |
| 161 | - sql: [{ required: true, message: "SQL 不能为空", trigger: "blur" }] | |
| 162 | - } | |
| 163 | - } | |
| 136 | + // 数据源列表 | |
| 137 | + dataSourceConfigs: [], | |
| 164 | 138 | }; |
| 165 | 139 | }, |
| 166 | 140 | created() { |
| 167 | 141 | this.getList(); |
| 142 | + // 加载数据源 | |
| 143 | + getDataSourceConfigList().then(response => { | |
| 144 | + this.dataSourceConfigs = response.data; | |
| 145 | + }); | |
| 168 | 146 | }, |
| 169 | 147 | activated() { |
| 170 | 148 | const time = this.$route.query.t; |
| ... | ... | @@ -200,12 +178,6 @@ export default { |
| 200 | 178 | }, |
| 201 | 179 | /** 同步数据库操作 */ |
| 202 | 180 | handleSynchDb(row) { |
| 203 | - // 基于 SQL 同步 | |
| 204 | - if (row.importType === 2) { | |
| 205 | - this.importSQL.open = true; | |
| 206 | - this.importSQL.form.tableId = row.id; | |
| 207 | - return; | |
| 208 | - } | |
| 209 | 181 | // 基于 DB 同步 |
| 210 | 182 | const tableName = row.tableName; |
| 211 | 183 | this.$modal.confirm('确认要强制同步"' + tableName + '"表结构吗?').then(function() { |
| ... | ... | @@ -218,10 +190,6 @@ export default { |
| 218 | 190 | openImportTable() { |
| 219 | 191 | this.$refs.import.show(); |
| 220 | 192 | }, |
| 221 | - /** 打开 SQL 导入的弹窗 **/ | |
| 222 | - openImportSQL() { | |
| 223 | - this.importSQL.open = true; | |
| 224 | - }, | |
| 225 | 193 | /** 重置按钮操作 */ |
| 226 | 194 | resetQuery() { |
| 227 | 195 | this.dateRange = []; |
| ... | ... | @@ -336,43 +304,15 @@ export default { |
| 336 | 304 | this.$modal.msgSuccess("删除成功"); |
| 337 | 305 | }).catch(() => {}); |
| 338 | 306 | }, |
| 339 | - // 取消按钮 | |
| 340 | - cancel() { | |
| 341 | - this.importSQL.open = false; | |
| 342 | - this.reset(); | |
| 343 | - }, | |
| 344 | - // 表单重置 | |
| 345 | - reset() { | |
| 346 | - this.importSQL.form = { | |
| 347 | - tableId: undefined, | |
| 348 | - sql: undefined, | |
| 349 | - }; | |
| 350 | - this.resetForm("importSQLForm"); | |
| 351 | - }, | |
| 352 | - // 提交 import SQL 表单 | |
| 353 | - submitImportSQLForm() { | |
| 354 | - this.$refs["importSQLForm"].validate(valid => { | |
| 355 | - if (!valid) { | |
| 356 | - return; | |
| 357 | - } | |
| 358 | - // 修改的提交 | |
| 359 | - let form = this.importSQL.form; | |
| 360 | - if (form.tableId != null) { | |
| 361 | - syncCodegenFromSQL(form.tableId, form.sql).then(response => { | |
| 362 | - this.$modal.msgSuccess("同步成功"); | |
| 363 | - this.importSQL.open = false; | |
| 364 | - this.getList(); | |
| 365 | - }); | |
| 366 | - return; | |
| 307 | + // 数据源配置的名字 | |
| 308 | + dataSourceConfigNameFormat(row, column) { | |
| 309 | + for (const config of this.dataSourceConfigs) { | |
| 310 | + if (row.dataSourceConfigId === config.id) { | |
| 311 | + return config.name; | |
| 367 | 312 | } |
| 368 | - // 添加的提交 | |
| 369 | - createCodegenListFromSQL(form).then(response => { | |
| 370 | - this.$modal.msgSuccess("导入成功"); | |
| 371 | - this.importSQL.open = false; | |
| 372 | - this.getList(); | |
| 373 | - }); | |
| 374 | - }); | |
| 375 | - } | |
| 313 | + } | |
| 314 | + return '未知【' + row.leaderUserId + '】'; | |
| 315 | + }, | |
| 376 | 316 | } |
| 377 | 317 | }; |
| 378 | 318 | </script> | ... | ... |