当前位置:网站首页>Get the attribute value difference between two different objects with reflection and annotation
Get the attribute value difference between two different objects with reflection and annotation
2022-04-23 13:44:00 【0oIronhide】
Business scenario : The operator changed some fields of a record , Want to log operations , Who changed a field to something
analysis : Record operation log , That is to compare the data from the front end with the data in the database , It's a comparison dto And entity The difference between attribute values , The properties of the two objects are not completely consistent
Solutions : Customize a comment to add to dto Attributes to be compared , Define the Chinese name of the attribute in the annotation , Then use reflection to traverse dto All annotated attributes in , Take the attribute name entity Find the property with the same name in , Then compare the attribute values ; If the attribute type is Integer Equal shaping type , Results output ” from 1 Turn into 2“ , This semantics is not easy to understand , Enumerations can be configured for this attribute on the annotation , Get the description corresponding to the number through reflection
Custom annotation :
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@Documented
public @interface CompareFiled {
String filedChineseName(); // The Chinese name of the attribute
Class<?> enumClass() default Enum.class; // Property corresponds to the enumeration class type
}
Core class :
public class CompareTwoObject {
// Through the introduction of code, Traverse all enumerated values through reflection , Get the corresponding desc
private static String getEnumValue(Class<?> clazz, Object val) {
try {
Method getCode = clazz.getDeclaredMethod("getCode");
Method getDesc = clazz.getDeclaredMethod("getDesc");
Object[] enumConstants = clazz.getEnumConstants();
for (Object enumConstant : enumConstants) {
if (getCode.invoke(enumConstant).equals(val)) {
return getDesc.invoke(enumConstant).toString();
}
}
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
return " The corresponding enumeration value... Was not found ";
}
/** * Compare the property values of two objects , Returns a string , The format is :【{ Property name } from { The old value } Turn into { The new value }】 * Program traversal newVal Add... To the object @CompareFiled Annotated fields , If the field is null Or field in oldVal If it does not exist, it is not compared * If there is a corresponding enumeration class on this field , The field value will be compared with that of the enumeration code Match , Return the corresponding name */
public static String compare(Object newVal, Object oldVal) {
StringBuilder result = new StringBuilder();
Class<?> newClass = newVal.getClass();
Class<?> oldClass = oldVal.getClass();
Field[] oldValFields = oldClass.getDeclaredFields();
Set<String> oldValFiledSet = new HashSet<>(oldValFields.length);
for (Field oldValField : oldValFields) {
// take oldVal Put all the attributes of set Collection , Easy to find
oldValField.setAccessible(true);
oldValFiledSet.add(oldValField.getName());
}
try {
Field[] newValFileds = newClass.getDeclaredFields();
for (Field newValFiled : newValFileds) {
newValFiled.setAccessible(true);
if (newValFiled.isAnnotationPresent(CompareFiled.class)) {
// If the attribute value is null, or oldVal The attribute is not included in the , No comparison
if (newValFiled.get(newVal) != null && oldValFiledSet.contains(newValFiled.getName())) {
Field oldValFiled = oldClass.getDeclaredField(newValFiled.getName());
oldValFiled.setAccessible(true);
// Compare whether the two attribute values are equal
if (!newValFiled.get(newVal).equals(oldValFiled.get(oldVal))) {
CompareFiled cf = newValFiled.getAnnotation(CompareFiled.class);
result.append("【").append(cf.filedChineseName());
// If enumeration is configured on the annotation , Gets the enumeration value
if (cf.enumClass().getSuperclass() == Enum.class) {
result.append(" from ").append(getEnumValue(cf.enumClass(), oldValFiled.get(oldVal)))
.append(" Turn into ").append(getEnumValue(cf.enumClass(), newValFiled.get(newVal))).append("】");
} else {
result.append(" from ").append(oldValFiled.get(oldVal))
.append(" Turn into ").append(newValFiled.get(newVal)).append("】");
}
}
}
}
}
} catch (NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();
}
return result.toString();
}
}
test Demo
public class Demo {
@Getter
enum NumEnum {
ONE(1, " Number one "),
TWO(2, " Number two ");
private Integer code;
private String desc;
NumEnum(Integer code, String desc) {
this.code = code;
this.desc = desc;
}
}
@Data
class Entity1 {
@CompareFiled(filedChineseName = " Numbers ", enumClass = NumEnum.class)
private Integer num = 1;
@CompareFiled(filedChineseName = " name ")
private String name = "XXX";
@CompareFiled(filedChineseName = " Time ")
private String time = "20:10";
@CompareFiled(filedChineseName = " date ")
private String date = "2021";
}
@Data
class Entity2 {
private Integer num = 2;
private String name = "XXX";
private String updateTime = "20:20";
private String date = "2020";
}
@Test
public void test() {
System.out.println(CompareTwoObject.compare(new Entity1(), new Entity2()));
// Results the print 【 Numbers from Number two Turn into Number one 】【 date from 2020 Turn into 2021】
}
版权声明
本文为[0oIronhide]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/04/202204230600131768.html
边栏推荐
- Two ways to deal with conflicting data in MySQL and PG Libraries
- 19c RAC steps for modifying VIP and scanip - same network segment
- Tersus notes employee information 516 MySQL query (time period uniqueness judgment of 2 fields)
- Oracle view related
- Utilisation de GDB
- Ora-16047 of a DG environment: dgid mismatch between destination setting and target database troubleshooting and listening vncr features
- ACFs file system creation, expansion, reduction and other configuration steps
- Use of GDB
- The difference between is and as in Oracle stored procedure
- Machine learning -- PCA and LDA
猜你喜欢

Double pointer instrument panel reading (I)

零拷贝技术

Ai21 labs | standing on the shoulders of giant frozen language models

Tersus notes employee information 516 MySQL query (time period uniqueness judgment of 2 fields)

Lenovo Savior y9000x 2020

【重心坐标插值、透视矫正插值】原理以及用法见解

Cross carbon market and Web3 to achieve renewable transformation

面试官给我挖坑:URI中的 “//” 有什么用?

Common types and basic usage of input plug-in of logstash data processing service

Android clear app cache
随机推荐
Lpddr4 notes
[point cloud series] deepmapping: unsupervised map estimation from multiple point clouds
Oracle index status query and index reconstruction
Bottomsheetdialogfragment + viewpager + fragment + recyclerview sliding problem
pycharm Install packages failed
ACFs file system creation, expansion, reduction and other configuration steps
Zero copy technology
Modification of table fields by Oracle
Interval query through rownum
Cross carbon market and Web3 to achieve renewable transformation
torch. Where can transfer gradient
Common commands of ADB shell
[point cloud series] neural opportunity point cloud (NOPC)
Short name of common UI control
QT calling external program
【视频】线性回归中的贝叶斯推断与R语言预测工人工资数据|数据分享
这个SQL语名是什么意思
Information: 2021 / 9 / 29 10:01 - build completed with 1 error and 0 warnings in 11S 30ms error exception handling
Machine learning -- model optimization
19c environment ora-01035 login error handling