实体属性变更历史记录框架(一)-变更历史记录从此无忧

16 篇文章 2 订阅
5 篇文章 0 订阅

  在实际mis项目中增删改查必不可少,针对"改"的操作,重要的项目中都要有变更历史记录.本实例提供了一个实体属性变更历史记录工具类,只要写很少的代码就能实现强大的变更历史记录功能.本工具类的主要优点是1.工具类对实体对象没有依赖性,任何对象都能记录历史.

先看看如何使用吧:
1.得到变化前后的对象.
2.调用下面方法传入第一步中的值.
  HistoryUtil util = new HistoryUtil();
  util.record(类名, 变化前的对象, 变化后的对象,实体Id,修改人);

例子详细代码:

package com.tgb.lk.history;

public class HistoryTest {
	public static void main(String[] args) {
		Student s = new Student();
		s.setId(1);
		s.setName("李坤");
		s.setSex("男");
		s.setClazz("五期提高班");

		// 可以使用commons-beanutils-xxx.jar中的下面这个方法来保留原对象.
		// BeanUtils.copyProperties(dest, src);

		Student s2 = new Student();
		s2.setId(1);
		s2.setName("李佳");
		s2.setSex("女");

		// HistoryUtil util = new HistoryUtil();
		// util.record(Student.class, s, s2,"1","admin");

		HistoryUtil<Student> util = new HistoryUtil<Student>();//方法内部有输出
		util.record(Student.class, s, s2, "1", "admin");
	}
}

例子输出结果:


实体类:
package com.tgb.lk.history;

public class Student {
	private int id;
	private String name;
	private String sex;
	private String clazz;

	//get和set方法
	@Override
	public String toString() {
		return "Student [clazz=" + clazz + ", id=" + id + ", name=" + name
				+ ", sex=" + sex + "]";
	}
}
核心逻辑:
变更历史实体类:

package com.tgb.lk.history;

import java.util.Date;

public class History {
	private int id;
	private String entity; // 实体类名,标记是哪个实体类
	private String entityId; // 实体对象的Id
	private String property; // 实体的属性名,标记实体的哪个属性发生修改
	private String oldValue; // 原属性值
	private String newValue; // 新属性值
	private String user; // 修改人
	private Date modifyDate; // 修改时间
	private String desc; // 描述

	//get和set方法略

	@Override
	public String toString() {
		return "\n History [id=" + id + ", entity=" + entity + ",\n entityId="
				+ entityId + ", property=" + property + ", oldValue="
				+ oldValue + ", newValue=" + newValue + ",\n user=" + user
				+ ", modifyDate=" + modifyDate + ", desc=" + desc + "]\n";
	}
}
HistoryUtil类(注意需要修改一下注释中添加入库和批量入库的实现):
package com.tgb.lk.history;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/*
 * @author likun 
 * 记录属性变更历史的工具类,使用步骤见main方法.
 * HistoryUtil util = new HistoryUtil();
 * util.record(Student.class, s, s2,"1","admin");
 */
public class HistoryUtil<T> {

	/**
	 * 支持自己定义一个History对象并保存入库.
	 * 
	 * @param history
	 */
	public void record(History history) {
		System.out.println(history);
		// 调用添加入库方法.
	}

	// 批量保存到数据库中,考虑到对象修改的属性可能较多,所以采用批量导入效率会高一些.
	public void record(List<History> historys) {
		System.out.println(historys);
		// 调用批量添加入库方法.
	}

	/**
	 * 比较两个对象哪些属性发生变化,将变化的属性保存为History对象.
	 * 
	 * @param clazz
	 *            修改类
	 * @param oldObj
	 *            老对象
	 * @param newObj
	 *            新对象
	 * @param entityId
	 *            实体Id
	 * @param user
	 *            修改人
	 */
	public void record(Class<T> clazz, T oldObj, T newObj,
			String entityId, String user) {
		if (oldObj == newObj) {
			return;// 如果两个对象相同直接退出
		}
		
		List<History> list = new ArrayList<History>();
		Field[] allFields = clazz.getDeclaredFields();// 得到指定类的所有属性Field.
		
		for (Field field : allFields) {
			field.setAccessible(true);// 设置类的私有字段属性可访问.
			try {
				if (!field.get(oldObj).equals(field.get(newObj))) {
					History history = new History();
					history.setEntity(clazz.toString());
					history.setProperty(field.getName());
					history.setOldValue(String.valueOf(field.get(oldObj)));
					history.setNewValue(String.valueOf(field.get(newObj)));
					history.setModifyDate(new Date());
					history.setEntityId(entityId);// 记录修改的对象的主键Id.
					history.setUser(user);// 记录修改者
					list.add(history);
				}
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			}
		}
		record(list);// 调用保存入库的方法.
	}

}


这篇文章中是属性变更历史记录框架的核心逻辑,看看你是否有这样的需求:
1.所有属性都记录变更历史太多,有些属性我不想记录变更历史.
2.实体属性变化前后的值需要把编码转成有意义的文字.例如:实体类中性别用0,1表示,而希望变更历史中记录前后变化的值是"男","女".
3.传入实体对象自动识别实体Id,而不需要手工传入.
4.实体的属性名不好记,想加一个好记别名,这样便于查询.

请看下篇文章:http://blog.csdn.net/lk_blog/article/details/8092925


实体属性变更历史记录框架(一)-变更历史记录从此无忧(http://blog.csdn.net/lk_blog/article/details/8007777)

实体属性变更历史记录框架(二)-变更历史记录从此无忧(http://blog.csdn.net/lk_blog/article/details/8092925)


限于本人水平有限,很多地方写的并不完美,希望大家不吝赐教.如果觉得本文对您有帮助请顶支持一下,如果有不足之处欢迎留言交流,希望在和大家的交流中得到提高.

代码下载:http://download.csdn.net/detail/lk_blog/4667643

  • 9
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值