1、需求
假如数据库中有一条记录从
{"id":1,"name":"张三","age":21,"sex":true}
更新成
{"id":1,"name":"李四","age":24,"sex":false}
则生成详细的日志记录
{
"id":1,"unityTag":"Person","unityOperate":"更新",
"unityMatter":"[姓名][年龄][性别]",
"unityContent":"[张三->李四][21->24][true->false]"
}
2、实现
需要用到:反射 、注解
3、具体实现
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* @author printsky
* @since 2018/8/29
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface LogCompar {
/**
* 中文名称
*
* @return String
*/
String name();
/**
* Date 如何格式化,默认为空
*
* @return String
*/
String dateFormat() default "";
}
/**
* @author printsky
* @since 2018/8/30
*/
public enum EnumTableName {
Person("Person"),
Province("Province"),
Income("Income");
EnumTableName(String tableName) {
this.tableName = tableName;
}
private String tableName;
public String getTableName() {
return tableName;
}
}
/**
* @author printsky
* @since 2018/08/28
*/
@JsonInclude(value = JsonInclude.Include.NON_NULL)
public class UnityLog {
/**
* id
*/
private Long id;
/**
* 数据库表名
*/
private String unityTag;
/**
* 数据库表记录id对应的操作日志
*/
private Long unityTagId;
/**
* 操作人
*/
private String unityOperator;
/**
* 操作时间
*/
private Date unityOperateTime;
/**
* 操作类型
*/
private String unityOperate;
/**
* 操作事项
*/
private String unityMatter;
/**
* 操作内容
*/
private String unityContent;
public UnityLog(Long id, String unityTag, Long unityTagId, String unityOperator, Date unityOperateTime, String unityOperate, String unityMatter, String unityContent) {
this.id = id;
this.unityTag = unityTag;
this.unityTagId = unityTagId;
this.unityOperator = unityOperator;
this.unityOperateTime = unityOperateTime;
this.unityOperate = unityOperate;
this.unityMatter = unityMatter;
this.unityContent = unityContent;
}
public UnityLog(UnityLogBuilder builder) {
this.unityTag = builder.unityTag;
this.unityTagId = builder.unityTagId;
this.unityOperator = builder.unityOperator;
this.unityOperate = builder.unityOperate;
this.unityMatter = builder.unityMatter;
this.unityContent = builder.unityContent;
}
public UnityLog() {
super();
}
/**
* id
*
* @return id id
*/
public Long getId() {
return id;
}
/**
* id
*
* @param id id
*/
public void setId(Long id) {
this.id = id;
}
/**
* 数据库表名
*
* @return unity_tag 数据库表名
*/
public String getUnityTag() {
return unityTag;
}
/**
* 数据库表名
*
* @param unityTag 数据库表名
*/
public void setUnityTag(String unityTag) {
this.unityTag = unityTag == null ? null : unityTag.trim();
}
/**
* 数据库表记录id对应的操作日志
*
* @return unity_tag_id 数据库表记录id对应的操作日志
*/
public Long getUnityTagId() {
return unityTagId;
}
/**
* 数据库表记录id对应的操作日志
*
* @param unityTagId 数据库表记录id对应的操作日志
*/
public void setUnityTagId(Long unityTagId) {
this.unityTagId = unityTagId;
}
/**
* 操作人
*
* @return unity_operator 操作人
*/
public String getUnityOperator() {
return unityOperator;
}
/**
* 操作人
*
* @param unityOperator 操作人
*/
public void setUnityOperator(String unityOperator) {
this.unityOperator = unityOperator == null ? null : unityOperator.trim();
}
/**
* 操作时间
*
* @return unity_operate_time 操作时间
*/
public Date getUnityOperateTime() {
return unityOperateTime;
}
/**
* 操作时间
*
* @param unityOperateTime 操作时间
*/
public void setUnityOperateTime(Date unityOperateTime) {
this.unityOperateTime = unityOperateTime;
}
/**
* 操作类型
*
* @return unity_operate 操作类型
*/
public String getUnityOperate() {
return unityOperate;
}
/**
* 操作类型
*
* @param unityOperate 操作类型
*/
public void setUnityOperate(String unityOperate) {
this.unityOperate = unityOperate == null ? null : unityOperate.trim();
}
/**
* 操作事项
*
* @return unity_matter 操作事项
*/
public String getUnityMatter() {
return unityMatter;
}
/**
* 操作事项
*
* @param unityMatter 操作事项
*/
public void setUnityMatter(String unityMatter) {
this.unityMatter = unityMatter == null ? null : unityMatter.trim();
}
/**
* 操作内容
*
* @return unity_content 操作内容
*/
public String getUnityContent() {
return unityContent;
}
/**
* 操作内容
*
* @param unityContent 操作内容
*/
public void setUnityContent(String unityContent) {
this.unityContent = unityContent == null ? null : unityContent.trim();
}
public void setIdAndOperator(Long unityTagId, String unityOperator) {
this.unityTagId = unityTagId;
this.unityOperator = unityOperator;
}
public static UnityLogBuilder builder() {
return new UnityLogBuilder();
}
public static class UnityLogBuilder {
private String unityTag;
private Long unityTagId;
private String unityOperator;
private String unityOperate;
private String unityMatter;
private String unityContent;
public UnityLogBuilder unityTag(String unityTag) {
this.unityTag = unityTag;
return this;
}
public UnityLogBuilder unityTagId(Long unityTagId) {
this.unityTagId = unityTagId;
return this;
}
public UnityLogBuilder unityOperator(String unityOperator) {
this.unityOperator = unityOperator;
return this;
}
public UnityLogBuilder unityOperate(String unityOperate) {
this.unityOperate = unityOperate;
return this;
}
public UnityLogBuilder unityMatter(String unityMatter) {
this.unityMatter = unityMatter;
return this;
}
public UnityLogBuilder unityContent(String unityContent) {
this.unityContent = unityContent;
return this;
}
public UnityLog build() {
return new UnityLog(this);
}
}
}
/**
* @author printsky
* @since 2018/8/30
*/
public class Person extends Base {
@LogCompar(name = "id")
private Long id;
@LogCompar(name = "姓名")
private String name;
@LogCompar(name = "年龄")
private Integer age;
@LogCompar(name = "性别")
private boolean sex;
public Person() {
}
public Person(Long id, String name, Integer age, boolean sex) {
this.id = id;
this.name = name;
this.age = age;
this.sex = sex;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public boolean isSex() {
return sex;
}
public void setSex(boolean sex) {
this.sex = sex;
}
@Override
EnumTableName getTableName() {
return EnumTableName.Person;
}
}
这个类是主要的的逻辑实现部分
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.lang.StringUtils;
import java.lang.reflect.Field;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* @author printsky
* @since 2018/8/30
*/
public abstract class Base {
public abstract Long getId();
abstract EnumTableName getTableName();
//region 生成数据修改日志
public final static String ADD = "新增";
public final static String UPDATE = "更新";
public final static String DELETE = "删除";
public <T extends Base> UnityLog createLog(String unityOperate, T oldObj) throws IllegalAccessException {
//保存操作日志
UnityLog unityLog = comparatorObject(unityOperate, oldObj);
unityLog.setId(getId());
return unityLog;
}
/**
* 比较新老对象的差别
*
* @param unityOperate
* @param oldObj
* @return
* @throws IllegalAccessException
*/
private UnityLog comparatorObject(String unityOperate, Object oldObj) throws IllegalAccessException {
StringBuilder matter = new StringBuilder();
StringBuilder content = new StringBuilder();
if (oldObj != null && UPDATE.equals(unityOperate)) {
Map<String, Object> oldMap = changeValueToMap(oldObj);
Map<String, Object> newMap = changeValueToMap(this);
if (oldMap != null && !oldMap.isEmpty()) {
for (Map.Entry<String, Object> entry : oldMap.entrySet()) {
Object oldValue = entry.getValue();
Object newValue = newMap.get(entry.getKey());
if (!oldValue.equals(newValue)) {
matter.append("[").append(entry.getKey()).append("]");
content.append("[").append(oldValue).append("->").append(newValue).append("]");
}
}
}
} else {
matter.append("-");
content.append("-");
}
return UnityLog.builder()
.unityOperate(unityOperate)
.unityTag(getTableName().getTableName())
.unityMatter(String.valueOf(matter))
.unityContent(String.valueOf(content))
.build();
}
/**
* 将类对象转换成Map
*
* @param entity 原对象
* @return Map
* @throws IllegalAccessException 类型转换时报错
*/
private static Map<String, Object> changeValueToMap(Object entity) throws IllegalAccessException {
Map<String, Object> resultMap = new HashMap<>();
Field[] fields = entity.getClass().getDeclaredFields();
for (Field field : fields) {
String name = field.getName();
if (PropertyUtils.isReadable(entity, name) && PropertyUtils.isWriteable(entity, name)) {
if (field.isAnnotationPresent(LogCompar.class)) {
LogCompar anno = field.getAnnotation(LogCompar.class);
//获取private对象字段值
field.setAccessible(true);
resultMap.put(anno.name(), field.get(entity));
}
}
}
return resultMap;
}
//endregion
}
public static void main(String[] args) {
Gson gson=new Gson();
Person user1=new Person(1L,"张三",21,true);
System.out.println("user1 = " + gson.toJson(user1));
Person user2=new Person(1L,"李四",24,false);
System.out.println("user2 = " + gson.toJson(user2));
try {
UnityLog log = user2.createLog(Base.UPDATE, user1);
System.out.println("log = " + gson.toJson(log));
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}