💩 改进异常处理体系
This commit is contained in:
parent
74ff03182e
commit
2e714dc080
|
@ -0,0 +1,26 @@
|
|||
package cn.bunny.core.dialect;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 数据库方言
|
||||
*/
|
||||
public interface DatabaseDialect {
|
||||
|
||||
/**
|
||||
* 提取表注释
|
||||
*
|
||||
* @param tableOptions 选项
|
||||
* @return 注释信息
|
||||
*/
|
||||
String extractTableComment(String tableOptions);
|
||||
|
||||
/**
|
||||
* 提取列注释
|
||||
*
|
||||
* @param columnSpecs 列规格
|
||||
* @return 注释信息
|
||||
*/
|
||||
String extractColumnComment(List<String> columnSpecs);
|
||||
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
package cn.bunny.core.dialect;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@Component
|
||||
public class MySqlDialect implements DatabaseDialect {
|
||||
|
||||
/**
|
||||
* 提取表注释
|
||||
*
|
||||
* @param tableOptions 选项
|
||||
* @return 注释信息
|
||||
*/
|
||||
@Override
|
||||
public String extractTableComment(String tableOptions) {
|
||||
Pattern pattern = Pattern.compile("COMMENT\\s*=\\s*'(.*?)'", Pattern.CASE_INSENSITIVE);
|
||||
Matcher matcher = pattern.matcher(tableOptions);
|
||||
return matcher.find() ? matcher.group(1) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 提取列注释
|
||||
*
|
||||
* @param columnSpecs 列规格
|
||||
* @return 注释信息
|
||||
*/
|
||||
@Override
|
||||
public String extractColumnComment(List<String> columnSpecs) {
|
||||
String columnSpecsString = String.join(" ", columnSpecs);
|
||||
Matcher columnSpecsStringMatcher = Pattern.compile("COMMENT\\s*'(.*?)'", Pattern.CASE_INSENSITIVE).matcher(columnSpecsString);
|
||||
return columnSpecsStringMatcher.find() ? columnSpecsStringMatcher.group(1) : null;
|
||||
}
|
||||
}
|
|
@ -4,7 +4,9 @@ import cn.bunny.domain.entity.ColumnMetaData;
|
|||
import cn.bunny.domain.entity.DatabaseInfoMetaData;
|
||||
import cn.bunny.domain.entity.TableMetaData;
|
||||
import cn.bunny.exception.GeneratorCodeException;
|
||||
import cn.bunny.utils.TypeConvertUtil;
|
||||
import cn.bunny.exception.MetadataNotFoundException;
|
||||
import cn.bunny.exception.MetadataProviderException;
|
||||
import cn.bunny.utils.MysqlTypeConvertUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
|
@ -109,7 +111,7 @@ public class DatabaseMetadataProvider implements IMetadataProvider {
|
|||
.tableType(tableType)
|
||||
.build();
|
||||
} else {
|
||||
throw new RuntimeException("数据表不存在");
|
||||
throw new MetadataNotFoundException("Table not found: " + identifier);
|
||||
}
|
||||
|
||||
return tableMetaData;
|
||||
|
@ -124,26 +126,29 @@ public class DatabaseMetadataProvider implements IMetadataProvider {
|
|||
* @return 所有表信息
|
||||
*/
|
||||
public List<TableMetaData> getTableMetadataBatch(String dbName) {
|
||||
// 当前数据库数据库所有的表
|
||||
List<TableMetaData> allTableInfo = new ArrayList<>();
|
||||
|
||||
try (Connection conn = dataSource.getConnection()) {
|
||||
DatabaseMetaData metaData = conn.getMetaData();
|
||||
|
||||
// 当前数据库中所有的表
|
||||
ResultSet tables = metaData.getTables(dbName, null, "%", new String[]{"TABLE"});
|
||||
|
||||
while (tables.next()) {
|
||||
// 表名称
|
||||
dbName = tables.getString("TABLE_NAME");
|
||||
String tableName = tables.getString("TABLE_NAME");
|
||||
String remarks = tables.getString("REMARKS");
|
||||
String tableCat = tables.getString("TABLE_CAT");
|
||||
String tableType = tables.getString("TABLE_TYPE");
|
||||
|
||||
// 设置表信息
|
||||
TableMetaData tableMetaData = getTableMetadata(dbName);
|
||||
TableMetaData tableMetaData = TableMetaData.builder()
|
||||
.tableName(tableName)
|
||||
.comment(remarks)
|
||||
.tableCat(tableCat)
|
||||
.tableType(tableType)
|
||||
.build();
|
||||
|
||||
allTableInfo.add(tableMetaData);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new GeneratorCodeException("Get error of [current/all] database tables" + e.getMessage());
|
||||
throw new MetadataProviderException("Failed to get batch table metadata", e);
|
||||
}
|
||||
|
||||
return allTableInfo;
|
||||
|
@ -175,13 +180,13 @@ public class DatabaseMetadataProvider implements IMetadataProvider {
|
|||
// 设置列字段
|
||||
column.setColumnName(columnName);
|
||||
// 列字段转成 下划线 -> 小驼峰
|
||||
column.setLowercaseName(TypeConvertUtil.convertToCamelCase(column.getColumnName()));
|
||||
column.setLowercaseName(MysqlTypeConvertUtil.convertToCamelCase(column.getColumnName()));
|
||||
// 列字段转成 下划线 -> 大驼峰名称
|
||||
column.setUppercaseName(TypeConvertUtil.convertToCamelCase(column.getColumnName(), true));
|
||||
column.setUppercaseName(MysqlTypeConvertUtil.convertToCamelCase(column.getColumnName(), true));
|
||||
// 字段类型
|
||||
column.setJdbcType(typeName);
|
||||
// 字段类型转 Java 类型
|
||||
String javaType = TypeConvertUtil.convertToJavaType(typeName);
|
||||
String javaType = MysqlTypeConvertUtil.convertToJavaType(typeName);
|
||||
column.setJavaType(javaType);
|
||||
// 字段类型转 JavaScript 类型
|
||||
column.setJavascriptType(StringUtils.uncapitalize(javaType));
|
||||
|
@ -201,7 +206,7 @@ public class DatabaseMetadataProvider implements IMetadataProvider {
|
|||
|
||||
return new ArrayList<>(map.values());
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Get error of database columns mete data" + e.getMessage());
|
||||
throw new MetadataProviderException("Failed to get table metadata for: " + identifier, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
package cn.bunny.core.factory;
|
||||
|
||||
import cn.bunny.core.dialect.DatabaseDialect;
|
||||
import cn.bunny.domain.entity.ColumnMetaData;
|
||||
import cn.bunny.domain.entity.TableMetaData;
|
||||
import cn.bunny.exception.GeneratorCodeException;
|
||||
import cn.bunny.utils.TypeConvertUtil;
|
||||
import cn.bunny.exception.SqlParseException;
|
||||
import cn.bunny.utils.MysqlTypeConvertUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import net.sf.jsqlparser.JSQLParserException;
|
||||
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
|
||||
import net.sf.jsqlparser.statement.Statement;
|
||||
|
@ -12,12 +15,13 @@ import org.apache.commons.lang3.StringUtils;
|
|||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class SqlMetadataProvider implements IMetadataProvider {
|
||||
|
||||
private final DatabaseDialect dialect;
|
||||
|
||||
/**
|
||||
* 解析 sql 表信息
|
||||
* 先解析SQL语句,解析列字段信息
|
||||
|
@ -49,11 +53,8 @@ public class SqlMetadataProvider implements IMetadataProvider {
|
|||
String tableOptionsStrings = String.join(" ", createTable.getTableOptionsStrings());
|
||||
|
||||
// 注释信息
|
||||
Pattern pattern = Pattern.compile("COMMENT\\s*=\\s*'(.*?)'", Pattern.CASE_INSENSITIVE);
|
||||
Matcher matcher = pattern.matcher(tableOptionsStrings);
|
||||
if (matcher.find()) {
|
||||
tableInfo.setComment(matcher.group(1));
|
||||
}
|
||||
String comment = dialect.extractTableComment(tableOptionsStrings);
|
||||
tableInfo.setComment(comment);
|
||||
|
||||
return tableInfo;
|
||||
}
|
||||
|
@ -71,11 +72,11 @@ public class SqlMetadataProvider implements IMetadataProvider {
|
|||
try {
|
||||
statement = CCJSqlParserUtil.parse(identifier);
|
||||
} catch (JSQLParserException e) {
|
||||
throw new RuntimeException("SQL解析失败");
|
||||
throw new SqlParseException("Fail parse sql", e.getCause());
|
||||
}
|
||||
|
||||
if (!(statement instanceof CreateTable createTable)) {
|
||||
throw new IllegalArgumentException("缺少SQL语句");
|
||||
throw new IllegalArgumentException("Lack of Sql Statement");
|
||||
}
|
||||
|
||||
return createTable.getColumnDefinitions()
|
||||
|
@ -91,24 +92,23 @@ public class SqlMetadataProvider implements IMetadataProvider {
|
|||
columnInfo.setJdbcType(dataType);
|
||||
|
||||
// 设置 Java 类型
|
||||
String javaType = TypeConvertUtil.convertToJavaType(dataType.contains("varchar") ? "varchar" : dataType);
|
||||
String javaType = MysqlTypeConvertUtil.convertToJavaType(dataType.contains("varchar") ? "varchar" : dataType);
|
||||
columnInfo.setJavaType(javaType);
|
||||
|
||||
// 设置 JavaScript 类型
|
||||
columnInfo.setJavascriptType(StringUtils.uncapitalize(javaType));
|
||||
|
||||
// 列字段转成 下划线 -> 小驼峰
|
||||
columnInfo.setLowercaseName(TypeConvertUtil.convertToCamelCase(column.getColumnName()));
|
||||
columnInfo.setLowercaseName(MysqlTypeConvertUtil.convertToCamelCase(column.getColumnName()));
|
||||
// 列字段转成 下划线 -> 大驼峰名称
|
||||
columnInfo.setUppercaseName(TypeConvertUtil.convertToCamelCase(column.getColumnName(), true));
|
||||
columnInfo.setUppercaseName(MysqlTypeConvertUtil.convertToCamelCase(column.getColumnName(), true));
|
||||
|
||||
// 解析注释
|
||||
List<String> columnSpecs = column.getColumnSpecs();
|
||||
String columnSpecsString = String.join(" ", columnSpecs);
|
||||
Matcher columnSpecsStringMatcher = Pattern.compile("COMMENT\\s*'(.*?)'", Pattern.CASE_INSENSITIVE).matcher(columnSpecsString);
|
||||
if (columnSpecsStringMatcher.find()) {
|
||||
columnInfo.setComment(columnSpecsStringMatcher.group(1));
|
||||
}
|
||||
|
||||
// 设置列属性信息
|
||||
String comment = dialect.extractColumnComment(columnSpecs);
|
||||
columnInfo.setComment(comment);
|
||||
|
||||
return columnInfo;
|
||||
}).toList();
|
||||
|
|
|
@ -2,7 +2,7 @@ package cn.bunny.core.template;
|
|||
|
||||
import cn.bunny.domain.dto.VmsArgumentDto;
|
||||
import cn.bunny.domain.entity.TableMetaData;
|
||||
import cn.bunny.utils.TypeConvertUtil;
|
||||
import cn.bunny.utils.MysqlTypeConvertUtil;
|
||||
import org.apache.velocity.Template;
|
||||
import org.apache.velocity.VelocityContext;
|
||||
import org.apache.velocity.app.Velocity;
|
||||
|
@ -61,11 +61,11 @@ public class VmsTemplateGenerator extends AbstractTemplateGenerator {
|
|||
context.put("package", dto.getPackageName());
|
||||
|
||||
// 将类名称转成小驼峰
|
||||
String toCamelCase = TypeConvertUtil.convertToCamelCase(tableName);
|
||||
String toCamelCase = MysqlTypeConvertUtil.convertToCamelCase(tableName);
|
||||
context.put("classLowercaseName", toCamelCase);
|
||||
|
||||
// 将类名称转成大驼峰
|
||||
String convertToCamelCase = TypeConvertUtil.convertToCamelCase(tableName, true);
|
||||
String convertToCamelCase = MysqlTypeConvertUtil.convertToCamelCase(tableName, true);
|
||||
context.put("classUppercaseName", convertToCamelCase);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
package cn.bunny.exception;
|
||||
|
||||
public class MetadataNotFoundException extends RuntimeException {
|
||||
public MetadataNotFoundException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
package cn.bunny.exception;
|
||||
|
||||
public class MetadataProviderException extends RuntimeException {
|
||||
public MetadataProviderException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
package cn.bunny.exception;
|
||||
|
||||
public class SqlParseException extends MetadataProviderException {
|
||||
public SqlParseException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
|
@ -32,36 +32,47 @@ public class VmsCodeGeneratorService {
|
|||
* 根据DTO生成代码模板
|
||||
*
|
||||
* @param dto 包含生成参数的数据传输对象
|
||||
* @return 生成的代码模板列表
|
||||
* @return 按表名分组的生成的代码模板列表
|
||||
*/
|
||||
public Map<String, List<GeneratorVo>> generateCode(VmsArgumentDto dto) {
|
||||
String sql = dto.getSql();
|
||||
// 提前获取可复用的数据
|
||||
final String sql = dto.getSql();
|
||||
final List<String> tableNames = dto.getTableNames();
|
||||
final List<String> paths = dto.getPath();
|
||||
|
||||
return dto.getTableNames().stream()
|
||||
return tableNames.parallelStream() // 使用并行流提高多表处理效率
|
||||
.map(tableName -> {
|
||||
// 获取表元数据和列信息
|
||||
TableMetaData tableMetaData = getTableMetadata(dto, tableName);
|
||||
List<ColumnMetaData> columnInfoList = getColumnInfoList(sql, tableName);
|
||||
|
||||
return dto.getPath().stream()
|
||||
.map(path -> {
|
||||
VmsTemplateGenerator generator = new VmsTemplateGenerator(dto, path, tableMetaData);
|
||||
StringWriter writer = generator.generatorCodeTemplate(tableMetaData, columnInfoList);
|
||||
String processedPath = VmsUtil.handleVmFilename(path, tableMetaData.getTableName());
|
||||
|
||||
return GeneratorVo.builder()
|
||||
.id(UUID.randomUUID().toString())
|
||||
.code(writer.toString())
|
||||
.comment(tableMetaData.getComment())
|
||||
.tableName(tableMetaData.getTableName())
|
||||
.path(processedPath)
|
||||
.build();
|
||||
})
|
||||
// 为每个路径生成模板
|
||||
return paths.stream()
|
||||
.map(path -> generateTemplate(dto, path, tableMetaData, columnInfoList))
|
||||
.toList();
|
||||
})
|
||||
.flatMap(List::stream)
|
||||
.collect(Collectors.groupingBy(GeneratorVo::getTableName));
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成单个模板
|
||||
*/
|
||||
private GeneratorVo generateTemplate(VmsArgumentDto dto, String path,
|
||||
TableMetaData tableMetaData, List<ColumnMetaData> columnInfoList) {
|
||||
VmsTemplateGenerator generator = new VmsTemplateGenerator(dto, path, tableMetaData);
|
||||
StringWriter writer = generator.generatorCodeTemplate(tableMetaData, columnInfoList);
|
||||
String processedPath = VmsUtil.handleVmFilename(path, tableMetaData.getTableName());
|
||||
|
||||
return GeneratorVo.builder()
|
||||
.id(UUID.randomUUID().toString())
|
||||
.code(writer.toString())
|
||||
.comment(tableMetaData.getComment())
|
||||
.tableName(tableMetaData.getTableName())
|
||||
.path(processedPath)
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取表元数据
|
||||
*
|
||||
|
|
|
@ -4,8 +4,8 @@ import com.google.common.base.CaseFormat;
|
|||
import org.assertj.core.util.introspection.CaseFormatUtils;
|
||||
|
||||
/* 类型转换,数据库转Java类型等 */
|
||||
public class TypeConvertUtil {
|
||||
|
||||
public class MysqlTypeConvertUtil {
|
||||
|
||||
/**
|
||||
* 将数据库类型转换为Java类型
|
||||
*/
|
|
@ -28,9 +28,9 @@ public class VmsUtil {
|
|||
int splitPathsSize = splitPaths.length - 1;
|
||||
|
||||
// 大驼峰名称
|
||||
String CamelCase = TypeConvertUtil.convertToCamelCase(className, true);
|
||||
String CamelCase = MysqlTypeConvertUtil.convertToCamelCase(className, true);
|
||||
// 小驼峰名称
|
||||
String camelCase = TypeConvertUtil.convertToCamelCase(className);
|
||||
String camelCase = MysqlTypeConvertUtil.convertToCamelCase(className);
|
||||
|
||||
// 当前文件名
|
||||
String filename = splitPaths[splitPathsSize];
|
||||
|
|
|
@ -1,98 +0,0 @@
|
|||
package cn.bunny;
|
||||
|
||||
|
||||
import cn.bunny.domain.entity.ColumnMetaData;
|
||||
import cn.bunny.domain.entity.TableMetaData;
|
||||
import cn.bunny.utils.TypeConvertUtil;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.sql.Connection;
|
||||
import java.sql.DatabaseMetaData;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@SpringBootTest
|
||||
public class JDBCTest {
|
||||
|
||||
private final DataSource dataSource;
|
||||
DatabaseMetaData metaData;
|
||||
|
||||
public JDBCTest(DataSource dataSource) {
|
||||
this.dataSource = dataSource;
|
||||
}
|
||||
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() throws Exception {
|
||||
try (Connection connection = dataSource.getConnection()) {
|
||||
metaData = connection.getMetaData();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testComment() throws SQLException {
|
||||
String tableName = "sys_i18n";
|
||||
TableMetaData tableMetaData;
|
||||
ResultSet tables = metaData.getTables(null, null, tableName, new String[]{"TABLE"});
|
||||
|
||||
// 获取表的注释信息
|
||||
if (tables.next()) {
|
||||
String remarks = tables.getString("REMARKS");
|
||||
String tableCat = tables.getString("TABLE_CAT");
|
||||
|
||||
tableMetaData = TableMetaData.builder()
|
||||
.tableName(tableName)
|
||||
.comment(remarks)
|
||||
.tableCat(tableCat)
|
||||
.build();
|
||||
|
||||
System.out.println(tableMetaData);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAllTableComment() throws SQLException {
|
||||
ResultSet tables = metaData.getTables(null, null, "%", new String[]{"TABLE"});
|
||||
List<TableMetaData> list = new ArrayList<>();
|
||||
|
||||
while (tables.next()) {
|
||||
String tableName = tables.getString("TABLE_NAME");
|
||||
String remarks = tables.getString("REMARKS");
|
||||
String tableCat = tables.getString("TABLE_CAT");
|
||||
|
||||
TableMetaData tableMetaData = TableMetaData.builder()
|
||||
.tableName(tableName).comment(remarks)
|
||||
.tableCat(tableCat)
|
||||
.build();
|
||||
list.add(tableMetaData);
|
||||
}
|
||||
|
||||
System.out.println(list);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testColumnInfo() throws SQLException {
|
||||
List<ColumnMetaData> columns = new ArrayList<>();
|
||||
|
||||
try (ResultSet columnsRs = metaData.getColumns(null, null, "sys_i18n", null)) {
|
||||
while (columnsRs.next()) {
|
||||
ColumnMetaData column = new ColumnMetaData();
|
||||
column.setColumnName(columnsRs.getString("COLUMN_NAME"));
|
||||
column.setLowercaseName(TypeConvertUtil.convertToCamelCase(column.getColumnName()));
|
||||
column.setJdbcType(columnsRs.getString("TYPE_NAME"));
|
||||
column.setJavaType(TypeConvertUtil.convertToJavaType(column.getJdbcType()));
|
||||
column.setComment(columnsRs.getString("REMARKS"));
|
||||
|
||||
columns.add(column);
|
||||
System.out.println(column);
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println(columns);
|
||||
}
|
||||
}
|
|
@ -1,105 +0,0 @@
|
|||
package cn.bunny;
|
||||
|
||||
import cn.bunny.domain.entity.ColumnMetaData;
|
||||
import cn.bunny.domain.entity.TableMetaData;
|
||||
import cn.bunny.utils.TypeConvertUtil;
|
||||
import net.sf.jsqlparser.JSQLParserException;
|
||||
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
|
||||
import net.sf.jsqlparser.statement.Statement;
|
||||
import net.sf.jsqlparser.statement.create.table.CreateTable;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class SqlParserTest {
|
||||
|
||||
@Test
|
||||
public void test() throws JSQLParserException {
|
||||
String sql = """
|
||||
CREATE TABLE `sys_files` (
|
||||
`id` bigint NOT NULL COMMENT '文件的唯一标识符,自动递增',
|
||||
`filename` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '文件的名称',
|
||||
`filepath` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '文件在服务器上的存储路径',
|
||||
`file_size` int NOT NULL COMMENT '文件的大小,以字节为单位',
|
||||
`file_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '文件的MIME类型',
|
||||
`download_count` int NULL DEFAULT 0 COMMENT '下载数量',
|
||||
`create_user` bigint NOT NULL COMMENT '创建用户',
|
||||
`update_user` bigint NULL DEFAULT NULL COMMENT '操作用户',
|
||||
`create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '记录文件最后修改的时间戳',
|
||||
`is_deleted` tinyint(1) UNSIGNED ZEROFILL NOT NULL DEFAULT 0 COMMENT '文件是否被删除',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
INDEX `idx_filename`(`filename` ASC) USING BTREE COMMENT '索引文件名',
|
||||
INDEX `idx_filepath`(`filepath` ASC) USING BTREE COMMENT '索引文件路径',
|
||||
INDEX `idx_file_type`(`file_type` ASC) USING BTREE COMMENT '索引文件类型',
|
||||
INDEX `idx_update_user`(`update_user` ASC) USING BTREE COMMENT '索引创更新用户',
|
||||
INDEX `idx_create_user`(`create_user` ASC) USING BTREE COMMENT '索引创建用户',
|
||||
INDEX `idx_user`(`update_user` ASC, `create_user` ASC) USING BTREE COMMENT '索引创建用户和更新用户',
|
||||
INDEX `idx_time`(`update_time` ASC, `create_time` ASC) USING BTREE COMMENT '索引创建时间和更新时间'
|
||||
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '系统文件表' ROW_FORMAT = DYNAMIC;
|
||||
""";
|
||||
|
||||
TableMetaData tableInfo = new TableMetaData();
|
||||
|
||||
// 解析sql
|
||||
Statement statement = CCJSqlParserUtil.parse(sql);
|
||||
if (!(statement instanceof CreateTable createTable)) {
|
||||
throw new IllegalArgumentException("Not a CREATE TABLE statement");
|
||||
}
|
||||
|
||||
// 设置表基本信息
|
||||
tableInfo.setTableName(createTable.getTable().getName());
|
||||
tableInfo.setTableType("TABLE");
|
||||
String tableOptionsStrings = String.join(" ", createTable.getTableOptionsStrings());
|
||||
|
||||
// 注释信息
|
||||
Pattern pattern = Pattern.compile("COMMENT\\s*=\\s*'(.*?)'", Pattern.CASE_INSENSITIVE);
|
||||
Matcher matcher = pattern.matcher(tableOptionsStrings);
|
||||
if (matcher.find()) {
|
||||
tableInfo.setComment(matcher.group(1));
|
||||
}
|
||||
|
||||
// 解析列信息
|
||||
List<ColumnMetaData> columnMetaData = createTable.getColumnDefinitions()
|
||||
.stream().map(column -> {
|
||||
// 列信息
|
||||
ColumnMetaData columnInfo = new ColumnMetaData();
|
||||
|
||||
// 列名称
|
||||
columnInfo.setColumnName(column.getColumnName());
|
||||
|
||||
// 设置 JDBC 类型
|
||||
String dataType = column.getColDataType().getDataType();
|
||||
columnInfo.setJdbcType(dataType);
|
||||
|
||||
// 设置 Java 类型
|
||||
String javaType = TypeConvertUtil.convertToJavaType(dataType.contains("varchar") ? "varchar" : dataType);
|
||||
columnInfo.setJavaType(javaType);
|
||||
|
||||
// 设置 JavaScript 类型
|
||||
columnInfo.setJavascriptType(StringUtils.uncapitalize(javaType));
|
||||
|
||||
// 列字段转成 下划线 -> 小驼峰
|
||||
columnInfo.setLowercaseName(TypeConvertUtil.convertToCamelCase(column.getColumnName()));
|
||||
// 列字段转成 下划线 -> 大驼峰名称
|
||||
columnInfo.setUppercaseName(TypeConvertUtil.convertToCamelCase(column.getColumnName(), true));
|
||||
|
||||
// 解析注释
|
||||
List<String> columnSpecs = column.getColumnSpecs();
|
||||
String columnSpecsString = String.join(" ", columnSpecs);
|
||||
Matcher columnSpecsStringMatcher = Pattern.compile("COMMENT\\s*'(.*?)'", Pattern.CASE_INSENSITIVE).matcher(columnSpecsString);
|
||||
if (columnSpecsStringMatcher.find()) {
|
||||
columnInfo.setComment(columnSpecsStringMatcher.group(1));
|
||||
}
|
||||
|
||||
return columnInfo;
|
||||
}).toList();
|
||||
|
||||
System.out.println(tableInfo);
|
||||
System.out.println("----------------------------------------------------------------------------------------");
|
||||
System.out.println(columnMetaData);
|
||||
}
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
package cn.bunny;
|
||||
|
||||
import cn.bunny.utils.TypeConvertUtil;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.assertj.core.util.introspection.CaseFormatUtils;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class StringFormatTest {
|
||||
|
||||
@Test
|
||||
void test1() {
|
||||
System.out.println(CaseFormatUtils.toCamelCase("user_login"));
|
||||
System.out.println(CaseFormatUtils.toCamelCase("userLogin"));
|
||||
System.out.println(CaseFormatUtils.toCamelCase("UserLogin"));
|
||||
|
||||
System.out.println("--------------------------------");
|
||||
|
||||
System.out.println(StringUtils.lowerCase("user_login"));
|
||||
System.out.println(StringUtils.lowerCase("userLogin"));
|
||||
System.out.println(StringUtils.lowerCase("UserLogin"));
|
||||
|
||||
System.out.println("--------------------------------");
|
||||
|
||||
System.out.println(StringUtils.upperCase("user_login"));
|
||||
System.out.println(StringUtils.upperCase("userLogin"));
|
||||
System.out.println(StringUtils.upperCase("UserLogin"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void test2() {
|
||||
System.out.println(TypeConvertUtil.convertToCamelCase("user_login_A"));
|
||||
System.out.println(TypeConvertUtil.convertToCamelCase("User_Login_A"));
|
||||
System.out.println(TypeConvertUtil.convertToCamelCase("userLoginA"));
|
||||
System.out.println(TypeConvertUtil.convertToCamelCase("UserLoginA"));
|
||||
|
||||
System.out.println("--------------------------------");
|
||||
|
||||
System.out.println(TypeConvertUtil.convertToCamelCase("i18n_type_A", true));
|
||||
System.out.println(TypeConvertUtil.convertToCamelCase("User_Login_A", true));
|
||||
System.out.println(TypeConvertUtil.convertToCamelCase("userLoginA", true));
|
||||
System.out.println(TypeConvertUtil.convertToCamelCase("UserLoginA", true));
|
||||
}
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
package cn.bunny;
|
||||
|
||||
import cn.hutool.crypto.digest.MD5;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class TimeTest {
|
||||
@Test
|
||||
void timeTest() {
|
||||
long currentTimeMillis = System.currentTimeMillis();
|
||||
String digestHex = MD5.create().digestHex(currentTimeMillis + "");
|
||||
System.out.println(currentTimeMillis);
|
||||
System.out.println(digestHex);
|
||||
}
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
package cn.bunny.service.impl;
|
||||
|
||||
import cn.bunny.domain.vo.VmsPathVo;
|
||||
import cn.bunny.utils.ResourceFileUtil;
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
class VmsServiceImplTest {
|
||||
|
||||
|
||||
@Test
|
||||
void vmsResourcePathList() throws IOException, URISyntaxException {
|
||||
List<String> vmsFiles = ResourceFileUtil.getAbsoluteFiles("vms");
|
||||
System.out.println(vmsFiles);
|
||||
|
||||
System.out.println("--------------------------------------------------------------");
|
||||
|
||||
List<String> vmsRelativeFiles = ResourceFileUtil.getRelativeFiles("vms");
|
||||
System.out.println(vmsRelativeFiles);
|
||||
|
||||
System.out.println("--------------------------集合对象模式------------------------------------");
|
||||
|
||||
Map<String, List<VmsPathVo>> map = vmsRelativeFiles.stream().map(vmFile -> {
|
||||
String[] filepathList = vmFile.split("/");
|
||||
String filename = filepathList[filepathList.length - 1].replace(".vm", "");
|
||||
|
||||
return VmsPathVo.builder().name(vmFile).label(filename).type(filepathList[0]).build();
|
||||
}).collect(Collectors.groupingBy(VmsPathVo::getType));
|
||||
|
||||
System.out.println(JSON.toJSONString(map));
|
||||
|
||||
System.out.println("----------------------------二维数组格式----------------------------------");
|
||||
List<List<VmsPathVo>> listMap = vmsRelativeFiles.stream().map(vmFile -> {
|
||||
String[] filepathList = vmFile.split("/");
|
||||
String filename = filepathList[filepathList.length - 1].replace(".vm", "");
|
||||
|
||||
return VmsPathVo.builder().name(vmFile).label(filename).type(filepathList[0]).build();
|
||||
})
|
||||
.collect(Collectors.groupingBy(VmsPathVo::getType))
|
||||
.values().stream().toList();
|
||||
|
||||
System.out.println(JSON.toJSONString(listMap));
|
||||
}
|
||||
}
|
|
@ -1,75 +0,0 @@
|
|||
package cn.bunny.utils;
|
||||
|
||||
import cn.bunny.domain.entity.TableMetaData;
|
||||
import lombok.SneakyThrows;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.sql.Connection;
|
||||
import java.sql.DatabaseMetaData;
|
||||
import java.sql.ResultSet;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@SpringBootTest
|
||||
class DatabaseMetadataProviderCoreTest {
|
||||
|
||||
String tableName = "sys_i18n";
|
||||
|
||||
@Autowired
|
||||
private DataSource dataSource;
|
||||
|
||||
|
||||
@Test
|
||||
void testTableInfoMetaData() {
|
||||
TableMetaData tableMetaData;
|
||||
|
||||
try (Connection connection = dataSource.getConnection()) {
|
||||
DatabaseMetaData metaData = connection.getMetaData();
|
||||
ResultSet tables = metaData.getTables(null, null, tableName, new String[]{"TABLE"});
|
||||
|
||||
// 获取表的注释信息
|
||||
if (tables.next()) {
|
||||
String remarks = tables.getString("REMARKS");
|
||||
String tableCat = tables.getString("TABLE_CAT");
|
||||
String tableType = tables.getString("TABLE_TYPE");
|
||||
|
||||
tableMetaData = TableMetaData.builder()
|
||||
.tableName(tableName)
|
||||
.comment(remarks)
|
||||
.tableCat(tableCat)
|
||||
.tableType(tableType)
|
||||
.build();
|
||||
} else {
|
||||
throw new RuntimeException("数据表不存在");
|
||||
}
|
||||
|
||||
System.out.println(tableMetaData);
|
||||
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
@Test
|
||||
void getDbTableList() {
|
||||
String dbName = "auth_admin";
|
||||
|
||||
try (Connection connection = dataSource.getConnection()) {
|
||||
DatabaseMetaData metaData = connection.getMetaData();
|
||||
ResultSet tables = metaData.getTables(dbName, null, "%", new String[]{"TABLE"});
|
||||
|
||||
List<String> list = new ArrayList<>();
|
||||
|
||||
while (tables.next()) {
|
||||
dbName = tables.getString("TABLE_NAME");
|
||||
list.add(dbName);
|
||||
}
|
||||
|
||||
System.out.println(list);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue