工程经验 - Java 字段映射
背景:最近在写业务的时候,发现有个关于字段映射的流程在很多模块中是很多人都必须要写的,而且每个人写法也不统一,很多流程是重复性的劳动,所以在考虑能否将这种字段映射抽象出来,并统一规范,让大家按照这个流程走
功能:应用于领域模型类,从枚举中自动获取枚举的字段值,支持设置默认值
Ps:由于公司原因,不透露具体的业务应用。以下应用属于个人 YY 的应用场景
一、场景
在社交业务中,每个模块的接口需要带上一个话题字段提交到后端,方便后端拿到这个字段统计话题热度
二、设计
依赖于 Hutool 和 Guava 的一些基础方法
2.1 接口
抽象接口,规范话题枚举的实现
public interface BaseField {
String getFieldName();
}
2.2 接口领域模型
抽象共同需要的字段到父类,并在其中写自动转换获取枚举字段的抽象
@Data
public abstract class BaseTopicCondition<T> {
private String topic;
public static <C extends BaseTopicCondition<?>,
E extends Enum<E>> void setTopicProperty(Class<E> enumClass,
C condition,
boolean defaultNull,
String defaultFieldName) {
if (!defaultNull) {
condition.setTopic(defaultFieldName);
} else {
setTopicProperty(enumClass, condition);
}
}
public static <C extends BaseTopicCondition<?>,
E extends Enum<E>> void setTopicProperty(Class<E> enumClass, C condition) {
E topicFieldEnum = Enums.getIfPresent(enumClass, condition.getTopic()).orNull();
Object topicFieldValue = Objects.nonNull(topicFieldEnum) ?
ReflectUtil.getFieldValue(topicFieldEnum, TopicPropConstant.TOPIC_FIELD_NAME) : null;
condition.setTopic(Objects.nonNull(topicFieldValue) ? topicFieldValue.toString() : null);
}
}
接口领域模型继承基础类,并设置自动获取需要的枚举字段方法
@Data
@EqualsAndHashCode(callSuper = true)
public class ProgramBookTopicCondition extends BaseTopicCondition<ProgramBook> {
private Integer bookId;
private Integer userId;
@Getter
@AllArgsConstructor
public enum BookTopicField implements BaseField {
CPP_TOPIC("cpp_book_topic"),
JAVA_TOPIC("java_book_topic"),
RUST_TOPIC("rust_book_topic"),
OTHER_TOPIC("other_book_topic");
private final String fieldName;
}
public static void setFieldProperty(ProgramBookTopicCondition condition) {
BaseTopicCondition.setTopicProperty(BookTopicField.class,
condition,
false,
BookTopicField.OTHER_TOPIC.fieldName);
}
}
2.3 其他实体
编程书籍实体
@Data
public class ProgramBook {
// 编程书籍实体
}
字段名称常量
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class TopicPropConstant {
public static final String TOPIC_FIELD_NAME = "fieldName";
}
三、总结
由于字段的获取之前写法不一,于是之前被安全组扫出了 SQL 注入漏洞,但方案的缺点是映射的表和实体不支持联表查的结果