Skip to content

Commit 81e7551

Browse files
committed
Merge remote-tracking branch 'origin/main'
2 parents 72a6103 + 385790f commit 81e7551

19 files changed

+711
-153
lines changed
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package com.tml.otowbackend.engine.sql;
2+
3+
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
4+
import com.tml.otowbackend.engine.ai.result.EntityClassDefinition;
5+
import lombok.Getter;
6+
import lombok.Setter;
7+
8+
import java.util.ArrayList;
9+
import java.util.List;
10+
11+
@Setter
12+
@Getter
13+
public class EntityInfo {
14+
private String tableName; // 表名
15+
private String tableComment; // 表注释
16+
private List<FieldInfo> fields; // 字段信息列表
17+
18+
public EntityInfo(String tableName, String tableComment, List<FieldInfo> fields) {
19+
this.tableName = tableName;
20+
this.tableComment = tableComment;
21+
this.fields = fields;
22+
}
23+
24+
public static List<EntityInfo> buildEntityInfoList(List<EntityClassDefinition> entityClassDefinitions) {
25+
List<EntityInfo> entityInfos = new ArrayList<>();
26+
for (EntityClassDefinition definition : entityClassDefinitions) {
27+
entityInfos.add(EntityInfo.buildByEntityClassDefinition(definition));
28+
}
29+
return entityInfos;
30+
}
31+
32+
public static EntityInfo buildByEntityClassDefinition(EntityClassDefinition classDefinition) {
33+
// 表名:将类名转换为下划线命名
34+
String tableName = StringUtils.camelToUnderline(classDefinition.getClassName());
35+
36+
// 表注释:使用实体类的中文描述
37+
String tableComment = classDefinition.getCdesc();
38+
39+
// 字段信息列表
40+
List<FieldInfo> fieldInfos = new ArrayList<>();
41+
42+
for (EntityClassDefinition.FieldDefinition fieldDefinition : classDefinition.getFields()) {
43+
String fname = fieldDefinition.getFname(); // 字段名
44+
String ftype = fieldDefinition.getFtype(); // 字段类型
45+
String fdesc = fieldDefinition.getFdesc(); // 字段描述
46+
47+
// 判断是否为主键字段(fname 为 "id" 时)
48+
if ("id".equalsIgnoreCase(fname)) {
49+
FieldInfo idField = new FieldInfo.Builder(fname, FieldMapper.mapFTypeToSQLType(ftype))
50+
.primaryKey(true)
51+
.autoIncrement(true) // 主键默认为自增
52+
.notNull(true) // 主键不能为空
53+
.comment(fdesc != null ? fdesc : "主键") // 字段描述
54+
.build();
55+
fieldInfos.add(idField);
56+
} else {
57+
// 普通字段
58+
FieldInfo field = new FieldInfo.Builder(fname, FieldMapper.mapFTypeToSQLType(ftype))
59+
.notNull(false) // 默认允许为空
60+
.comment(fdesc) // 字段描述
61+
.build();
62+
fieldInfos.add(field);
63+
}
64+
}
65+
66+
// 返回构建的 EntityInfo
67+
return new EntityInfo(tableName, tableComment, fieldInfos);
68+
}
69+
}

src/main/java/com/tml/otowbackend/engine/sql/EntityProcessor.java renamed to src/main/java/com/tml/otowbackend/engine/sql/EntityScanner.java

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,20 @@
66
import com.tml.otowbackend.engine.sql.annotation.DefaultValue;
77
import com.tml.otowbackend.engine.sql.annotation.TransientField;
88

9+
import java.io.File;
910
import java.lang.reflect.Field;
11+
import java.net.URL;
1012
import java.util.ArrayList;
1113
import java.util.List;
14+
import java.util.Objects;
1215

