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