JeeSite | save information modification record

Keywords: Java Attribute Database PHP

Demand point

In many scenarios, the information can not be easily modified. When modifying, it needs either permission or approval. However, in either way, the data before and after modification needs to be kept "background". That is to say, the key information is modified with modification records. Generally, modification records record the data fields of the modifier, modification date and modification. .

For example, to change a person's name from "Zhang San" to "Li Si", the information recorded may be as follows:

Name: (Zhang San) => (Li Si); Gender: (Female) => (Male);

This is a good indication of which fields have been modified and what data have been changed before and after the modification. No matter how the key information is modified, there will be evidence to check, such as time, person, information before and after data modification, etc.

 

Judging the modified data

After modifying the data in the page and submitting it to the page, the data will be transferred from JSP to Controller. At this time, the data has not been updated to the database. From the object submitted to Controller, the existing data can be retrieved from the database with the id of the data, and then the modified data fields can be obtained by comparing the existing data with the submitted data. What are they?

What's more tedious here is how to compare. It's certainly not a good way to use if to judge fields one by one. After all, fields are too often written by dead people. Then how to proceed, directly compare the two objects, the source code I found from the Internet, easy to use, meet the needs, the source code is as follows:

 1 /** 
 2  * Gets a list of two objects with different contents of the same name attribute 
 3  * @param class1 Object 1 
 4  * @param class2 Object 2 
 5  * @return 
 6  * @throws ClassNotFoundException 
 7  * @throws IllegalAccessException 
 8  */  
 9 public static List<Map<String ,Object>> compareTwoClass(Object class1, Object class2) {  
10     List<Map<String,Object>> list=new ArrayList<Map<String, Object>>();  
11     // Getting object's class  
12     Class<?> clazz1 = class1.getClass();  
13     Class<?> clazz2 = class2.getClass();  
14     // Get a list of attributes for an object  
15     Field[] field1 = clazz1.getDeclaredFields();  
16     Field[] field2 = clazz2.getDeclaredFields();  
17     // Traversal property list field1  
18     for(int i=0;i<field1.length;i++){  
19         // Traversal property list field2  
20         for(int j=0;j<field2.length;j++){  
21             // If field1[i]Attribute name and field2[j]Property names have the same content  
22             if(field1[i].getName().equals(field2[j].getName())){  
23                 if(field1[i].getName().equals(field2[j].getName())){  
24                     field1[i].setAccessible(true);  
25                     field2[j].setAccessible(true);  
26                     // If field1[i]Attribute values and field2[j]Attribute values differ in content  
27                     try {
28                         if (!compareTwo(field1[i].get(class1), field2[j].get(class2))){  
29                             Map<String,Object> map2=new HashMap<String, Object>();  
30                             map2.put("name",field1[i].getName());  
31                             map2.put("old",field1[i].get(class1));  
32                             map2.put("new",field2[j].get(class2));  
33                             list.add(map2);  
34                         }
35                     } catch (IllegalArgumentException e) {
36                         // TODO Auto-generated catch block
37                         e.printStackTrace();
38                     } catch (IllegalAccessException e) {
39                         // TODO Auto-generated catch block
40                         e.printStackTrace();
41                     }  
42                     break;  
43                 }  
44             }
45         }
46     }
47     return list;
48 }
49 
50 /**  
51  * Compare the two data to see if they have the same content  
52  *  
53  * @param  object1,object2  
54  * @return boolean type  
55  */  
56 public static boolean compareTwo(Object object1,Object object2){  
57     if ( object1 == null && object2 == null ) {  
58         return true;  
59     }  
60     if ( object1 == null && object2 != null ) {  
61         return false;  
62     }  
63     if ( object1.equals(object2) ) {  
64         return true;  
65     }  
66     return false;  
67 }

Where did I find the source code? I forgot. Thank you for sharing it here. It's your source code that helped me solve the problems in the project quickly. (Although I didn't know Java at that time, I thought there must be a corresponding method for similar processing, rather than silly comparing one by one. Later, I learned that reflection and annotation are really good things in Java. It saves a lot of things to use them in projects. Now when I write PHP, although PHP doesn't support annotations, I also use reflection to parse annotations. It's really easy to implement annotations like Java.)

 

