【发布时间】:2023-01-12 03:42:15
【问题描述】:
我需要使用反射为每个 dto 的实体找到所有“缺失”和额外的字段。 例如。
我有
public class TestDto {
long id;
String name;
int age;
long personId;
String phone;
}
和实体
public class TestEntity {
long id;
String name;
int age;
Person person;
String address;
}
person = personId(映射)。我们不需要像“缺失”字段和“额外”字段那样打印它。
输出: dto 缺少字段。请添加!:地址; dto 的额外字段。请删除! : 电话;
我写
private final Map<String, String> fieldMappings = new HashMap<>();
fieldMappings.put("person", "personId");
Field[] dtoFields = auditDtoClass.getDeclaredFields();
Field[] entityFields = entityClass.getDeclaredFields();
List<String> missingFields = Arrays.stream(entityFields)
.filter(field -> !fieldMappings.containsKey(field.getName()) && Stream.of(dtoFields)
.noneMatch(dtoField -> dtoField.getName().equals(field.getName())))
.map(Field::getName)
.filter(field -> Arrays.stream(dtoFields)
.noneMatch(f -> f.getName().equals(field)))
.toList();
List<String> extraFields = Arrays.stream(dtoFields)
.filter(field -> !fieldMappings.containsValue(field.getName()) &&
!fieldMappings.containsKey(field.getName()) && Stream.of(entityFields)
.noneMatch(entityField -> entityField.getName().equals(field.getName())))
.map(Field::getName)
.filter(field -> Arrays.stream(entityFields)
.noneMatch(f -> f.getName().equals(field)))
.toList();
这是不对的。
因为程序员可以在不添加到 dto 的情况下在其他实体中添加(私有 Person person 字段),并且它没有在缺少的字段中打印它。
我还认为我们可以链接这些字段
fieldMappings.put("person", "personId"); 实体/dto 类,但现在我不明白如何。
我很想听听有关如何执行此操作的想法。
【问题讨论】:
-
使用
fieldMappings.put("person", "personId");,此代码确实可以正常工作。我在这里看不到您的实际问题 -
旁注:
getDeclaredFields()将只返回在类本身中声明的字段,而不是在超类中声明的任何字段。此外,也许您可以使用任何现有的映射库来查找这些差异,例如Dozer、Mapstruct 等 - 无论如何,您都必须有一些映射代码才能获取数据(例如personId = person.getId()),所以我会将该检查逻辑放入相同的功能中。 -
我想检查所有的 dto。不仅是 TestDto 。如果您想为另一个 dto 添加人员字段,则此代码是错误的。例如 Shop 实体有字段 person 并且它只是在缺少的字段中忽略它。
-
@Thomas 我有
@Mapping(source = "person.id", target = "personId") TestDto toAuditDto(Test entity); -
顺便说一句,您的代码似乎效率极低,例如您基本上是在遍历每个实体字段的每个 dto 字段,反之亦然,从而获得 O(n*m) 复杂性。此外,您似乎基本上过滤了两次,即
Stream.of(dtoFields).noneMatch(dtoField -> dtoField.getName().equals(field.getName()))和Arrays.stream(dtoFields).noneMatch(f -> f.getName().equals(field))似乎在做同样的事情。
标签: java unit-testing reflection