基于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小时内删除。
发表评论