Commit d79549b48a635c856f8b8c26b1d2155f56163096

Authored by YunaiV
1 parent d04271b9

优化代码生成器实现,增加 DatabaseTableDAO 抽象,支持多 db 类型

Showing 21 changed files with 419 additions and 155 deletions
yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/util/DatabaseUtils.java deleted
1   -package cn.iocoder.yudao.framework.mybatis.core.util;
2   -
3   -import java.sql.Connection;
4   -import java.sql.DriverManager;
5   -
6   -/**
7   - * 数据库工具类
8   - *
9   - * @author 芋道源码
10   - */
11   -public class DatabaseUtils {
12   -
13   - /**
14   - * 判断连接是否正确
15   - *
16   - * @param url 数据源连接
17   - * @param username 账号
18   - * @param password 密码
19   - * @return 是否正确
20   - */
21   - public static boolean isConnectionOK(String url, String username, String password) {
22   - try (Connection ignored = DriverManager.getConnection(url, username, password)) {
23   - return true;
24   - } catch (Exception ex) {
25   - return false;
26   - }
27   - }
28   -
29   -}
yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/util/JdbcUtils.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.mybatis.core.util;
  2 +
  3 +import com.baomidou.mybatisplus.annotation.DbType;
  4 +import lombok.SneakyThrows;
  5 +import org.springframework.dao.DataAccessException;
  6 +import org.springframework.jdbc.core.JdbcTemplate;
  7 +import org.springframework.jdbc.core.RowCallbackHandler;
  8 +import org.springframework.jdbc.core.RowMapper;
  9 +
  10 +import java.sql.*;
  11 +import java.util.ArrayList;
  12 +import java.util.List;
  13 +
  14 +/**
  15 + * JDBC 工具类
  16 + *
  17 + * @author 芋道源码
  18 + */
  19 +public class JdbcUtils {
  20 +
  21 + /**
  22 + * 判断连接是否正确
  23 + *
  24 + * @param url 数据源连接
  25 + * @param username 账号
  26 + * @param password 密码
  27 + * @return 是否正确
  28 + */
  29 + public static boolean isConnectionOK(String url, String username, String password) {
  30 + try (Connection ignored = DriverManager.getConnection(url, username, password)) {
  31 + return true;
  32 + } catch (Exception ex) {
  33 + return false;
  34 + }
  35 + }
  36 +
  37 + /**
  38 + * 获得连接
  39 + *
  40 + * @param url 数据源连接
  41 + * @param username 账号
  42 + * @param password 密码
  43 + * @return 是否正确
  44 + */
  45 + @SneakyThrows
  46 + public static Connection getConnection(String url, String username, String password) {
  47 + return DriverManager.getConnection(url, username, password);
  48 + }
  49 +
  50 + /**
  51 + * 执行指定 SQL,返回查询列表
  52 + *
  53 + * 参考 {@link JdbcTemplate#query(String, RowMapper)} 实现,主要考虑 JdbcTemplate 不支持使用指定 Connection 查询
  54 + *
  55 + * @param connection 数据库连接
  56 + * @param sql SQL
  57 + * @param handler 行处理器
  58 + * @return 列表
  59 + */
  60 + @SneakyThrows
  61 + public static <T> List<T> query(Connection connection, String sql, RowMapper<T> handler) {
  62 + try (PreparedStatement ps = connection.prepareStatement(sql);
  63 + ResultSet rs = ps.executeQuery()) {
  64 + // 处理结果
  65 + List<T> result = new ArrayList<>();
  66 + int rowNum = 0;
  67 + while (rs.next()) {
  68 + result.add(handler.mapRow(rs, rowNum++));
  69 + }
  70 + return result;
  71 + }
  72 + }
  73 +
  74 + /**
  75 + * 获得 URL 对应的 DB 类型
  76 + *
  77 + * @param url URL
  78 + * @return DB 类型
  79 + */
  80 + public static DbType getDbType(String url) {
  81 + String name = com.alibaba.druid.util.JdbcUtils.getDbType(url, null);
  82 + return DbType.getDbType(name);
  83 + }
  84 +
  85 +}
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/CodegenController.java
... ... @@ -13,7 +13,7 @@ import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.table.SchemaTab
13 13 import cn.iocoder.yudao.module.infra.convert.codegen.CodegenConvert;
14 14 import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenColumnDO;
15 15 import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenTableDO;
16   -import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.SchemaTableDO;
  16 +import cn.iocoder.yudao.module.infra.dal.dataobject.db.DatabaseTableDO;
