基于Springboot与注解⽐较两个对象对应字段的属性值前⾔:⽐较两个对象同⼀字段的不同值,并对字段进⾏释义,对字典值进⾏转义,输出中⽂修改说明,可⽤于操作⽇志的输出。⼀、字典值缓存
1、应⽤上下⽂⼯具类
启动类中设置应⽤上下⽂,从⽽可以在⼯具类中注⼊服务层
1 @SpringBootApplication
2public class DemoApplication {
3
4public static void main(String[] args) {
5        ApplicationContext applicationContext = SpringApplication.run(DemoApplication.class, args);
6        SpringContextUtil.setApplicationContext(applicationContext);
7    }
8
9 }
应⽤上下⽂⼯具类
1public class SpringContextUtil {
2
3private static ApplicationContext applicationContext;
4
5public static ApplicationContext getApplicationContext() {
6return applicationContext;
7    }
8
9public static void setApplicationContext(ApplicationContext applicationContext) {
10        SpringContextUtil.applicationContext = applicationContext;
11    }
12
13//返回指定bean的实例
14public static Object getBean(String beanId) {
Bean(beanId);
16    }
17 }
2、字典值缓存
字典表结构,忽略字典表服务层代码,缓存于HashMap中。
1public class DictMap {
2
3    @Autowired
4private static SysDictService dictService;
5
6private static HashMap<String, String> hashMap = new HashMap<>();
7//静态⽅法在程序启动的时候只加载⼀次,这样为了让查询⽅法只去数据库查询⼀次
8static {
9//获取应⽤上下⽂对象
10        ApplicationContext ctx = ApplicationContext();
11//获取字典服务实例
12        dictService = Bean(SysDictService.class);
13        queryDict();
14    }
15//从数据库中取值放⼊到HashMap中
16public static void queryDict(){
17        hashMap.clear();
18        List<SysDict> dicts = dictService.findAll();
19for (SysDict dict : dicts) {
20            hashMap.Code(),DictName());
21        }
22    }
23
24/**
25    * 获取单个字典值的说明(中⽂)
26    * @param dictType
27    * @param dictValue
28    * @return
29*/
30public static String getDictName(String dictType,String dictValue){
31        StringBuilder sb = new StringBuilder();
32        StringBuilder keySb = sb.append(dictType).append("_").append(dictValue);
33        String key = String();
34        String value = (key);
35return value;
36    }
37
38/**
39    * 获取多个字典值的说明(中⽂)
40    * @param dictType
41    * @param dictValue
42    * @return
43*/
44public static String getDictNames(String dictType,String dictValue){
45        String dictStr = "";
46if (StringUtils.isNotBlank(dictValue)){
47//以"|"为分隔符
48            String[] split = dictValue.split("\\|");
49for (int i = 0; i < split.length; i++) {
50if (i == split.length - 1) {
51                    dictStr += DictName(dictType, split[i]);
52                } else {
53                    dictStr += DictName(dictType, split[i]) + "|";
54                }
55            }
56        }
57return dictStr;
58    }
59
60 }
⼆、注解
字段注解,字段中⽂名,作⽤于实体类需要⽐较的字段。
1/**
2 * @Description: 需要显⽰的实体字段中⽂名
3*/
4 @Retention(RetentionPolicy.RUNTIME) // 注解会在class字节码⽂件中存在,在运⾏时可以通过反射获取到
5 @Target({ElementType.FIELD,ElementType.METHOD})//定义注解的作⽤⽬标**作⽤范围字段、枚举的常量/⽅法
springboot中文6 @Documented//说明该注解将被包含在javadoc中
7public @interface FieldMeta {
8    String name() default "";
9    String description() default "";
10 }
三、实体类的写法
使⽤注解标志对应字段中⽂名,重写字典字段的get⽅法,进⾏字典值转义。
1 @Data
2public class ContrastClass {
3
4    @FieldMeta(name = "年龄")
5private int age;
6    @FieldMeta(name = "姓名")
7private String name;
8    @FieldMeta(name = "⽣⽇")
9private Date date;
10
11private String status;
12
13    @FieldMeta(name = "状态")
14private String statusStr;
15
16public String getStatusStr() {
DictNames("STAFF_STATUS",status);
18    }
19 }
四、对⽐⼯具类
通过反射对两个对象的相关字段进⾏⽐较
1/**
2 * @Description: ⽐较两个对象的变化
3*/
4public class ContrastUtils {
5
6/**记录每个修改字段的分隔符*/
7public static final String separator = ";";
8
9/**
10    * ⽐较两个对象,并返回不⼀致的信息
11    * @param  oldObj 旧对象
12    * @param  newObj 新对象
13    * @return
14    * @throws ClassNotFoundException
15    * @throws IllegalAccessException
16*/
17public static String compareTwoObj(Object oldObj,Object newObj ) throws IllegalAccessException, IntrospectionException, InvocationTargetException { 18
19        String str = "";
20//获取对象的class
21        Class<?> oldClass = Class();
22        Class<?> newClass = Class();
23//获取对象的属性列表
24        Field[] oldFields = DeclaredFields();
25        Field[] newFields = DeclaredFields();
26for (int i = 0; i < oldFields.length; i++) {
27if ("serialVersionUID".equals(oldFields[i].getName())) {
28continue;
29            }
30            oldFields[i].setAccessible(true);
31            newFields[i].setAccessible(true);
32
33// 这样就获取到这个注解属性了
34            FieldMeta fieldChinese = oldFields[i].getAnnotation(FieldMeta.class);
35//⽆对应注解则说明该字段⽆需⽐较
36if (fieldChinese == null || StringUtils.isBlank(fieldChinese.name())) {
37continue;
38            }
39//获取注解中字段名
40            String fieldName = fieldChinese.name();
41
42            PropertyDescriptor oldPd = new PropertyDescriptor(oldFields[i].getName(), oldClass);
43            PropertyDescriptor newPd = new PropertyDescriptor(newFields[i].getName(), newClass);
44            Method oldReadMethod = ReadMethod();
45            Method newReadMethod = ReadMethod();
46//获取对应字段的值
47            Object oldValue = oldReadMethod.invoke(oldObj);
48            Object newValue = newReadMethod.invoke(newObj);
49
50/**获取差异字段*/
51            str = getDifferenceFieldStr(str, i, fieldName, oldValue, newValue);
52
53        }
54return str;
55    }
56
57/**
58    * 获取差异字段新旧值
59    * @param str
60    * @param i
61    * @param fieldName
62    * @param oldValue
63    * @param newValue
64    * @return
65*/
66private static String getDifferenceFieldStr(String str, int i, String fieldName, Object oldValue, Object newValue) {
67
68if (null == oldValue || StringUtils.String())){
69            oldValue = "⽆";
70        }
71if (null == newValue || StringUtils.String())){
72            newValue = "⽆";
73        }
74if (!oldValue.equals(newValue)) {
75if (i != 0) {
76                str += separator;
77            }
78            str += "字段名称:" + fieldName + ",旧值:" + oldValue + ",新值:" + newValue;
79        }
80return str;
81    }
82
83 }
五、测试类
1 @RestController
2 @RequestMapping("demo")
3public class DictController {
4
5    @GetMapping("/test")
6public ResultVo test() throws IllegalAccessException, InterruptedException, IntrospectionException, InvocationTargetException {
7
8        ContrastClass test1 = new ContrastClass();
9        test1.setAge(10);
10        test1.setDate(new Date());
11        test1.setStatus("1|2");
12        Thread.sleep(100);
13
14        ContrastClass test2 = new ContrastClass();
15        test2.setAge(20);
16        test2.setName("李四");
17        test2.setStatus("2|4");
18        test2.setDate(new Date());
19        String s = ContrastUtilspareTwoObj(test1, test2); 20
21return new ResultVo().success(s);
22    }
23
24 }
六、结果

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。