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

pull/2/head
YunaiV 2022-04-28 19:27:59 +08:00
parent d04271b965
commit d79549b48a
21 changed files with 419 additions and 155 deletions

View File

@ -1,29 +0,0 @@
package cn.iocoder.yudao.framework.mybatis.core.util;
import java.sql.Connection;
import java.sql.DriverManager;
/**
*
*
* @author
*/
public class DatabaseUtils {
/**
*
*
* @param url
* @param username
* @param password
* @return
*/
public static boolean isConnectionOK(String url, String username, String password) {
try (Connection ignored = DriverManager.getConnection(url, username, password)) {
return true;
} catch (Exception ex) {
return false;
}
}
}

View File

@ -0,0 +1,85 @@
package cn.iocoder.yudao.framework.mybatis.core.util;
import com.baomidou.mybatisplus.annotation.DbType;
import lombok.SneakyThrows;
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
*
* @author
*/
public class JdbcUtils {
/**
*
*
* @param url
* @param username
* @param password
* @return
*/
public static boolean isConnectionOK(String url, String username, String password) {
try (Connection ignored = DriverManager.getConnection(url, username, password)) {
return true;
} catch (Exception ex) {
return false;
}
}
/**
*
*
* @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);
}
}

View File

@ -13,7 +13,7 @@ import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.table.SchemaTab
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.codegen.SchemaTableDO; 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.collection.CollectionUtils;
import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils; import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;
@ -58,7 +58,7 @@ public class CodegenController {
@RequestParam(value = "tableName", required = false) String tableName, @RequestParam(value = "tableName", required = false) String tableName,
@RequestParam(value = "tableComment", required = false) String tableComment) { @RequestParam(value = "tableComment", required = false) String tableComment) {
// 获得数据库自带的表定义列表 // 获得数据库自带的表定义列表
List<SchemaTableDO> schemaTables = codegenService.getSchemaTableList(tableName, tableComment); List<DatabaseTableDO> schemaTables = codegenService.getSchemaTableList(tableName, tableComment);
// 移除在 Codegen 中,已经存在的 // 移除在 Codegen 中,已经存在的
Set<String> existsTables = CollectionUtils.convertSet(codegenService.getCodeGenTableList(), CodegenTableDO::getTableName); Set<String> existsTables = CollectionUtils.convertSet(codegenService.getCodeGenTableList(), CodegenTableDO::getTableName);
schemaTables.removeIf(table -> existsTables.contains(table.getTableName())); schemaTables.removeIf(table -> existsTables.contains(table.getTableName()));

View File

@ -9,8 +9,8 @@ import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.table.CodegenTa
import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.table.SchemaTableRespVO; import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.table.SchemaTableRespVO;
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.codegen.SchemaColumnDO; import cn.iocoder.yudao.module.infra.dal.dataobject.db.DatabaseColumnDO;
import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.SchemaTableDO; import cn.iocoder.yudao.module.infra.dal.dataobject.db.DatabaseTableDO;
import org.mapstruct.Mapper; import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers; import org.mapstruct.factory.Mappers;
@ -25,11 +25,11 @@ public interface CodegenConvert {
// ========== InformationSchemaTableDO 和 InformationSchemaColumnDO 相关 ========== // ========== InformationSchemaTableDO 和 InformationSchemaColumnDO 相关 ==========
CodegenTableDO convert(SchemaTableDO bean); CodegenTableDO convert(DatabaseTableDO bean);
List<CodegenColumnDO> convertList(List<SchemaColumnDO> list); List<CodegenColumnDO> convertList(List<DatabaseColumnDO> list);
CodegenTableRespVO convert(SchemaColumnDO bean); CodegenTableRespVO convert(DatabaseColumnDO bean);
// ========== CodegenTableDO 相关 ========== // ========== CodegenTableDO 相关 ==========
@ -47,7 +47,7 @@ public interface CodegenConvert {
List<CodegenColumnDO> convertList03(List<CodegenUpdateReqVO.Column> columns); List<CodegenColumnDO> convertList03(List<CodegenUpdateReqVO.Column> columns);
List<SchemaTableRespVO> convertList04(List<SchemaTableDO> list); List<SchemaTableRespVO> convertList04(List<DatabaseTableDO> list);
// ========== 其它 ========== // ========== 其它 ==========

View File

@ -74,7 +74,6 @@ public class CodegenColumnDO extends BaseDO {
/** /**
* Java * Java
*/ */
// @NotBlank(message = "Java属性不能为空")
private String javaField; private String javaField;
/** /**
* *

View File

@ -13,6 +13,11 @@ import lombok.Data;
@Data @Data
public class DataSourceConfigDO extends BaseDO { public class DataSourceConfigDO extends BaseDO {
/**
* - Master
*/
public static final Long ID_MASTER = 0L;
/** /**
* *
*/ */

View File

@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.infra.dal.dataobject.codegen; package cn.iocoder.yudao.module.infra.dal.dataobject.db;
import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
@ -10,10 +10,9 @@ import lombok.Data;
* *
* @author * @author
*/ */
@TableName(value = "information_schema.columns", autoResultMap = true)
@Data @Data
@Builder @Builder
public class SchemaColumnDO { public class DatabaseColumnDO {
/** /**
* *
@ -34,17 +33,14 @@ public class SchemaColumnDO {
/** /**
* *
*/ */
@TableField("case when is_nullable = 'yes' then '1' else '0' end")
private Boolean nullable; private Boolean nullable;
/** /**
* *
*/ */
@TableField("case when column_key = 'PRI' then '1' else '0' end")
private Boolean primaryKey; private Boolean primaryKey;
/** /**
* *
*/ */
@TableField("case when extra = 'auto_increment' then '1' else '0' end")
private Boolean autoIncrement; private Boolean autoIncrement;
/** /**
* *

View File

@ -1,6 +1,5 @@
package cn.iocoder.yudao.module.infra.dal.dataobject.codegen; package cn.iocoder.yudao.module.infra.dal.dataobject.db;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;
@ -11,15 +10,10 @@ import java.util.Date;
* *
* @author * @author
*/ */
@TableName(value = "information_schema.tables", autoResultMap = true)
@Data @Data
@Builder @Builder
public class SchemaTableDO { public class DatabaseTableDO {
/**
*
*/
private String tableSchema;
/** /**
* *
*/ */

View File

@ -1,19 +0,0 @@
package cn.iocoder.yudao.module.infra.dal.mysql.codegen;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.SchemaColumnDO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface SchemaColumnMapper extends BaseMapperX<SchemaColumnDO> {
default List<SchemaColumnDO> selectListByTableName(String tableSchema, String tableName) {
return selectList(new QueryWrapper<SchemaColumnDO>().eq("table_name", tableName)
.eq("table_schema", tableSchema)
.orderByAsc("ordinal_position"));
}
}

View File

@ -1,26 +0,0 @@
package cn.iocoder.yudao.module.infra.dal.mysql.codegen;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.SchemaTableDO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.apache.ibatis.annotations.Mapper;
import java.util.Collection;
import java.util.List;
@Mapper
public interface SchemaTableMapper extends BaseMapperX<SchemaTableDO> {
default List<SchemaTableDO> selectList(Collection<String> tableSchemas, String tableName, String tableComment) {
return selectList(new QueryWrapperX<SchemaTableDO>().in("table_schema", tableSchemas)
.likeIfPresent("table_name", tableName)
.likeIfPresent("table_comment", tableComment));
}
default SchemaTableDO selectByTableSchemaAndTableName(String tableSchema, String tableName) {
return selectOne(new QueryWrapper<SchemaTableDO>().eq("table_schema",tableSchema)
.eq("table_name", tableName));
}
}

View File

@ -0,0 +1,57 @@
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();
}

View File

@ -0,0 +1,70 @@
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, column_type, column_comment, " +
" (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," +
" ordinal_position" +
" 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"))
.columnType(rs.getString("column_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;
}
}

View File

@ -5,7 +5,7 @@ import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.CodegenUpdateRe
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.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.codegen.SchemaTableDO; 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;
@ -119,6 +119,6 @@ public interface CodegenService {
* @param tableComment * @param tableComment
* @return * @return
*/ */
List<SchemaTableDO> getSchemaTableList(String tableName, String tableComment); List<DatabaseTableDO> getSchemaTableList(String tableName, String tableComment);
} }

View File

@ -8,17 +8,16 @@ import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.table.CodegenTa
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.codegen.SchemaColumnDO; import cn.iocoder.yudao.module.infra.dal.dataobject.db.DatabaseColumnDO;
import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.SchemaTableDO; 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.dal.mysql.codegen.SchemaColumnMapper;
import cn.iocoder.yudao.module.infra.dal.mysql.codegen.SchemaTableMapper;
import cn.iocoder.yudao.module.infra.enums.codegen.CodegenImportTypeEnum; import cn.iocoder.yudao.module.infra.enums.codegen.CodegenImportTypeEnum;
import cn.iocoder.yudao.module.infra.framework.codegen.config.CodegenProperties; import cn.iocoder.yudao.module.infra.framework.codegen.config.CodegenProperties;
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.codegen.inner.CodegenSQLParser;
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 org.apache.commons.collections4.KeyValue;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -43,9 +42,8 @@ import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.*;
public class CodegenServiceImpl implements CodegenService { public class CodegenServiceImpl implements CodegenService {
@Resource @Resource
private SchemaTableMapper schemaTableMapper; private DatabaseTableService databaseTableService;
@Resource
private SchemaColumnMapper schemaColumnMapper;
@Resource @Resource
private CodegenTableMapper codegenTableMapper; private CodegenTableMapper codegenTableMapper;
@Resource @Resource
@ -63,7 +61,7 @@ public class CodegenServiceImpl implements CodegenService {
private CodegenProperties codegenProperties; private CodegenProperties codegenProperties;
private Long createCodegen0(Long userId, CodegenImportTypeEnum importType, private Long createCodegen0(Long userId, CodegenImportTypeEnum importType,
SchemaTableDO schemaTable, List<SchemaColumnDO> schemaColumns) { DatabaseTableDO schemaTable, List<DatabaseColumnDO> schemaColumns) {
// 校验导入的表和字段非空 // 校验导入的表和字段非空
if (schemaTable == null) { if (schemaTable == null) {
throw exception(CODEGEN_IMPORT_TABLE_NULL); throw exception(CODEGEN_IMPORT_TABLE_NULL);
@ -90,10 +88,10 @@ public class CodegenServiceImpl implements CodegenService {
@Override @Override
public Long createCodegenListFromSQL(Long userId, String sql) { public Long createCodegenListFromSQL(Long userId, String sql) {
// 从 SQL 中,获得数据库表结构 // 从 SQL 中,获得数据库表结构
SchemaTableDO schemaTable; DatabaseTableDO schemaTable;
List<SchemaColumnDO> schemaColumns; List<DatabaseColumnDO> schemaColumns;
try { try {
KeyValue<SchemaTableDO, List<SchemaColumnDO>> result = CodegenSQLParser.parse(sql); KeyValue<DatabaseTableDO, List<DatabaseColumnDO>> result = CodegenSQLParser.parse(sql);
schemaTable = result.getKey(); schemaTable = result.getKey();
schemaColumns = result.getValue(); schemaColumns = result.getValue();
} catch (Exception ex) { } catch (Exception ex) {
@ -108,8 +106,8 @@ public class CodegenServiceImpl implements CodegenService {
// 获取当前schema // 获取当前schema
String tableSchema = codegenProperties.getDbSchemas().iterator().next(); String tableSchema = codegenProperties.getDbSchemas().iterator().next();
// 从数据库中,获得数据库表结构 // 从数据库中,获得数据库表结构
SchemaTableDO schemaTable = schemaTableMapper.selectByTableSchemaAndTableName(tableSchema, tableName); DatabaseTableDO schemaTable = databaseTableService.getTable(0L, tableName);
List<SchemaColumnDO> schemaColumns = schemaColumnMapper.selectListByTableName(tableSchema, tableName); List<DatabaseColumnDO> schemaColumns = databaseTableService.getColumnList(0L, tableName);
// 导入 // 导入
return this.createCodegen0(userId, CodegenImportTypeEnum.DB, schemaTable, schemaColumns); return this.createCodegen0(userId, CodegenImportTypeEnum.DB, schemaTable, schemaColumns);
} }
@ -147,9 +145,8 @@ public class CodegenServiceImpl implements CodegenService {
if (table == null) { if (table == null) {
throw exception(CODEGEN_TABLE_NOT_EXISTS); throw exception(CODEGEN_TABLE_NOT_EXISTS);
} }
String tableSchema = codegenProperties.getDbSchemas().iterator().next();
// 从数据库中,获得数据库表结构 // 从数据库中,获得数据库表结构
List<SchemaColumnDO> schemaColumns = schemaColumnMapper.selectListByTableName(tableSchema, table.getTableName()); List<DatabaseColumnDO> schemaColumns = databaseTableService.getColumnList(0L, table.getTableName());
// 执行同步 // 执行同步
this.syncCodegen0(tableId, schemaColumns); this.syncCodegen0(tableId, schemaColumns);
@ -164,9 +161,9 @@ public class CodegenServiceImpl implements CodegenService {
throw exception(CODEGEN_TABLE_NOT_EXISTS); throw exception(CODEGEN_TABLE_NOT_EXISTS);
} }
// 从 SQL 中,获得数据库表结构 // 从 SQL 中,获得数据库表结构
List<SchemaColumnDO> schemaColumns; List<DatabaseColumnDO> schemaColumns;
try { try {
KeyValue<SchemaTableDO, List<SchemaColumnDO>> result = CodegenSQLParser.parse(sql); KeyValue<DatabaseTableDO, List<DatabaseColumnDO>> result = CodegenSQLParser.parse(sql);
schemaColumns = result.getValue(); schemaColumns = result.getValue();
} catch (Exception ex) { } catch (Exception ex) {
throw exception(CODEGEN_PARSE_SQL_ERROR); throw exception(CODEGEN_PARSE_SQL_ERROR);
@ -176,12 +173,12 @@ public class CodegenServiceImpl implements CodegenService {
this.syncCodegen0(tableId, schemaColumns); this.syncCodegen0(tableId, schemaColumns);
} }
private void syncCodegen0(Long tableId, List<SchemaColumnDO> schemaColumns) { private void syncCodegen0(Long tableId, List<DatabaseColumnDO> schemaColumns) {
// 校验导入的字段不为空 // 校验导入的字段不为空
if (CollUtil.isEmpty(schemaColumns)) { if (CollUtil.isEmpty(schemaColumns)) {
throw exception(CODEGEN_SYNC_COLUMNS_NULL); throw exception(CODEGEN_SYNC_COLUMNS_NULL);
} }
Set<String> schemaColumnNames = CollectionUtils.convertSet(schemaColumns, SchemaColumnDO::getColumnName); Set<String> schemaColumnNames = CollectionUtils.convertSet(schemaColumns, DatabaseColumnDO::getColumnName);
// 构建 CodegenColumnDO 数组,只同步新增的字段 // 构建 CodegenColumnDO 数组,只同步新增的字段
List<CodegenColumnDO> codegenColumns = codegenColumnMapper.selectListByTableId(tableId); List<CodegenColumnDO> codegenColumns = codegenColumnMapper.selectListByTableId(tableId);
@ -255,8 +252,8 @@ public class CodegenServiceImpl implements CodegenService {
} }
@Override @Override
public List<SchemaTableDO> getSchemaTableList(String tableName, String tableComment) { public List<DatabaseTableDO> getSchemaTableList(String tableName, String tableComment) {
List<SchemaTableDO> tables = schemaTableMapper.selectList(codegenProperties.getDbSchemas(), tableName, tableComment); List<DatabaseTableDO> tables = databaseTableService.getTableList(0L, tableName, tableComment);
// TODO 强制移除 Quartz 的表,未来做成可配置 // TODO 强制移除 Quartz 的表,未来做成可配置
tables.removeIf(table -> table.getTableName().startsWith("QRTZ_")); tables.removeIf(table -> table.getTableName().startsWith("QRTZ_"));
tables.removeIf(table -> table.getTableName().startsWith("ACT_")); tables.removeIf(table -> table.getTableName().startsWith("ACT_"));

View File

@ -7,8 +7,8 @@ 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.codegen.SchemaColumnDO; import cn.iocoder.yudao.module.infra.dal.dataobject.db.DatabaseColumnDO;
import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.SchemaTableDO; 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;
@ -22,8 +22,8 @@ import static cn.hutool.core.text.CharSequenceUtil.*;
/** /**
* Builder * Builder
* 1. {@link SchemaTableDO} {@link CodegenTableDO} * 1. {@link DatabaseTableDO} {@link CodegenTableDO}
* 2. {@link SchemaColumnDO} {@link CodegenColumnDO} * 2. {@link DatabaseColumnDO} {@link CodegenColumnDO}
*/ */
@Component @Component
public class CodegenBuilder { public class CodegenBuilder {
@ -109,7 +109,7 @@ public class CodegenBuilder {
LIST_OPERATION_RESULT_EXCLUDE_COLUMN.remove("createTime"); // 创建时间,还是需要返回的 LIST_OPERATION_RESULT_EXCLUDE_COLUMN.remove("createTime"); // 创建时间,还是需要返回的
} }
public CodegenTableDO buildTable(SchemaTableDO schemaTable) { public CodegenTableDO buildTable(DatabaseTableDO schemaTable) {
CodegenTableDO table = CodegenConvert.INSTANCE.convert(schemaTable); CodegenTableDO table = CodegenConvert.INSTANCE.convert(schemaTable);
initTableDefault(table); initTableDefault(table);
return table; return table;
@ -133,7 +133,7 @@ public class CodegenBuilder {
table.setTemplateType(CodegenTemplateTypeEnum.CRUD.getType()); table.setTemplateType(CodegenTemplateTypeEnum.CRUD.getType());
} }
public List<CodegenColumnDO> buildColumns(Long tableId, List<SchemaColumnDO> schemaColumns) { public List<CodegenColumnDO> buildColumns(Long tableId, List<DatabaseColumnDO> schemaColumns) {
List<CodegenColumnDO> columns = CodegenConvert.INSTANCE.convertList(schemaColumns); List<CodegenColumnDO> columns = CodegenConvert.INSTANCE.convertList(schemaColumns);
for (CodegenColumnDO column : columns) { for (CodegenColumnDO column : columns) {
column.setTableId(tableId); column.setTableId(tableId);

View File

@ -1,8 +1,8 @@
package cn.iocoder.yudao.module.infra.service.codegen.inner; package cn.iocoder.yudao.module.infra.service.codegen.inner;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.SchemaColumnDO; import cn.iocoder.yudao.module.infra.dal.dataobject.db.DatabaseColumnDO;
import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.SchemaTableDO; import cn.iocoder.yudao.module.infra.dal.dataobject.db.DatabaseTableDO;
import com.alibaba.druid.DbType; import com.alibaba.druid.DbType;
import com.alibaba.druid.sql.ast.expr.SQLCharExpr; import com.alibaba.druid.sql.ast.expr.SQLCharExpr;
import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition; import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition;
@ -21,7 +21,7 @@ import java.util.Objects;
import static com.alibaba.druid.sql.SQLUtils.normalize; import static com.alibaba.druid.sql.SQLUtils.normalize;
/** /**
* SQL SQL {@link SchemaTableDO} {@link SchemaColumnDO} * SQL SQL {@link DatabaseTableDO} {@link DatabaseColumnDO}
* ~ * ~
* *
* @author * @author
@ -29,18 +29,18 @@ import static com.alibaba.druid.sql.SQLUtils.normalize;
public class CodegenSQLParser { public class CodegenSQLParser {
/** /**
* SQL {@link SchemaTableDO} {@link SchemaColumnDO} * SQL {@link DatabaseTableDO} {@link DatabaseColumnDO}
* *
* @param sql SQL * @param sql SQL
* @return * @return
*/ */
public static KeyValue<SchemaTableDO, List<SchemaColumnDO>> parse(String sql) { public static KeyValue<DatabaseTableDO, List<DatabaseColumnDO>> parse(String sql) {
// 解析 SQL 成 Statement // 解析 SQL 成 Statement
SQLCreateTableStatement statement = parseCreateSQL(sql); SQLCreateTableStatement statement = parseCreateSQL(sql);
// 解析 Table 表 // 解析 Table 表
SchemaTableDO table = parseTable(statement); DatabaseTableDO table = parseTable(statement);
// 解析 Column 字段 // 解析 Column 字段
List<SchemaColumnDO> columns = parseColumns(statement); List<DatabaseColumnDO> columns = parseColumns(statement);
columns.forEach(column -> column.setTableName(table.getTableName())); columns.forEach(column -> column.setTableName(table.getTableName()));
// 返回 // 返回
return new DefaultKeyValue<>(table, columns); return new DefaultKeyValue<>(table, columns);
@ -61,8 +61,8 @@ public class CodegenSQLParser {
return (MySqlCreateTableStatement) repository.findTable(tableName).getStatement(); return (MySqlCreateTableStatement) repository.findTable(tableName).getStatement();
} }
private static SchemaTableDO parseTable(SQLCreateTableStatement statement) { private static DatabaseTableDO parseTable(SQLCreateTableStatement statement) {
return SchemaTableDO.builder() return DatabaseTableDO.builder()
.tableName(statement.getTableSource().getTableName(true)) .tableName(statement.getTableSource().getTableName(true))
.tableComment(getCommentText(statement)) .tableComment(getCommentText(statement))
.build(); .build();
@ -75,13 +75,13 @@ public class CodegenSQLParser {
return ((SQLCharExpr) statement.getComment()).getText(); return ((SQLCharExpr) statement.getComment()).getText();
} }
private static List<SchemaColumnDO> parseColumns(SQLCreateTableStatement statement) { private static List<DatabaseColumnDO> parseColumns(SQLCreateTableStatement statement) {
List<SchemaColumnDO> columns = new ArrayList<>(); List<DatabaseColumnDO> columns = new ArrayList<>();
statement.getTableElementList().forEach(element -> parseColumn(columns, element)); statement.getTableElementList().forEach(element -> parseColumn(columns, element));
return columns; return columns;
} }
private static void parseColumn(List<SchemaColumnDO> columns, SQLTableElement element) { private static void parseColumn(List<DatabaseColumnDO> columns, SQLTableElement element) {
// 处理主键 // 处理主键
if (element instanceof SQLPrimaryKey) { if (element instanceof SQLPrimaryKey) {
parsePrimaryKey(columns, (SQLPrimaryKey) element); parsePrimaryKey(columns, (SQLPrimaryKey) element);
@ -93,16 +93,16 @@ public class CodegenSQLParser {
} }
} }
private static void parsePrimaryKey(List<SchemaColumnDO> columns, SQLPrimaryKey primaryKey) { private static void parsePrimaryKey(List<DatabaseColumnDO> columns, SQLPrimaryKey primaryKey) {
String columnName = normalize(primaryKey.getColumns().get(0).toString()); // 暂时不考虑联合主键 String columnName = normalize(primaryKey.getColumns().get(0).toString()); // 暂时不考虑联合主键
// 匹配 columns 主键字段,设置为 primary // 匹配 columns 主键字段,设置为 primary
columns.stream().filter(column -> column.getColumnName().equals(columnName)) columns.stream().filter(column -> column.getColumnName().equals(columnName))
.forEach(column -> column.setPrimaryKey(true)); .forEach(column -> column.setPrimaryKey(true));
} }
private static void parseColumnDefinition(List<SchemaColumnDO> columns, SQLColumnDefinition definition) { private static void parseColumnDefinition(List<DatabaseColumnDO> columns, SQLColumnDefinition definition) {
String text = definition.toString().toUpperCase(); String text = definition.toString().toUpperCase();
columns.add(SchemaColumnDO.builder() columns.add(DatabaseColumnDO.builder()
.columnName(normalize(definition.getColumnName())) .columnName(normalize(definition.getColumnName()))
.columnType(definition.getDataType().toString()) .columnType(definition.getDataType().toString())
.columnComment(Objects.isNull(definition.getComment()) ? "" .columnComment(Objects.isNull(definition.getComment()) ? ""

View File

@ -1,10 +1,9 @@
package cn.iocoder.yudao.module.infra.service.db; package cn.iocoder.yudao.module.infra.service.db;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
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 org.w3c.dom.stylesheets.LinkStyle; 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;

View File

@ -1,22 +1,21 @@
package cn.iocoder.yudao.module.infra.service.db; package cn.iocoder.yudao.module.infra.service.db;
import cn.hutool.db.DbUtil; import cn.iocoder.yudao.framework.mybatis.core.util.JdbcUtils;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.util.DatabaseUtils;
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.convert.db.DataSourceConfigConvert; import cn.iocoder.yudao.module.infra.convert.db.DataSourceConfigConvert;
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.mysql.db.DataSourceConfigMapper; import cn.iocoder.yudao.module.infra.dal.mysql.db.DataSourceConfigMapper;
import com.baomidou.mybatisplus.extension.toolkit.JdbcUtils; import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DataSourceProperty;
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceProperties;
import org.jasypt.encryption.StringEncryptor; import org.jasypt.encryption.StringEncryptor;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.sql.Connection;
import java.util.List; import java.util.List;
import java.util.Objects;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.DATA_SOURCE_CONFIG_NOT_EXISTS; import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.DATA_SOURCE_CONFIG_NOT_EXISTS;
@ -37,6 +36,9 @@ public class DataSourceConfigServiceImpl implements DataSourceConfigService {
@Resource @Resource
private StringEncryptor stringEncryptor; private StringEncryptor stringEncryptor;
@Resource
private DynamicDataSourceProperties dynamicDataSourceProperties;
@Override @Override
public Long createDataSourceConfig(DataSourceConfigCreateReqVO createReqVO) { public Long createDataSourceConfig(DataSourceConfigCreateReqVO createReqVO) {
DataSourceConfigDO dataSourceConfig = DataSourceConfigConvert.INSTANCE.convert(createReqVO); DataSourceConfigDO dataSourceConfig = DataSourceConfigConvert.INSTANCE.convert(createReqVO);
@ -77,6 +79,11 @@ public class DataSourceConfigServiceImpl implements DataSourceConfigService {
@Override @Override
public DataSourceConfigDO getDataSourceConfig(Long id) { public DataSourceConfigDO getDataSourceConfig(Long id) {
// 如果 id 为 0默认为 master 的数据源
if (Objects.equals(id, DataSourceConfigDO.ID_MASTER)) {
return buildMasterDataSourceConfig();
}
// 从 DB 中读取
DataSourceConfigDO dataSourceConfig = dataSourceConfigMapper.selectById(id); DataSourceConfigDO dataSourceConfig = dataSourceConfigMapper.selectById(id);
dataSourceConfig.setPassword(stringEncryptor.decrypt(dataSourceConfig.getPassword())); dataSourceConfig.setPassword(stringEncryptor.decrypt(dataSourceConfig.getPassword()));
return dataSourceConfig; return dataSourceConfig;
@ -84,14 +91,26 @@ public class DataSourceConfigServiceImpl implements DataSourceConfigService {
@Override @Override
public List<DataSourceConfigDO> getDataSourceConfigList() { public List<DataSourceConfigDO> getDataSourceConfigList() {
return dataSourceConfigMapper.selectList(); List<DataSourceConfigDO> result = dataSourceConfigMapper.selectList();
// 补充 master 数据源
result.add(0, buildMasterDataSourceConfig());
return result;
} }
private void checkConnectionOK(DataSourceConfigDO config) { private void checkConnectionOK(DataSourceConfigDO config) {
boolean success = DatabaseUtils.isConnectionOK(config.getUrl(), config.getUsername(), config.getPassword()); boolean success = JdbcUtils.isConnectionOK(config.getUrl(), config.getUsername(), config.getPassword());
if (!success) { if (!success) {
throw exception(DATA_SOURCE_CONFIG_NOT_OK); throw exception(DATA_SOURCE_CONFIG_NOT_OK);
} }
} }
private DataSourceConfigDO buildMasterDataSourceConfig() {
String primary = dynamicDataSourceProperties.getPrimary();
DataSourceProperty dataSourceProperty = dynamicDataSourceProperties.getDatasource().get(primary);
return new DataSourceConfigDO().setId(DataSourceConfigDO.ID_MASTER).setName(primary)
.setUrl(dataSourceProperty.getUrl())
.setUsername(dataSourceProperty.getUsername())
.setPassword(dataSourceProperty.getPassword());
}
} }

View File

@ -0,0 +1,43 @@
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 java.util.List;
/**
* Service
*
* @author
*/
public interface DatabaseTableService {
/**
* +
*
* @param dataSourceConfigId
* @param tableNameLike
* @param tableCommentLike
* @return
*/
List<DatabaseTableDO> getTableList(Long dataSourceConfigId, String tableNameLike, String tableCommentLike);
/**
*
*
* @param dataSourceConfigId
* @param tableName
* @return
*/
DatabaseTableDO getTable(Long dataSourceConfigId, String tableName);
/**
*
*
* @param dataSourceConfigId
* @param tableName
* @return
*/
List<DatabaseColumnDO> getColumnList(Long dataSourceConfigId, String tableName);
}

View File

@ -0,0 +1,74 @@
package cn.iocoder.yudao.module.infra.service.db;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import cn.iocoder.yudao.framework.mybatis.core.util.JdbcUtils;
import cn.iocoder.yudao.module.infra.dal.dataobject.db.DataSourceConfigDO;
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.db.DatabaseTableDAO;
import com.baomidou.mybatisplus.annotation.DbType;
import lombok.SneakyThrows;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.sql.Connection;
import java.util.List;
/**
* Service
*
* @author
*/
@Service
public class DatabaseTableServiceImpl implements DatabaseTableService {
@Resource
private DataSourceConfigService dataSourceConfigService;
@Resource
private List<DatabaseTableDAO> databaseTableDAOs;
@Override
@SneakyThrows
public List<DatabaseTableDO> getTableList(Long dataSourceConfigId, String tableNameLike, String tableCommentLike) {
try (Connection connection = getConnection(dataSourceConfigId)) {
return getDatabaseTableDAO(dataSourceConfigId).selectTableList(connection, tableNameLike, tableCommentLike);
}
}
@Override
@SneakyThrows
public DatabaseTableDO getTable(Long dataSourceConfigId, String tableName) {
try (Connection connection = getConnection(dataSourceConfigId)) {
return getDatabaseTableDAO(dataSourceConfigId).selectTable(connection, tableName);
}
}
@Override
@SneakyThrows
public List<DatabaseColumnDO> getColumnList(Long dataSourceConfigId, String tableName) {
try (Connection connection = getConnection(dataSourceConfigId)) {
return getDatabaseTableDAO(dataSourceConfigId).selectColumnList(connection, tableName);
}
}
private Connection getConnection(Long dataSourceConfigId) {
DataSourceConfigDO config = dataSourceConfigService.getDataSourceConfig(dataSourceConfigId);
Assert.notNull(config, "数据源({}) 不存在!", dataSourceConfigId);
return JdbcUtils.getConnection(config.getUrl(), config.getUsername(), config.getPassword());
}
private DatabaseTableDAO getDatabaseTableDAO(Long dataSourceConfigId) {
DataSourceConfigDO config = dataSourceConfigService.getDataSourceConfig(dataSourceConfigId);
Assert.notNull(config, "数据源({}) 不存在!", dataSourceConfigId);
// 获得 dbType
DbType dbType = JdbcUtils.getDbType(config.getUrl());
Assert.notNull(config, "数据源类型({}) 不存在!", config.getUrl());
// 获得 DatabaseTableDAO
DatabaseTableDAO dao = CollUtil.findOne(databaseTableDAOs, databaseTableDAO -> databaseTableDAO.getType().equals(dbType));
Assert.notNull(dao, "DAO({}) 查找不到实现!", dbType);
return dao;
}
}

View File

@ -1,6 +1,6 @@
package cn.iocoder.yudao.module.infra.service.db; package cn.iocoder.yudao.module.infra.service.db;
import cn.iocoder.yudao.framework.mybatis.core.util.DatabaseUtils; import cn.iocoder.yudao.framework.mybatis.core.util.JdbcUtils;
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
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;
@ -41,12 +41,12 @@ public class DataSourceConfigServiceImplTest extends BaseDbUnitTest {
@Test @Test
public void testCreateDataSourceConfig_success() { public void testCreateDataSourceConfig_success() {
try (MockedStatic<DatabaseUtils> databaseUtilsMock = mockStatic(DatabaseUtils.class)) { try (MockedStatic<JdbcUtils> databaseUtilsMock = mockStatic(JdbcUtils.class)) {
// 准备参数 // 准备参数
DataSourceConfigCreateReqVO reqVO = randomPojo(DataSourceConfigCreateReqVO.class); DataSourceConfigCreateReqVO reqVO = randomPojo(DataSourceConfigCreateReqVO.class);
// mock 方法 // mock 方法
when(stringEncryptor.encrypt(eq(reqVO.getPassword()))).thenReturn("123456"); when(stringEncryptor.encrypt(eq(reqVO.getPassword()))).thenReturn("123456");
databaseUtilsMock.when(() -> DatabaseUtils.isConnectionOK(eq(reqVO.getUrl()), databaseUtilsMock.when(() -> JdbcUtils.isConnectionOK(eq(reqVO.getUrl()),
eq(reqVO.getUsername()), eq(reqVO.getPassword()))).thenReturn(true); eq(reqVO.getUsername()), eq(reqVO.getPassword()))).thenReturn(true);
// 调用 // 调用
@ -62,7 +62,7 @@ public class DataSourceConfigServiceImplTest extends BaseDbUnitTest {
@Test @Test
public void testUpdateDataSourceConfig_success() { public void testUpdateDataSourceConfig_success() {
try (MockedStatic<DatabaseUtils> databaseUtilsMock = mockStatic(DatabaseUtils.class)) { try (MockedStatic<JdbcUtils> databaseUtilsMock = mockStatic(JdbcUtils.class)) {
// mock 数据 // mock 数据
DataSourceConfigDO dbDataSourceConfig = randomPojo(DataSourceConfigDO.class); DataSourceConfigDO dbDataSourceConfig = randomPojo(DataSourceConfigDO.class);
dataSourceConfigMapper.insert(dbDataSourceConfig);// @Sql: 先插入出一条存在的数据 dataSourceConfigMapper.insert(dbDataSourceConfig);// @Sql: 先插入出一条存在的数据
@ -72,7 +72,7 @@ public class DataSourceConfigServiceImplTest extends BaseDbUnitTest {
}); });
// mock 方法 // mock 方法
when(stringEncryptor.encrypt(eq(reqVO.getPassword()))).thenReturn("123456"); when(stringEncryptor.encrypt(eq(reqVO.getPassword()))).thenReturn("123456");
databaseUtilsMock.when(() -> DatabaseUtils.isConnectionOK(eq(reqVO.getUrl()), databaseUtilsMock.when(() -> JdbcUtils.isConnectionOK(eq(reqVO.getUrl()),
eq(reqVO.getUsername()), eq(reqVO.getPassword()))).thenReturn(true); eq(reqVO.getUsername()), eq(reqVO.getPassword()))).thenReturn(true);
// 调用 // 调用