1316
/**
1417
* 描述:
18+
*
1519
* @author suifeng
1620
* 日期: 2024/12/12
1721
*/
18-
public class EntityProcessor {
22+
public class EntityScanner {
1923

2024
/**
2125
* 获取实体类的字段信息
@@ -69,4 +73,53 @@ public static List<FieldInfo> getFields(Class<?> clazz) {
6973
}
7074
return fields;
7175
}
76+
77+
/**
78+
* 根据包名扫描实体类并生成实体信息列表
79+
*
80+
* @param packageName 包名
81+
* @return 实体信息列表
82+
*/
83+
public static List<EntityInfo> buildFromPackage(String packageName) {
84+
List<Class<?>> entityClasses = EntityScanner.scanEntities(packageName);
85+
List<EntityInfo> entities = new ArrayList<>();
86+
87+
for (Class<?> clazz : entityClasses) {
88+
String tableName = NameConverter.getTableName(clazz);
89+
List<FieldInfo> fields = getFields(clazz);
90+
entities.add(new EntityInfo(tableName, "", fields));
91+
}
92+
93+
return entities;
94+
}
95+
96+
/**
97+
* 扫描指定包下的所有类
98+
*
99+
* @param packageName 包名
100+
* @return 类的列表
101+
*/
102+
public static List<Class<?>> scanEntities(String packageName) {
103+
List<Class<?>> classes = new ArrayList<>();
104+
String path = packageName.replace(".", "/");
105+
URL resource = Thread.currentThread().getContextClassLoader().getResource(path);
106+
107+
if (resource == null) {
108+
throw new RuntimeException("包路径不存在: " + packageName);
109+
}
110+
111+
File directory = new File(resource.getFile());
112+
for (File file : Objects.requireNonNull(directory.listFiles())) {
113+
if (file.getName().endsWith(".class")) {
114+
try {
115+
String className = packageName + "." + file.getName().replace(".class", "");
116+
classes.add(Class.forName(className));
117+
} catch (ClassNotFoundException e) {
118+
throw new RuntimeException("类加载失败: " + file.getName(), e);
119+
}
120+
}
121+
}
122+
123+
return classes;
124+
}
72125
}

src/main/java/com/tml/otowbackend/engine/sql/FieldInfo.java

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
package com.tml.otowbackend.engine.sql;
22

3+
import com.tml.otowbackend.engine.ai.result.EntityClassDefinition;
34
import lombok.Data;
45

56
/**
6-
* 描述:
7+
* 描述: 字段信息类
78
* @author suifeng
89
* 日期: 2024/12/12
910
*/
@@ -17,4 +18,46 @@ public class FieldInfo {
1718
private boolean autoIncrement; // 是否自增
1819
private boolean notNull; // 是否非空
1920
private String comment; // 字段注释
21+
22+
/**
23+
* 静态构建器,简化外部构造
24+
*/
25+
public static class Builder {
26+
private final FieldInfo fieldInfo;
27+
28+
public Builder(String columnName, String columnType) {
29+
this.fieldInfo = new FieldInfo();
30+
this.fieldInfo.setColumnName(columnName);
31+
this.fieldInfo.setColumnType(columnType);
32+
}
33+
34+
public Builder defaultValue(String defaultValue) {
35+
this.fieldInfo.setDefaultValue(defaultValue);
36+
return this;
37+
}
38+
39+
public Builder primaryKey(boolean primaryKey) {
40+
this.fieldInfo.setPrimaryKey(primaryKey);
41+
return this;
42+
}
43+
44+
public Builder autoIncrement(boolean autoIncrement) {
45+
this.fieldInfo.setAutoIncrement(autoIncrement);
46+
return this;
47+
}
48+
49+
public Builder notNull(boolean notNull) {
50+
this.fieldInfo.setNotNull(notNull);
51+
return this;
52+
}
53+
54+
public Builder comment(String comment) {
55+
this.fieldInfo.setComment(comment);
56+
return this;
57+
}
58+
59+
public FieldInfo build() {
60+
return this.fieldInfo;
61+
}
62+
}
2063
}
Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,43 @@
11
package com.tml.otowbackend.engine.sql;
22

3+
import com.tml.otowbackend.engine.generator.utils.TypeConverter;
34
import com.tml.otowbackend.engine.sql.annotation.ColumnLength;
45
import com.tml.otowbackend.engine.sql.annotation.TextType;
56

67
import java.lang.reflect.Field;
8+
import java.time.LocalDate;
9+
import java.time.LocalDateTime;
10+
import java.util.Date;
711
import java.util.HashMap;
812
import java.util.Map;
913

1014
/**
11-
* 描述:
12-
* @author suifeng
13-
* 日期: 2024/12/12
15+
* 描述: 字段类型映射工具类
16+
* 负责将 Java 类型或自定义字段类型 (ftype) 映射为 SQL 数据库类型
1417
*/
1518
public class FieldMapper {
1619

1720
// Java 类型到 SQL 类型的映射
1821
private static final Map<Class<?>, String> JAVA_TO_SQL_TYPE = new HashMap<>();
1922

2023
static {
24+
// 初始化 Java 类型到 SQL 类型的映射
2125
JAVA_TO_SQL_TYPE.put(String.class, "VARCHAR(255)");
2226
JAVA_TO_SQL_TYPE.put(Integer.class, "INT");
2327
JAVA_TO_SQL_TYPE.put(Long.class, "BIGINT");
2428
JAVA_TO_SQL_TYPE.put(Boolean.class, "BIT");
2529
JAVA_TO_SQL_TYPE.put(boolean.class, "BIT");
2630
JAVA_TO_SQL_TYPE.put(Double.class, "DOUBLE");
2731
JAVA_TO_SQL_TYPE.put(Float.class, "FLOAT");
28-
JAVA_TO_SQL_TYPE.put(java.util.Date.class, "DATETIME");
29-
JAVA_TO_SQL_TYPE.put(java.time.LocalDate.class, "DATE");
30-
JAVA_TO_SQL_TYPE.put(java.time.LocalDateTime.class, "TIMESTAMP");
32+
JAVA_TO_SQL_TYPE.put(Date.class, "DATETIME");
33+
JAVA_TO_SQL_TYPE.put(LocalDate.class, "DATE");
34+
JAVA_TO_SQL_TYPE.put(LocalDateTime.class, "TIMESTAMP");
3135
}
3236

3337
/**
3438
* 映射字段的 Java 类型到 SQL 类型
3539
*
36-
* @param field 字段
40+
* @param field Java 字段
3741
* @return SQL 类型
3842
*/
3943
public static String mapJavaTypeToSQLType(Field field) {
@@ -45,7 +49,7 @@ public static String mapJavaTypeToSQLType(Field field) {
4549
String sqlType = JAVA_TO_SQL_TYPE.get(fieldType);
4650

4751
if (sqlType == null) {
48-
throw new UnsupportedOperationException("Unsupported field type: " + fieldType.getName());
52+
throw new UnsupportedOperationException("Unsupported Java field type: " + fieldType.getName());
4953
}
5054

5155
// 动态处理 String 类型的长度
@@ -56,4 +60,27 @@ public static String mapJavaTypeToSQLType(Field field) {
5660

5761
return sqlType;
5862
}
63+
64+
/**
65+
* 映射自定义字段类型 (ftype) 到 SQL 类型
66+
* 使用 TypeConverter 将 ftype 转换为包装类,然后基于 JAVA_TO_SQL_TYPE 映射到 SQL 类型
67+
*
68+
* @param ftype 自定义字段类型 (如 "string", "int", "LocalDateTime")
69+
* @return SQL 类型
70+
*/
71+
public static String mapFTypeToSQLType(String ftype) {
72+
// 使用 TypeConverter 将 ftype 转换为包装类
73+
Class<?> javaType = TypeConverter.toDatabaseFriendlyType(ftype);
74+
if (javaType == null) {
75+
throw new UnsupportedOperationException("Unsupported ftype: " + ftype);
76+
}
77+
78+
// 根据包装类映射到 SQL 类型
79+
String sqlType = JAVA_TO_SQL_TYPE.get(javaType);
80+
if (sqlType == null) {
81+
throw new UnsupportedOperationException("Unsupported Java type for ftype: " + javaType.getName());
82+
}
83+
84+
return sqlType;
85+
}
5986
}

src/main/java/com/tml/otowbackend/engine/sql/SQLExecutor.java

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,13 @@
1616
public class SQLExecutor {
1717

1818
/**
19-
* 执行指定 SQL 文件
20-
*
21-
* @param dbUrl 数据库连接 URL
22-
* @param username 数据库用户名
23-
* @param password 数据库密码
24-
* @param sqlFilePath SQL 文件路径
19+
* 执行 SQL 脚本
20+
* @param dbUrl 数据库连接 URL
21+
* @param username 数据库用户名
22+
* @param password 数据库密码
23+
* @param sql SQL 脚本
2524
*/
26-
public static void executeSQLFile(String dbUrl, String username, String password, String sqlFilePath) {
25+
public static void executeSQL(String dbUrl, String username, String password, String sql) {
2726
try {
2827
// 显式加载 MySQL 驱动
2928
Class.forName("com.mysql.cj.jdbc.Driver");
@@ -32,28 +31,24 @@ public static void executeSQLFile(String dbUrl, String username, String password
3231
connection.setAutoCommit(false); // 开启事务
3332

3433
try (Statement statement = connection.createStatement()) {
35-
// 加载并执行 SQL 文件
36-
String sqlScript = loadSQLFile(sqlFilePath);
37-
String[] sqlStatements = sqlScript.split(";");
38-
for (String sql : sqlStatements) {
39-
if (sql.trim().isEmpty()) {
34+
String[] sqlStatements = sql.split(";");
35+
for (String sqlStatement : sqlStatements) {
36+
if (sqlStatement.trim().isEmpty()) {
4037
continue; // 跳过空语句
4138
}
42-
statement.execute(sql.trim());
43-
System.out.println("执行成功: " + sql.trim());
39+
statement.execute(sqlStatement.trim());
40+
System.out.println("执行成功: " + sqlStatement.trim());
4441
}
4542

4643
connection.commit(); // 提交事务
47-
System.out.println("SQL 文件执行完成,事务已提交。");
48-
44+
System.out.println("SQL 执行完成,事务已提交。");
4945
} catch (SQLException e) {
5046
connection.rollback(); // 回滚事务
5147
throw new RuntimeException("SQL 执行失败,事务已回滚。原因: " + e.getMessage(), e);
5248
}
53-
54-
} catch (SQLException e) {
55-
throw new RuntimeException("数据库连接失败: " + e.getMessage(), e);
5649
}
50+
} catch (SQLException e) {
51+
throw new RuntimeException("数据库连接失败: " + e.getMessage(), e);
5752
} catch (ClassNotFoundException e) {
5853
throw new RuntimeException("MySQL JDBC 驱动未找到,请检查依赖配置。", e);
5954
}
@@ -65,7 +60,7 @@ public static void executeSQLFile(String dbUrl, String username, String password
6560
* @param sqlFilePath SQL 文件路径
6661
* @return SQL 文件内容
6762
*/
68-
private static String loadSQLFile(String sqlFilePath) {
63+
public static String loadSQLFile(String sqlFilePath) {
6964
StringBuilder sqlBuilder = new StringBuilder();
7065
try (BufferedReader reader = new BufferedReader(new FileReader(sqlFilePath))) {
7166
String line;

0 commit comments

Comments
 (0)