Skip to content

Commit 67dd1d4

Browse files
committed
fix(core): 修复 ModelField 注解获取问题并增强 SQL 更新语句生成逻辑
- 修复在使用代理类时无法直接获取 ModelField 注解的问题 -增加对注解的动态检查,以适应字节码增强等场景 - 优化 SQL 更新语句生成逻辑,仅包含需要更新的字段 - 新增 带类型的groupBy 方法支持分组查询
1 parent 1a18067 commit 67dd1d4

File tree

4 files changed

+67
-5
lines changed

4 files changed

+67
-5
lines changed

flexmodel-codegen/src/main/groovy/tech/wetech/flexmodel/codegen/BuildItemSPIFileGenerator.groovy

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package tech.wetech.flexmodel.codegen
22

33
import groovy.util.logging.Log
4+
import tech.wetech.flexmodel.BuildItem
45

56
import java.nio.file.Path
67

@@ -15,7 +16,7 @@ class BuildItemSPIFileGenerator extends AbstractGenerator {
1516
return Path.of(
1617
targetDirectory,
1718
"target/classes/META-INF/services",
18-
"tech.wetech.flexmodel.BuildItem"
19+
BuildItem.class.getName()
1920
).toString()
2021
}
2122

flexmodel-core/src/main/java/tech/wetech/flexmodel/query/Expressions.java

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import org.slf4j.LoggerFactory;
55
import tech.wetech.flexmodel.annotation.ModelField;
66

7+
import java.lang.annotation.Annotation;
78
import java.lang.invoke.SerializedLambda;
89
import java.lang.reflect.Field;
910
import java.lang.reflect.Method;
@@ -98,10 +99,30 @@ private static <T, R> String getAnnotatedFieldName(Class<T> targetClass, String
9899
// 查找字段并获取 @ModelField 注解
99100
Field field = findFieldByName(targetClass, fieldName);
100101
if (field != null) {
102+
// 首先尝试直接获取注解
101103
ModelField modelField = field.getAnnotation(ModelField.class);
102104
if (modelField != null) {
103105
return modelField.value();
104106
}
107+
108+
// 如果直接获取失败,可能是由于动态代理或字节码增强导致的
109+
// 遍历所有注解,查找 ModelField 注解
110+
Annotation[] annotations = field.getAnnotations();
111+
for (Annotation annotation : annotations) {
112+
// 检查注解是否为 ModelField 或其代理类
113+
if (isModelFieldAnnotation(annotation)) {
114+
// 通过反射获取注解的值
115+
try {
116+
Method valueMethod = annotation.getClass().getMethod("value");
117+
Object value = valueMethod.invoke(annotation);
118+
if (value instanceof String) {
119+
return (String) value;
120+
}
121+
} catch (Exception e) {
122+
log.warn("获取注解值失败: " + e.getMessage());
123+
}
124+
}
125+
}
105126
}
106127

107128
return null;
@@ -114,6 +135,35 @@ private static <T, R> String getAnnotatedFieldName(Class<T> targetClass, String
114135
}
115136
}
116137

138+
/**
139+
* 检查注解是否为 ModelField 注解
140+
*/
141+
private static boolean isModelFieldAnnotation(Annotation annotation) {
142+
if (annotation == null) {
143+
return false;
144+
}
145+
146+
// 直接检查注解类型
147+
if (annotation.annotationType() == ModelField.class) {
148+
return true;
149+
}
150+
151+
// 检查注解的类型名称(处理代理类的情况)
152+
String annotationClassName = annotation.annotationType().getName();
153+
if (ModelField.class.getName().equals(annotationClassName)) {
154+
return true;
155+
}
156+
157+
// 检查注解类是否实现了 ModelField 接口(代理类可能实现原始注解接口)
158+
try {
159+
// 通过反射检查注解类是否包含 value 方法
160+
Method valueMethod = annotation.getClass().getMethod("value");
161+
return valueMethod != null;
162+
} catch (NoSuchMethodException e) {
163+
return false;
164+
}
165+
}
166+
117167
/**
118168
* 获取目标类
119169
*/

flexmodel-core/src/main/java/tech/wetech/flexmodel/query/TypedDSLQueryBuilder.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,16 @@ public TypedDSLQueryBuilder<T> groupBy(String... fields) {
121121
return this;
122122
}
123123

124+
@SafeVarargs
125+
public final <R> TypedDSLQueryBuilder<T> groupBy(Expressions.SFunction<T, R>... getters) {
126+
String[] fields = new String[getters.length];
127+
for (int i = 0; i < fields.length; i++) {
128+
fields[i] = Expressions.getFieldName(getters[i]);
129+
}
130+
delegate.groupBy(fields);
131+
return this;
132+
}
133+
124134
/**
125135
* 设置连接
126136
*/

flexmodel-core/src/main/java/tech/wetech/flexmodel/sql/SqlDataService.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,8 @@ public int updateById(String modelName, Object objR, Object id) {
148148
.append(" set ");
149149
StringJoiner assignment = new StringJoiner(", ");
150150

151-
record.keySet().stream().filter(col -> !col.equals(idField.getName()))
151+
record.keySet().stream()
152+
.filter(col -> !col.equals(idField.getName()) && (data.containsKey(col) || processedData.get(col) != null))
152153
.forEach(col -> assignment.add(sqlDialect.quoteIdentifier(col) + "=:" + col));
153154

154155
sql.append(assignment);
@@ -159,7 +160,7 @@ public int updateById(String modelName, Object objR, Object id) {
159160
.append(idField.getName())
160161
.append(")");
161162

162-
Map<String, Object> params = new HashMap<>(record);
163+
Map<String, Object> params = new HashMap<>(processedData);
163164
params.put(idField.getName(), id);
164165

165166
log.debug("Generated UPDATE SQL: {}", sql);
@@ -194,14 +195,14 @@ public int update(String modelName, Object objR, String filter) {
194195
.append(" set ");
195196
StringJoiner assignment = new StringJoiner(", ");
196197
processedData.keySet().stream()
197-
.filter(col -> !col.equals(idField.getName()))
198+
.filter(col -> !col.equals(idField.getName()) && (record.containsKey(col) || processedData.get(col) != null))
198199
.forEach(col -> assignment.add(sqlDialect.quoteIdentifier(col) + "=:" + col));
199200
sql.append(assignment);
200201

201202
sql.append(" where ")
202203
.append(" (").append(sqlResult.sqlClause()).append(")");
203204

204-
Map<String, Object> params = new HashMap<>(record);
205+
Map<String, Object> params = new HashMap<>(processedData);
205206
params.putAll(sqlResult.args());
206207

207208
log.debug("Generated UPDATE SQL: {}", sql);

0 commit comments

Comments
 (0)