17 17 import cn.iocoder.yudao.module.infra.service.codegen.CodegenService;
18 18 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
19 19 import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;
... ... @@ -58,7 +58,7 @@ public class CodegenController {
58 58 @RequestParam(value = "tableName", required = false) String tableName,
59 59 @RequestParam(value = "tableComment", required = false) String tableComment) {
60 60 // 获得数据库自带的表定义列表
61   - List<SchemaTableDO> schemaTables = codegenService.getSchemaTableList(tableName, tableComment);
  61 + List<DatabaseTableDO> schemaTables = codegenService.getSchemaTableList(tableName, tableComment);
62 62 // 移除在 Codegen 中,已经存在的
63 63 Set<String> existsTables = CollectionUtils.convertSet(codegenService.getCodeGenTableList(), CodegenTableDO::getTableName);
64 64 schemaTables.removeIf(table -> existsTables.contains(table.getTableName()));
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/convert/codegen/CodegenConvert.java
... ... @@ -9,8 +9,8 @@ import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.table.CodegenTa
9 9 import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.table.SchemaTableRespVO;
10 10 import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenColumnDO;
11 11 import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenTableDO;
12   -import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.SchemaColumnDO;
13   -import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.SchemaTableDO;
  12 +import cn.iocoder.yudao.module.infra.dal.dataobject.db.DatabaseColumnDO;
  13 +import cn.iocoder.yudao.module.infra.dal.dataobject.db.DatabaseTableDO;
14 14 import org.mapstruct.Mapper;
15 15 import org.mapstruct.factory.Mappers;
16 16  
... ... @@ -25,11 +25,11 @@ public interface CodegenConvert {
25 25  
26 26 // ========== InformationSchemaTableDO 和 InformationSchemaColumnDO 相关 ==========
27 27  
28   - CodegenTableDO convert(SchemaTableDO bean);
  28 + CodegenTableDO convert(DatabaseTableDO bean);
29 29  
30   - List<CodegenColumnDO> convertList(List<SchemaColumnDO> list);
  30 + List<CodegenColumnDO> convertList(List<DatabaseColumnDO> list);
31 31  
32   - CodegenTableRespVO convert(SchemaColumnDO bean);
  32 + CodegenTableRespVO convert(DatabaseColumnDO bean);
33 33  
34 34 // ========== CodegenTableDO 相关 ==========
35 35  
... ... @@ -47,7 +47,7 @@ public interface CodegenConvert {
47 47  
48 48 List<CodegenColumnDO> convertList03(List<CodegenUpdateReqVO.Column> columns);
49 49  
50   - List<SchemaTableRespVO> convertList04(List<SchemaTableDO> list);
  50 + List<SchemaTableRespVO> convertList04(List<DatabaseTableDO> list);
51 51  
52 52 // ========== 其它 ==========
53 53  
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/dataobject/codegen/CodegenColumnDO.java
... ... @@ -74,7 +74,6 @@ public class CodegenColumnDO extends BaseDO {
74 74 /**
75 75 * Java 属性名
76 76 */
77   -// @NotBlank(message = "Java属性不能为空")
78 77 private String javaField;
79 78 /**
80 79 * 字典类型
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/dataobject/db/DataSourceConfigDO.java
... ... @@ -14,6 +14,11 @@ import lombok.Data;
14 14 public class DataSourceConfigDO extends BaseDO {
15 15  
16 16 /**
  17 + * 主键编号 - Master 数据源
  18 + */
  19 + public static final Long ID_MASTER = 0L;
  20 +
  21 + /**
17 22 * 主键编号
18 23 */
19 24 private Long id;
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/dataobject/codegen/SchemaColumnDO.java renamed to yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/dataobject/db/DatabaseColumnDO.java
1   -package cn.iocoder.yudao.module.infra.dal.dataobject.codegen;
  1 +package cn.iocoder.yudao.module.infra.dal.dataobject.db;
2 2  
3 3 import com.baomidou.mybatisplus.annotation.TableField;
4 4 import com.baomidou.mybatisplus.annotation.TableName;
... ... @@ -10,10 +10,9 @@ import lombok.Data;
10 10 *
11 11 * @author 芋道源码
12 12 */
13   -@TableName(value = "information_schema.columns", autoResultMap = true)
14 13 @Data
15 14 @Builder
16   -public class SchemaColumnDO {
  15 +public class DatabaseColumnDO {
17 16  
18 17 /**
19 18 * 表名称
... ... @@ -34,17 +33,14 @@ public class SchemaColumnDO {
34 33 /**
35 34 * 是否允许为空
36 35 */
37   - @TableField("case when is_nullable = 'yes' then '1' else '0' end")
38 36 private Boolean nullable;
39 37 /**
40 38 * 是否主键
41 39 */
42   - @TableField("case when column_key = 'PRI' then '1' else '0' end")
43 40 private Boolean primaryKey;
44 41 /**
45 42 * 是否自增
46 43 */
47   - @TableField("case when extra = 'auto_increment' then '1' else '0' end")
48 44 private Boolean autoIncrement;
49 45 /**
50 46 * 排序字段
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/dataobject/codegen/SchemaTableDO.java renamed to yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/dataobject/db/DatabaseTableDO.java
1   -package cn.iocoder.yudao.module.infra.dal.dataobject.codegen;
  1 +package cn.iocoder.yudao.module.infra.dal.dataobject.db;
2 2  
3   -import com.baomidou.mybatisplus.annotation.TableName;
4 3 import lombok.Builder;
5 4 import lombok.Data;
6 5  
... ... @@ -11,16 +10,11 @@ import java.util.Date;
11 10 *
12 11 * @author 芋道源码
13 12 */
14   -@TableName(value = "information_schema.tables", autoResultMap = true)
15 13 @Data
16 14 @Builder
17   -public class SchemaTableDO {
  15 +public class DatabaseTableDO {
18 16  
19 17 /**
20   - * 数据库
21   - */
22   - private String tableSchema;
23   - /**
24 18 * 表名称
25 19 */
26 20 private String tableName;
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/codegen/SchemaColumnMapper.java deleted
1   -package cn.iocoder.yudao.module.infra.dal.mysql.codegen;
2   -
3   -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
4   -import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.SchemaColumnDO;
5   -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
6   -import org.apache.ibatis.annotations.Mapper;
7   -
8   -import java.util.List;
9   -
10   -@Mapper
11   -public interface SchemaColumnMapper extends BaseMapperX<SchemaColumnDO> {
12   -
13   - default List<SchemaColumnDO> selectListByTableName(String tableSchema, String tableName) {
14   - return selectList(new QueryWrapper<SchemaColumnDO>().eq("table_name", tableName)
15   - .eq("table_schema", tableSchema)
16   - .orderByAsc("ordinal_position"));
17   - }
18   -
19   -}
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/codegen/SchemaTableMapper.java deleted
1   -package cn.iocoder.yudao.module.infra.dal.mysql.codegen;
2   -
3   -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
4   -import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
5   -import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.SchemaTableDO;
6   -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
7   -import org.apache.ibatis.annotations.Mapper;
8   -
9   -import java.util.Collection;
10   -import java.util.List;
11   -
12   -@Mapper
13   -public interface SchemaTableMapper extends BaseMapperX<SchemaTableDO> {
14   -
15   - default List<SchemaTableDO> selectList(Collection<String> tableSchemas, String tableName, String tableComment) {
16   - return selectList(new QueryWrapperX<SchemaTableDO>().in("table_schema", tableSchemas)
17   - .likeIfPresent("table_name", tableName)
18   - .likeIfPresent("table_comment", tableComment));
19   - }
20   -
21   - default SchemaTableDO selectByTableSchemaAndTableName(String tableSchema, String tableName) {
22   - return selectOne(new QueryWrapper<SchemaTableDO>().eq("table_schema",tableSchema)
23   - .eq("table_name", tableName));
24   - }
25   -
26   -}
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/db/DatabaseTableDAO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.infra.dal.mysql.db;
  2 +
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.iocoder.yudao.module.infra.dal.dataobject.db.DatabaseColumnDO;
  5 +import cn.iocoder.yudao.module.infra.dal.dataobject.db.DatabaseTableDO;
  6 +import com.baomidou.mybatisplus.annotation.DbType;
  7 +
  8 +import java.sql.Connection;
  9 +import java.util.List;
  10 +
  11 +/**
  12 + * 数据库 Table DAO 接口
  13 + *
  14 + * @author 芋道源码
  15 + */
  16 +public interface DatabaseTableDAO {
  17 +
  18 + /**
  19 + * 获得表列表,基于表名称 + 表描述进行模糊匹配
  20 + *
  21 + * @param connection 数据库连接
  22 + * @param tableNameLike 表名称,模糊匹配
  23 + * @param tableCommentLike 表描述,模糊匹配
  24 + * @return 表列表
  25 + */
  26 + List<DatabaseTableDO> selectTableList(Connection connection, String tableNameLike, String tableCommentLike);
  27 +
  28 + /**
  29 + * 获得指定表名
  30 + *
  31 + * @param connection 数据库连接
  32 + * @param tableName 表名称
  33 + * @return 表
  34 + */
  35 + default DatabaseTableDO selectTable(Connection connection, String tableName) {
  36 + // 考虑到对性能没有要求,直接查询列表,然后内存过滤到记录
  37 + List<DatabaseTableDO> tables = selectTableList(connection, tableName, null);
  38 + return CollUtil.findOne(tables, table -> table.getTableName().equalsIgnoreCase(tableName));
  39 + }
  40 +
  41 + /**
  42 + * 获得指定表的字段列表
  43 + *
  44 + * @param connection 数据库连接
  45 + * @param tableName 表名称
  46 + * @return 字段列表
  47 + */
  48 + List<DatabaseColumnDO> selectColumnList(Connection connection, String tableName);
  49 +
  50 + /**
  51 + * 获得数据库的类型
  52 + *
  53 + * @return 数据库的类型
  54 + */
  55 + DbType getType();
  56 +
  57 +}
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/db/DatabaseTableMySQLDAOImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.infra.dal.mysql.db;
  2 +
  3 +import cn.hutool.core.util.StrUtil;
  4 +import cn.iocoder.yudao.framework.mybatis.core.util.JdbcUtils;
  5 +import cn.iocoder.yudao.module.infra.dal.dataobject.db.DatabaseColumnDO;
  6 +import cn.iocoder.yudao.module.infra.dal.dataobject.db.DatabaseTableDO;
  7 +import com.baomidou.mybatisplus.annotation.DbType;
  8 +import org.springframework.stereotype.Repository;
  9 +
  10 +import java.sql.Connection;
  11 +import java.util.List;
  12 +
  13 +/**
  14 + * {@link DatabaseTableDAO} 的 MySQL 实现类
  15 + *
  16 + * @author 芋道源码
  17 + */
  18 +@Repository
  19 +public class DatabaseTableMySQLDAOImpl implements DatabaseTableDAO {
  20 +
  21 + @Override
  22 + public List<DatabaseTableDO> selectTableList(Connection connection, String tableNameLike, String tableCommentLike) {
  23 + // 拼接 SQL
  24 + String sql = "SELECT table_name, table_comment, create_time" +
  25 + " FROM information_schema.TABLES" +
  26 + " WHERE table_schema = (SELECT DATABASE())";
  27 + if (StrUtil.isNotEmpty(tableNameLike)) {
  28 + sql += StrUtil.format(" AND table_name LIKE '%{}%'", tableNameLike);
  29 + }
  30 + if (StrUtil.isNotEmpty(tableCommentLike)) {
  31 + sql += StrUtil.format(" AND table_comment LIKE '%{}%'", tableCommentLike);
  32 + }
  33 + // 执行并返回结果
  34 + return JdbcUtils.query(connection, sql, (rs, rowNum) -> DatabaseTableDO.builder()
  35 + .tableName(rs.getString("table_name"))
  36 + .tableComment(rs.getString("table_comment"))
  37 + .createTime(rs.getDate("create_time"))
  38 + .build());
  39 + }
  40 +
  41 + @Override
  42 + public List<DatabaseColumnDO> selectColumnList(Connection connection, String tableName) {
  43 + // 拼接 SQL
  44 + String sql = "SELECT table_name, column_name, column_type, column_comment, " +
  45 + " (CASE WHEN is_nullable = 'yes' THEN '1' ELSE '0' END) AS nullable," +
  46 + " (CASE WHEN column_key = 'PRI' THEN '1' ELSE '0' END) AS primary_key," +
  47 + " (CASE WHEN extra = 'auto_increment' THEN '1' ELSE '0' END) AS auto_increment," +
  48 + " ordinal_position" +
  49 + " FROM information_schema.COLUMNS" +
  50 + " WHERE table_schema = (SELECT DATABASE())" +
  51 + String.format(" AND table_name = '%s'", tableName);
  52 + // 执行并返回结果
  53 + return JdbcUtils.query(connection, sql, (rs, rowNum) -> DatabaseColumnDO.builder()
  54 + .tableName(rs.getString("table_name"))
  55 + .columnName(rs.getString("column_name"))
  56 + .columnType(rs.getString("column_type"))
  57 + .columnComment(rs.getString("column_comment"))
  58 + .nullable(rs.getBoolean("nullable"))
  59 + .primaryKey(rs.getBoolean("primary_key"))
  60 + .autoIncrement(rs.getBoolean("auto_increment"))
  61 + .ordinalPosition(rs.getInt("ordinal_position"))
  62 + .build());
  63 + }
  64 +
  65 + @Override
  66 + public DbType getType() {
  67 + return DbType.MYSQL;
  68 + }
  69 +
  70 +}
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/codegen/CodegenService.java
... ... @@ -5,7 +5,7 @@ import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.CodegenUpdateRe
5 5 import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.table.CodegenTablePageReqVO;
6 6 import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenColumnDO;
7 7 import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenTableDO;
8   -import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.SchemaTableDO;
  8 +import cn.iocoder.yudao.module.infra.dal.dataobject.db.DatabaseTableDO;
9 9  
10 10 import java.util.List;
11 11 import java.util.Map;
... ... @@ -119,6 +119,6 @@ public interface CodegenService {
119 119 * @param tableComment 表描述
120 120 * @return 表定义列表
121 121 */
122   - List<SchemaTableDO> getSchemaTableList(String tableName, String tableComment);
  122 + List<DatabaseTableDO> getSchemaTableList(String tableName, String tableComment);
123 123  
124 124 }
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/codegen/CodegenServiceImpl.java
... ... @@ -8,17 +8,16 @@ import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.table.CodegenTa
8 8 import cn.iocoder.yudao.module.infra.convert.codegen.CodegenConvert;
9 9 import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenColumnDO;
10 10 import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenTableDO;
11   -import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.SchemaColumnDO;
12   -import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.SchemaTableDO;
  11 +import cn.iocoder.yudao.module.infra.dal.dataobject.db.DatabaseColumnDO;
  12 +import cn.iocoder.yudao.module.infra.dal.dataobject.db.DatabaseTableDO;
13 13 import cn.iocoder.yudao.module.infra.dal.mysql.codegen.CodegenColumnMapper;
14 14 import cn.iocoder.yudao.module.infra.dal.mysql.codegen.CodegenTableMapper;
15   -import cn.iocoder.yudao.module.infra.dal.mysql.codegen.SchemaColumnMapper;
16   -import cn.iocoder.yudao.module.infra.dal.mysql.codegen.SchemaTableMapper;
17 15 import cn.iocoder.yudao.module.infra.enums.codegen.CodegenImportTypeEnum;
18 16 import cn.iocoder.yudao.module.infra.framework.codegen.config.CodegenProperties;
19 17 import cn.iocoder.yudao.module.infra.service.codegen.inner.CodegenBuilder;
20 18 import cn.iocoder.yudao.module.infra.service.codegen.inner.CodegenEngine;
21 19 import cn.iocoder.yudao.module.infra.service.codegen.inner.CodegenSQLParser;
  20 +import cn.iocoder.yudao.module.infra.service.db.DatabaseTableService;
22 21 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
23 22 import org.apache.commons.collections4.KeyValue;
24 23 import org.springframework.stereotype.Service;
... ... @@ -43,9 +42,8 @@ import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.*;
43 42 public class CodegenServiceImpl implements CodegenService {
44 43  
45 44 @Resource
46   - private SchemaTableMapper schemaTableMapper;
47   - @Resource
48   - private SchemaColumnMapper schemaColumnMapper;
  45 + private DatabaseTableService databaseTableService;
  46 +
49 47 @Resource
50 48 private CodegenTableMapper codegenTableMapper;
51 49 @Resource
... ... @@ -63,7 +61,7 @@ public class CodegenServiceImpl implements CodegenService {
63 61 private CodegenProperties codegenProperties;
64 62  
65 63 private Long createCodegen0(Long userId, CodegenImportTypeEnum importType,
66   - SchemaTableDO schemaTable, List<SchemaColumnDO> schemaColumns) {
  64 + DatabaseTableDO schemaTable, List<DatabaseColumnDO> schemaColumns) {
67 65 // 校验导入的表和字段非空
68 66 if (schemaTable == null) {
69 67 throw exception(CODEGEN_IMPORT_TABLE_NULL);
... ... @@ -90,10 +88,10 @@ public class CodegenServiceImpl implements CodegenService {
90 88 @Override
91 89 public Long createCodegenListFromSQL(Long userId, String sql) {
92 90 // 从 SQL 中,获得数据库表结构
93   - SchemaTableDO schemaTable;
94   - List<SchemaColumnDO> schemaColumns;
  91 + DatabaseTableDO schemaTable;
  92 + List<DatabaseColumnDO> schemaColumns;
95 93 try {
96   - KeyValue<SchemaTableDO, List<SchemaColumnDO>> result = CodegenSQLParser.parse(sql);
  94 + KeyValue<DatabaseTableDO, List<DatabaseColumnDO>> result = CodegenSQLParser.parse(sql);
97 95 schemaTable = result.getKey();
98 96 schemaColumns = result.getValue();
99 97 } catch (Exception ex) {
... ... @@ -108,8 +106,8 @@ public class CodegenServiceImpl implements CodegenService {
108 106 // 获取当前schema
109 107 String tableSchema = codegenProperties.getDbSchemas().iterator().next();
110 108 // 从数据库中,获得数据库表结构
111   - SchemaTableDO schemaTable = schemaTableMapper.selectByTableSchemaAndTableName(tableSchema, tableName);
112   - List<SchemaColumnDO> schemaColumns = schemaColumnMapper.selectListByTableName(tableSchema, tableName);
  109 + DatabaseTableDO schemaTable = databaseTableService.getTable(0L, tableName);
  110 + List<DatabaseColumnDO> schemaColumns = databaseTableService.getColumnList(0L, tableName);
113 111 // 导入
114 112 return this.createCodegen0(userId, CodegenImportTypeEnum.DB, schemaTable, schemaColumns);
115 113 }
... ... @@ -147,9 +145,8 @@ public class CodegenServiceImpl implements CodegenService {
147 145 if (table == null) {
148 146 throw exception(CODEGEN_TABLE_NOT_EXISTS);
149 147 }
150   - String tableSchema = codegenProperties.getDbSchemas().iterator().next();
151 148 // 从数据库中,获得数据库表结构
152   - List<SchemaColumnDO> schemaColumns = schemaColumnMapper.selectListByTableName(tableSchema, table.getTableName());
  149 + List<DatabaseColumnDO> schemaColumns = databaseTableService.getColumnList(0L, table.getTableName());
153 150  
154 151 // 执行同步
155 152 this.syncCodegen0(tableId, schemaColumns);
... ... @@ -164,9 +161,9 @@ public class CodegenServiceImpl implements CodegenService {
164 161 throw exception(CODEGEN_TABLE_NOT_EXISTS);
165 162 }
166 163 // 从 SQL 中,获得数据库表结构
167   - List<SchemaColumnDO> schemaColumns;
  164 + List<DatabaseColumnDO> schemaColumns;
168 165 try {
169   - KeyValue<SchemaTableDO, List<SchemaColumnDO>> result = CodegenSQLParser.parse(sql);
  166 + KeyValue<DatabaseTableDO, List<DatabaseColumnDO>> result = CodegenSQLParser.parse(sql);
170 167 schemaColumns = result.getValue();
171 168 } catch (Exception ex) {
172 169 throw exception(CODEGEN_PARSE_SQL_ERROR);
... ... @@ -176,12 +173,12 @@ public class CodegenServiceImpl implements CodegenService {
176 173 this.syncCodegen0(tableId, schemaColumns);
177 174 }
178 175  
179   - private void syncCodegen0(Long tableId, List<SchemaColumnDO> schemaColumns) {
  176 + private void syncCodegen0(Long tableId, List<DatabaseColumnDO> schemaColumns) {
180 177 // 校验导入的字段不为空
181 178 if (CollUtil.isEmpty(schemaColumns)) {
182 179 throw exception(CODEGEN_SYNC_COLUMNS_NULL);
183 180 }
184   - Set<String> schemaColumnNames = CollectionUtils.convertSet(schemaColumns, SchemaColumnDO::getColumnName);
  181 + Set<String> schemaColumnNames = CollectionUtils.convertSet(schemaColumns, DatabaseColumnDO::getColumnName);
185 182  
186 183 // 构建 CodegenColumnDO 数组,只同步新增的字段
187 184 List<CodegenColumnDO> codegenColumns = codegenColumnMapper.selectListByTableId(tableId);
... ... @@ -255,8 +252,8 @@ public class CodegenServiceImpl implements CodegenService {
255 252 }
256 253  
257 254 @Override
258   - public List<SchemaTableDO> getSchemaTableList(String tableName, String tableComment) {
259   - List<SchemaTableDO> tables = schemaTableMapper.selectList(codegenProperties.getDbSchemas(), tableName, tableComment);
  255 + public List<DatabaseTableDO> getSchemaTableList(String tableName, String tableComment) {
  256 + List<DatabaseTableDO> tables = databaseTableService.getTableList(0L, tableName, tableComment);
260 257 // TODO 强制移除 Quartz 的表,未来做成可配置
261 258 tables.removeIf(table -> table.getTableName().startsWith("QRTZ_"));
262 259 tables.removeIf(table -> table.getTableName().startsWith("ACT_"));
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenBuilder.java
... ... @@ -7,8 +7,8 @@ import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
7 7 import cn.iocoder.yudao.module.infra.convert.codegen.CodegenConvert;
8 8 import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenColumnDO;
9 9 import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenTableDO;
10   -import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.SchemaColumnDO;
11   -import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.SchemaTableDO;
  10 +import cn.iocoder.yudao.module.infra.dal.dataobject.db.DatabaseColumnDO;
  11 +import cn.iocoder.yudao.module.infra.dal.dataobject.db.DatabaseTableDO;
12 12 import cn.iocoder.yudao.module.infra.enums.codegen.CodegenColumnHtmlTypeEnum;
13 13 import cn.iocoder.yudao.module.infra.enums.codegen.CodegenColumnListConditionEnum;
14 14 import cn.iocoder.yudao.module.infra.enums.codegen.CodegenTemplateTypeEnum;
... ... @@ -22,8 +22,8 @@ import static cn.hutool.core.text.CharSequenceUtil.*;
22 22  
23 23 /**
24 24 * 代码生成器的 Builder,负责:
25   - * 1. 将数据库的表 {@link SchemaTableDO} 定义,构建成 {@link CodegenTableDO}
26   - * 2. 将数据库的列 {@link SchemaColumnDO} 构定义,建成 {@link CodegenColumnDO}
  25 + * 1. 将数据库的表 {@link DatabaseTableDO} 定义,构建成 {@link CodegenTableDO}
  26 + * 2. 将数据库的列 {@link DatabaseColumnDO} 构定义,建成 {@link CodegenColumnDO}
27 27 */
28 28 @Component
29 29 public class CodegenBuilder {
... ... @@ -109,7 +109,7 @@ public class CodegenBuilder {
109 109 LIST_OPERATION_RESULT_EXCLUDE_COLUMN.remove("createTime"); // 创建时间,还是需要返回的
110 110 }
111 111  
112   - public CodegenTableDO buildTable(SchemaTableDO schemaTable) {
  112 + public CodegenTableDO buildTable(DatabaseTableDO schemaTable) {
113 113 CodegenTableDO table = CodegenConvert.INSTANCE.convert(schemaTable);
114 114 initTableDefault(table);
115 115 return table;
... ... @@ -133,7 +133,7 @@ public class CodegenBuilder {
133 133 table.setTemplateType(CodegenTemplateTypeEnum.CRUD.getType());
134 134 }
135 135  
136   - public List<CodegenColumnDO> buildColumns(Long tableId, List<SchemaColumnDO> schemaColumns) {
  136 + public List<CodegenColumnDO> buildColumns(Long tableId, List<DatabaseColumnDO> schemaColumns) {
137 137 List<CodegenColumnDO> columns = CodegenConvert.INSTANCE.convertList(schemaColumns);
138 138 for (CodegenColumnDO column : columns) {
139 139 column.setTableId(tableId);
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenSQLParser.java
1 1 package cn.iocoder.yudao.module.infra.service.codegen.inner;
2 2  
3 3 import cn.hutool.core.collection.CollUtil;
4   -import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.SchemaColumnDO;
5   -import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.SchemaTableDO;
  4 +import cn.iocoder.yudao.module.infra.dal.dataobject.db.DatabaseColumnDO;
  5 +import cn.iocoder.yudao.module.infra.dal.dataobject.db.DatabaseTableDO;
6 6 import com.alibaba.druid.DbType;
7 7 import com.alibaba.druid.sql.ast.expr.SQLCharExpr;
8 8 import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition;
... ... @@ -21,7 +21,7 @@ import java.util.Objects;
21 21 import static com.alibaba.druid.sql.SQLUtils.normalize;
22 22  
23 23 /**
24   - * SQL 解析器,将创建表的 SQL,解析成 {@link SchemaTableDO} 和 {@link SchemaColumnDO} 对象,
  24 + * SQL 解析器,将创建表的 SQL,解析成 {@link DatabaseTableDO} 和 {@link DatabaseColumnDO} 对象,
25 25 * 后续可以基于它们,生成代码~
26 26 *
27 27 * @author 芋道源码
... ... @@ -29,18 +29,18 @@ import static com.alibaba.druid.sql.SQLUtils.normalize;
29 29 public class CodegenSQLParser {
30 30  
31 31 /**
32   - * 解析建表 SQL 语句,返回 {@link SchemaTableDO} 和 {@link SchemaColumnDO} 对象
  32 + * 解析建表 SQL 语句,返回 {@link DatabaseTableDO} 和 {@link DatabaseColumnDO} 对象
33 33 *
34 34 * @param sql 建表 SQL 语句
35 35 * @return 解析结果
36 36 */
37   - public static KeyValue<SchemaTableDO, List<SchemaColumnDO>> parse(String sql) {
  37 + public static KeyValue<DatabaseTableDO, List<DatabaseColumnDO>> parse(String sql) {
38 38 // 解析 SQL 成 Statement
39 39 SQLCreateTableStatement statement = parseCreateSQL(sql);
40 40 // 解析 Table 表
41   - SchemaTableDO table = parseTable(statement);
  41 + DatabaseTableDO table = parseTable(statement);
42 42 // 解析 Column 字段
43   - List<SchemaColumnDO> columns = parseColumns(statement);
  43 + List<DatabaseColumnDO> columns = parseColumns(statement);
44 44 columns.forEach(column -> column.setTableName(table.getTableName()));
45 45 // 返回
46 46 return new DefaultKeyValue<>(table, columns);
... ... @@ -61,8 +61,8 @@ public class CodegenSQLParser {
61 61 return (MySqlCreateTableStatement) repository.findTable(tableName).getStatement();
62 62 }
63 63  
64   - private static SchemaTableDO parseTable(SQLCreateTableStatement statement) {
65   - return SchemaTableDO.builder()
  64 + private static DatabaseTableDO parseTable(SQLCreateTableStatement statement) {
  65 + return DatabaseTableDO.builder()
66 66 .tableName(statement.getTableSource().getTableName(true))
67 67 .tableComment(getCommentText(statement))
68 68 .build();
... ... @@ -75,13 +75,13 @@ public class CodegenSQLParser {
75 75 return ((SQLCharExpr) statement.getComment()).getText();
76 76 }
77 77  
78   - private static List<SchemaColumnDO> parseColumns(SQLCreateTableStatement statement) {
79   - List<SchemaColumnDO> columns = new ArrayList<>();
  78 + private static List<DatabaseColumnDO> parseColumns(SQLCreateTableStatement statement) {
  79 + List<DatabaseColumnDO> columns = new ArrayList<>();
80 80 statement.getTableElementList().forEach(element -> parseColumn(columns, element));
81 81 return columns;
82 82 }
83 83  
84   - private static void parseColumn(List<SchemaColumnDO> columns, SQLTableElement element) {
  84 + private static void parseColumn(List<DatabaseColumnDO> columns, SQLTableElement element) {
85 85 // 处理主键
86 86 if (element instanceof SQLPrimaryKey) {
87 87 parsePrimaryKey(columns, (SQLPrimaryKey) element);
... ... @@ -93,16 +93,16 @@ public class CodegenSQLParser {
93 93 }
94 94 }
95 95  
96   - private static void parsePrimaryKey(List<SchemaColumnDO> columns, SQLPrimaryKey primaryKey) {
  96 + private static void parsePrimaryKey(List<DatabaseColumnDO> columns, SQLPrimaryKey primaryKey) {
97 97 String columnName = normalize(primaryKey.getColumns().get(0).toString()); // 暂时不考虑联合主键
98 98 // 匹配 columns 主键字段,设置为 primary
99 99 columns.stream().filter(column -> column.getColumnName().equals(columnName))
100 100 .forEach(column -> column.setPrimaryKey(true));
101 101 }
102 102  
103   - private static void parseColumnDefinition(List<SchemaColumnDO> columns, SQLColumnDefinition definition) {
  103 + private static void parseColumnDefinition(List<DatabaseColumnDO> columns, SQLColumnDefinition definition) {
104 104 String text = definition.toString().toUpperCase();
105   - columns.add(SchemaColumnDO.builder()
  105 + columns.add(DatabaseColumnDO.builder()
106 106 .columnName(normalize(definition.getColumnName()))
107 107 .columnType(definition.getDataType().toString())
108 108 .columnComment(Objects.isNull(definition.getComment()) ? ""
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/db/DataSourceConfigService.java
1 1 package cn.iocoder.yudao.module.infra.service.db;
2 2  
3   -import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 3 import cn.iocoder.yudao.module.infra.controller.admin.db.vo.DataSourceConfigCreateReqVO;
5 4 import cn.iocoder.yudao.module.infra.controller.admin.db.vo.DataSourceConfigUpdateReqVO;
6 5 import cn.iocoder.yudao.module.infra.dal.dataobject.db.DataSourceConfigDO;
7   -import org.w3c.dom.stylesheets.LinkStyle;
  6 +import cn.iocoder.yudao.module.infra.dal.dataobject.db.DatabaseTableDO;
8 7  
9 8 import javax.validation.Valid;
10 9 import java.util.List;
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/db/DataSourceConfigServiceImpl.java
1 1 package cn.iocoder.yudao.module.infra.service.db;
2 2  
3   -import cn.hutool.db.DbUtil;
4   -import cn.iocoder.yudao.framework.common.pojo.PageResult;
5   -import cn.iocoder.yudao.framework.mybatis.core.util.DatabaseUtils;
  3 +import cn.iocoder.yudao.framework.mybatis.core.util.JdbcUtils;
6 4 import cn.iocoder.yudao.module.infra.controller.admin.db.vo.DataSourceConfigCreateReqVO;
7 5 import cn.iocoder.yudao.module.infra.controller.admin.db.vo.DataSourceConfigUpdateReqVO;
8 6 import cn.iocoder.yudao.module.infra.convert.db.DataSourceConfigConvert;
9 7 import cn.iocoder.yudao.module.infra.dal.dataobject.db.DataSourceConfigDO;
10 8 import cn.iocoder.yudao.module.infra.dal.mysql.db.DataSourceConfigMapper;
11   -import com.baomidou.mybatisplus.extension.toolkit.JdbcUtils;
  9 +import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DataSourceProperty;
  10 +import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceProperties;
12 11 import org.jasypt.encryption.StringEncryptor;
13 12 import org.springframework.stereotype.Service;
14 13 import org.springframework.validation.annotation.Validated;
15 14  
16 15 import javax.annotation.Resource;
17 16  
18   -import java.sql.Connection;
19 17 import java.util.List;
  18 +import java.util.Objects;
20 19  
21 20 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
22 21 import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.DATA_SOURCE_CONFIG_NOT_EXISTS;
... ... @@ -37,6 +36,9 @@ public class DataSourceConfigServiceImpl implements DataSourceConfigService {
37 36 @Resource
38 37 private StringEncryptor stringEncryptor;
39 38  
  39 + @Resource
  40 + private DynamicDataSourceProperties dynamicDataSourceProperties;
  41 +
40 42 @Override
41 43 public Long createDataSourceConfig(DataSourceConfigCreateReqVO createReqVO) {
42 44 DataSourceConfigDO dataSourceConfig = DataSourceConfigConvert.INSTANCE.convert(createReqVO);
... ... @@ -77,6 +79,11 @@ public class DataSourceConfigServiceImpl implements DataSourceConfigService {
77 79  
78 80 @Override
79 81 public DataSourceConfigDO getDataSourceConfig(Long id) {
  82 + // 如果 id 为 0,默认为 master 的数据源
  83 + if (Objects.equals(id, DataSourceConfigDO.ID_MASTER)) {
  84 + return buildMasterDataSourceConfig();
  85 + }
  86 + // 从 DB 中读取
80 87 DataSourceConfigDO dataSourceConfig = dataSourceConfigMapper.selectById(id);
81 88 dataSourceConfig.setPassword(stringEncryptor.decrypt(dataSourceConfig.getPassword()));
82 89 return dataSourceConfig;
... ... @@ -84,14 +91,26 @@ public class DataSourceConfigServiceImpl implements DataSourceConfigService {
84 91  
85 92 @Override
86 93 public List<DataSourceConfigDO> getDataSourceConfigList() {
87   - return dataSourceConfigMapper.selectList();
  94 + List<DataSourceConfigDO> result = dataSourceConfigMapper.selectList();
  95 + // 补充 master 数据源
  96 + result.add(0, buildMasterDataSourceConfig());
  97 + return result;
88 98 }
89 99  
90 100 private void checkConnectionOK(DataSourceConfigDO config) {
91   - boolean success = DatabaseUtils.isConnectionOK(config.getUrl(), config.getUsername(), config.getPassword());
  101 + boolean success = JdbcUtils.isConnectionOK(config.getUrl(), config.getUsername(), config.getPassword());
92 102 if (!success) {
93 103 throw exception(DATA_SOURCE_CONFIG_NOT_OK);
94 104 }
95 105 }
96 106  
  107 + private DataSourceConfigDO buildMasterDataSourceConfig() {
  108 + String primary = dynamicDataSourceProperties.getPrimary();
  109 + DataSourceProperty dataSourceProperty = dynamicDataSourceProperties.getDatasource().get(primary);
  110 + return new DataSourceConfigDO().setId(DataSourceConfigDO.ID_MASTER).setName(primary)
  111 + .setUrl(dataSourceProperty.getUrl())
  112 + .setUsername(dataSourceProperty.getUsername())
  113 + .setPassword(dataSourceProperty.getPassword());
  114 + }
  115 +
97 116 }
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/db/DatabaseTableService.java 0 → 100644
  1 +package cn.iocoder.yudao.module.infra.service.db;
  2 +
  3 +import cn.iocoder.yudao.module.infra.dal.dataobject.db.DatabaseColumnDO;
  4 +import cn.iocoder.yudao.module.infra.dal.dataobject.db.DatabaseTableDO;
  5 +
  6 +import java.util.List;
  7 +
  8 +/**
  9 + * 数据库表 Service
  10 + *
  11 + * @author 芋道源码
  12 + */
  13 +public interface DatabaseTableService {
  14 +
  15 + /**
  16 + * 获得表列表,基于表名称 + 表描述进行模糊匹配
  17 + *
  18 + * @param dataSourceConfigId 数据源配置的编号
  19 + * @param tableNameLike 表名称,模糊匹配
  20 + * @param tableCommentLike 表描述,模糊匹配
  21 + * @return 表列表
  22 + */
  23 + List<DatabaseTableDO> getTableList(Long dataSourceConfigId, String tableNameLike, String tableCommentLike);
  24 +
  25 + /**
  26 + * 获得指定表名
  27 + *
  28 + * @param dataSourceConfigId 数据源配置的编号
  29 + * @param tableName 表名称
  30 + * @return 表
  31 + */
  32 + DatabaseTableDO getTable(Long dataSourceConfigId, String tableName);
  33 +
  34 + /**
  35 + * 获得指定表的字段列表
  36 + *
  37 + * @param dataSourceConfigId 数据源配置的编号
  38 + * @param tableName 表名称
  39 + * @return 字段列表
  40 + */
  41 + List<DatabaseColumnDO> getColumnList(Long dataSourceConfigId, String tableName);
  42 +
  43 +}
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/db/DatabaseTableServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.infra.service.db;
  2 +
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.hutool.core.lang.Assert;
  5 +import cn.iocoder.yudao.framework.mybatis.core.util.JdbcUtils;
  6 +import cn.iocoder.yudao.module.infra.dal.dataobject.db.DataSourceConfigDO;
  7 +import cn.iocoder.yudao.module.infra.dal.dataobject.db.DatabaseColumnDO;
  8 +import cn.iocoder.yudao.module.infra.dal.dataobject.db.DatabaseTableDO;
  9 +import cn.iocoder.yudao.module.infra.dal.mysql.db.DatabaseTableDAO;
  10 +import com.baomidou.mybatisplus.annotation.DbType;
  11 +import lombok.SneakyThrows;
  12 +import org.springframework.stereotype.Service;
  13 +
  14 +import javax.annotation.Resource;
  15 +import java.sql.Connection;
  16 +import java.util.List;
  17 +
  18 +/**
  19 + * 数据库表 Service 实现类
  20 + *
  21 + * @author 芋道源码
  22 + */
  23 +@Service
  24 +public class DatabaseTableServiceImpl implements DatabaseTableService {
  25 +
  26 + @Resource
  27 + private DataSourceConfigService dataSourceConfigService;
  28 +
  29 + @Resource
  30 + private List<DatabaseTableDAO> databaseTableDAOs;
  31 +
  32 + @Override
  33 + @SneakyThrows
  34 + public List<DatabaseTableDO> getTableList(Long dataSourceConfigId, String tableNameLike, String tableCommentLike) {
  35 + try (Connection connection = getConnection(dataSourceConfigId)) {
  36 + return getDatabaseTableDAO(dataSourceConfigId).selectTableList(connection, tableNameLike, tableCommentLike);
  37 + }
  38 + }
  39 +
  40 + @Override
  41 + @SneakyThrows
  42 + public DatabaseTableDO getTable(Long dataSourceConfigId, String tableName) {
  43 + try (Connection connection = getConnection(dataSourceConfigId)) {
  44 + return getDatabaseTableDAO(dataSourceConfigId).selectTable(connection, tableName);
  45 + }
  46 + }
  47 +
  48 + @Override
  49 + @SneakyThrows
  50 + public List<DatabaseColumnDO> getColumnList(Long dataSourceConfigId, String tableName) {
  51 + try (Connection connection = getConnection(dataSourceConfigId)) {
  52 + return getDatabaseTableDAO(dataSourceConfigId).selectColumnList(connection, tableName);
  53 + }
  54 + }
  55 +
  56 + private Connection getConnection(Long dataSourceConfigId) {
  57 + DataSourceConfigDO config = dataSourceConfigService.getDataSourceConfig(dataSourceConfigId);
  58 + Assert.notNull(config, "数据源({}) 不存在!", dataSourceConfigId);
  59 + return JdbcUtils.getConnection(config.getUrl(), config.getUsername(), config.getPassword());
  60 + }
  61 +
  62 + private DatabaseTableDAO getDatabaseTableDAO(Long dataSourceConfigId) {
  63 + DataSourceConfigDO config = dataSourceConfigService.getDataSourceConfig(dataSourceConfigId);
  64 + Assert.notNull(config, "数据源({}) 不存在!", dataSourceConfigId);
  65 + // 获得 dbType
  66 + DbType dbType = JdbcUtils.getDbType(config.getUrl());
  67 + Assert.notNull(config, "数据源类型({}) 不存在!", config.getUrl());
  68 + // 获得 DatabaseTableDAO
  69 + DatabaseTableDAO dao = CollUtil.findOne(databaseTableDAOs, databaseTableDAO -> databaseTableDAO.getType().equals(dbType));
  70 + Assert.notNull(dao, "DAO({}) 查找不到实现!", dbType);
  71 + return dao;
  72 + }
  73 +
  74 +}
... ...
yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/db/DataSourceConfigServiceImplTest.java
1 1 package cn.iocoder.yudao.module.infra.service.db;
2 2  
3   -import cn.iocoder.yudao.framework.mybatis.core.util.DatabaseUtils;
  3 +import cn.iocoder.yudao.framework.mybatis.core.util.JdbcUtils;
4 4 import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
5 5 import cn.iocoder.yudao.module.infra.controller.admin.db.vo.DataSourceConfigCreateReqVO;
6 6 import cn.iocoder.yudao.module.infra.controller.admin.db.vo.DataSourceConfigUpdateReqVO;
... ... @@ -41,12 +41,12 @@ public class DataSourceConfigServiceImplTest extends BaseDbUnitTest {
41 41  
42 42 @Test
43 43 public void testCreateDataSourceConfig_success() {
44   - try (MockedStatic<DatabaseUtils> databaseUtilsMock = mockStatic(DatabaseUtils.class)) {
  44 + try (MockedStatic<JdbcUtils> databaseUtilsMock = mockStatic(JdbcUtils.class)) {
45 45 // 准备参数
46 46 DataSourceConfigCreateReqVO reqVO = randomPojo(DataSourceConfigCreateReqVO.class);
47 47 // mock 方法
48 48 when(stringEncryptor.encrypt(eq(reqVO.getPassword()))).thenReturn("123456");
49   - databaseUtilsMock.when(() -> DatabaseUtils.isConnectionOK(eq(reqVO.getUrl()),
  49 + databaseUtilsMock.when(() -> JdbcUtils.isConnectionOK(eq(reqVO.getUrl()),
50 50 eq(reqVO.getUsername()), eq(reqVO.getPassword()))).thenReturn(true);
51 51  
52 52 // 调用
... ... @@ -62,7 +62,7 @@ public class DataSourceConfigServiceImplTest extends BaseDbUnitTest {
62 62  
63 63 @Test
64 64 public void testUpdateDataSourceConfig_success() {
65   - try (MockedStatic<DatabaseUtils> databaseUtilsMock = mockStatic(DatabaseUtils.class)) {
  65 + try (MockedStatic<JdbcUtils> databaseUtilsMock = mockStatic(JdbcUtils.class)) {
66 66 // mock 数据
67 67 DataSourceConfigDO dbDataSourceConfig = randomPojo(DataSourceConfigDO.class);
68 68 dataSourceConfigMapper.insert(dbDataSourceConfig);// @Sql: 先插入出一条存在的数据
... ... @@ -72,7 +72,7 @@ public class DataSourceConfigServiceImplTest extends BaseDbUnitTest {
72 72 });
73 73 // mock 方法
74 74 when(stringEncryptor.encrypt(eq(reqVO.getPassword()))).thenReturn("123456");
75   - databaseUtilsMock.when(() -> DatabaseUtils.isConnectionOK(eq(reqVO.getUrl()),
  75 + databaseUtilsMock.when(() -> JdbcUtils.isConnectionOK(eq(reqVO.getUrl()),
76 76 eq(reqVO.getUsername()), eq(reqVO.getPassword()))).thenReturn(true);
77 77  
78 78 // 调用
... ...