Attribute analysis

The function above returns a List with different attribute values in the two objects. After obtaining the List, it traverses the corresponding field meanings of the attributes again, and then splices them into a string to generate a modification log for preservation.

Generally, it is only necessary to associate the attributes in the class with the corresponding Chinese characters, but there are dictionary types in JeeSite, such as "male" and "female", which display "male" and "female" on the page, while in the database, they may be stored as "0" and "1", so they are usually submitted on the page after selecting "male" or "female". It is also "0" or "1". Logging in this way is obviously not intuitive. Therefore, in this case, it is necessary to associate the Chinese of the field with the dictionary name, so that the Chinese of the field can be matched to the description of the value of the dictionary.

The code is as follows:

 1 public String catModifyInfo(List<Map<String, Object>> list) {
 2     Map<String, String> mapField = new HashMap<String, String>() {{ 
 3         // Attributes in class, Chinese corresponding to attributes
 4         put("sex","Gender");
 5     }};
 6     Map<String, String> mapDict = new HashMap<String, String>() {{ 
 7         // Property corresponds to Chinese, in JeeSite Description of Chinese Dictionary
 8         put("Gender", "SEX");
 9     }}; 
10     
11     // Constructed modified string
12     String modInfo = "";
13     
14     for ( Map<String, Object> mp : list) {
15         System.out.println(mp.get("name") + "---" + mp.get("old") + "---" + mp.get("new"));
16         System.out.println(mapField.get(mp.get("name")));
17                     
18         // Determine whether the modified value is a dictionary
19         if ( mapDict.containsKey(mapField.get(mp.get("name"))) ) {
20             String oldValue = mp.get("old").toString();
21             String newValue = mp.get("new").toString();
22             String type     = mapDict.get(mapField.get(mp.get("name")));
23             String oldStr = DictUtils.getDictLabel(oldValue, type, "");
24             String newStr = DictUtils.getDictLabel(newValue, type, "");
25             System.out.println(mapField.get(mp.get("name")) + ":(" + oldStr + ") => (" + newStr + ");");
26             modInfo += mapField.get(mp.get("name")) + ":(" + oldStr + ") => (" + newStr + ");"; 
27         } else {
28             modInfo += mapField.get(mp.get("name")) + ":(" + mp.get("old") + ") => (" + mp.get("new") + ");"; 
29         }
30     }
31     
32     return modInfo;
33 }

The parameters passed in by the function are attributes of the difference between two objects. After the loop is parsed and the string is stitched together, the corresponding log can be obtained.

 

Calling method

After submitting data in JeeSite, the save method in the relevant Controller is invoked whether it is modified or new, so the above method needs to be invoked in the save method.

How can the same method be used to judge whether it is currently new or modified? The method of judging is to determine whether there is an ID in the incoming object, if there is an id, the description is modified, and if there is no id, the description is new.

The code is as follows:

 1 /*
 2  * If the id is not empty, it is represented as a modification
 3  */
 4 if ( StringUtils.isNotBlank(newXxx.getId()) ) {
 5     Xxx oldXxx = new Xxx();
 6     // Get the original information
 7     oldXxx = xxxService.get(newXxx.getId());
 8     
 9     // Compare modified information with unmodified information
10     List<Map<String, Object>> modList = compareTwoClass(oldXxx, newXxx);
11     // Generating difference information
12     String strModifyInfo = catModifyInfo(modList);
13     // Output differential string
14     System.out.println(strModifyInfo);
15     
16     // Save the modification record to the log table
17     // ...
18 }

With the above way, we can realize the log record before and after modifying the information. The situation after modification is as follows:

However, this method is not perfect. If the name or number of table fields are changed, the code should be modified accordingly. If the newly added fields have corresponding dictionaries, then the corresponding association of dictionaries should be added, so the code needs to be modified every time, which is very inconvenient.

The solution is simple, using the code generation function in JeeSite, you can solve this problem.

 

 

My Wechat Public Number: "Nung UP2U"

Posted by konetch on Mon, 14 Oct 2019 06:49:44 -0700