当前位置:网站首页>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
边栏推荐
- [Journal Conference Series] IEEE series template download guide
- Interface idempotency problem
- SAP UI5 应用开发教程之七十二 - SAP UI5 页面路由的动画效果设置
- Apache Atlas Compilation and installation records
- Test on the time required for Oracle to delete data with delete
- The interviewer dug a hole for me: what's the use of "/ /" in URI?
- [tensorflow] sharing mechanism
- Oracle calculates the difference between two dates in seconds, minutes, hours and days
- [multi screen interaction] realize dual multi screen display II: startactivity mode
- 交叉碳市场和 Web3 以实现再生变革
猜你喜欢
[point cloud series] learning representations and generative models for 3D point clouds
集简云 x 飞书深诺,助力企业运营部实现自动化办公
[point cloud series] multi view neural human rendering (NHR)
[indicators] precision, recall
The interviewer dug a hole for me: how many concurrent TCP connections can a single server have?
Lpddr4 notes
[point cloud series] relationship based point cloud completion
SAP ui5 application development tutorial 72 - trial version of animation effect setting of SAP ui5 page routing
The query did not generate a result set exception resolution when the dolphin scheduler schedules the SQL task to create a table
切线空间(tangent space)
随机推荐
SAP UI5 应用开发教程之七十二 - SAP UI5 页面路由的动画效果设置
Test the time required for Oracle library to create an index with 7 million data in a common way
Oracle and MySQL batch query all table names and table name comments under users
[point cloud series] pointfilter: point cloud filtering via encoder decoder modeling
SAP ui5 application development tutorial 72 - animation effect setting of SAP ui5 page routing
PyTorch 21. NN in pytorch Embedding module
Storage scheme of video viewing records of users in station B
Oracle database combines the query result sets of multiple columns into one row
这个SQL语名是什么意思
Machine learning -- model optimization
Stack protector under armcc / GCC
QT调用外部程序
TIA博途中基于高速计数器触发中断OB40实现定点加工动作的具体方法示例
为什么从事云原生开发需要学习容器技术
Special window function rank, deny_ rank, row_ number
Isparta is a tool that generates webp, GIF and apng from PNG and supports the transformation of webp, GIF and apng
Software test system integration project management engineer full truth simulation question (including answer and analysis)
[point cloud series] foldingnet: point cloud auto encoder via deep grid deformation
聯想拯救者Y9000X 2020
pycharm Install packages failed