一.1.先做一个前置通知和后置通知,嗯。。。出现异常也要处理
2.要写个数据对比的方法,得出有修改的字段还有他们的新值和旧值
3.数据对比里需要调用对应mapper查数据库得到旧值,才能对比
二.边撸代码边说呗 ,不过代码顺序得和上面的逻辑思路顺序倒着来
1.写个mapper调用方法,返回旧数据实体,首先要拿到id或者ids
/**
* ****获取对象里某个字段的值**(这里是获取id或ids)**
*
* @param object
* @param fieldName
* @return
* @throws Exception
*/
public static List<String> getFieldValue(Object object, String fieldName) throws Exception {
**//定义返回值**
List<String> result = new ArrayList<>();
Field field = object.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
Object value = field.get(object);
Class fieldType = field.getType();
**//判断java字段类型(为了兼容批量操作不传集合,传逗号分割的字符串的)**
if (Collection.class.isInstance(fieldType)) {
result = (ArrayList<String>) value;
} else {
String[] valueStr = value.toString().split(",");
result = Arrays.asList(valueStr);
}
return result;
}
/**
* 取得旧数据对象
*
* @param fieldValue 字段值,这里是id值
* @param operationLogFlag 日志注解
* @return
* @throws IllegalAccessException
* @throws InstantiationException
*/
public static Object getResult(String fieldValue, OperationLogFlag operationLogFlag) throws IllegalAccessException, InstantiationException {
**//加个断言,免得真出现没id也进到这逻辑的情况**
Assert.notNull(fieldValue, "未解析到id值,请检查前台传递参数是否正确");
**//从注解里拿到要查询数据库所调用的class文件**
Class serviceclass = operationLogFlag.serviceclass();
**//想用newInstance()但是好像由于是接口没有构造函数,所以直接从ioc容器里拿直接点**
BaseMapper baseMapper = (BaseMapper) SpringContextUtil.getBean(serviceclass);
return baseMapper.selectById(fieldValue);
}
想想还得附上SpringContextUtil代码。。。以下就是
/**
* Spring上下文获取工具类
*/
@Component
public class SpringContextUtil implements ApplicationContextAware {
private static ApplicationContext applicationContext;
/**
* 设置上下文
*
* @param applicationContext
* @throws BeansException
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
SpringContextUtil.applicationContext = applicationContext;
}
/**
* 获取上下文
*
* @return
*/
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
/**
* 通过名字获取上下文中的bean
*
* @param name
* @return
*/
public static Object getBean(String name) {
return applicationContext.getBean(name);
}
/**
* 通过类型获取上下文中的bean
*
* @param requiredType
* @return
*/
public static Object getBean(Class<?> requiredType) {
return applicationContext.getBean(requiredType);
}
}
2.得出旧对象,开始比较了,下面是比较的代码
/**
* 获取两个对象同名属性内容不相同的列表
*
* @param newObject 新对象
* @param oldObject 旧对象
* @return
* @throws IllegalAccessException
*/
public static List<Map<String, Object>> getTwoObjectDiff(Object newObject, Object oldObject) throws IllegalAccessException {
List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
**//取得两个对象的class**
Class<?> newObjectClass = newObject.getClass();
Class<?> oldObjectClass = oldObject.getClass();
**//取得对象的各个属性,要一个一个比较字段**
Field[] newObjectClassDeclaredFields = newObjectClass.getDeclaredFields();
Field[] oldObjectClassDeclaredFields = oldObjectClass.getDeclaredFields();
**//开始遍历newObjectClass属性列表**
for (int i = 0; i < newObjectClassDeclaredFields.length; i++) {
**//循环内部开始遍历oldObjectClass属性列表**
for (int j = 0; j < oldObjectClassDeclaredFields.length; j++) {
//如果newObjectClass[i]属性名与oldObjectClass[i]属性名内容相同,就开始比较value
Object newName = newObjectClassDeclaredFields[i].getName();
Object oldName = oldObjectClassDeclaredFields[j].getName();
if (newName.equals(oldName)) {
**//把新旧数据的字段设为可使用**
newObjectClassDeclaredFields[i].setAccessible(true);
oldObjectClassDeclaredFields[j].setAccessible(true);
**//把新旧自字段值做个处理,避免出现类似旧值为null而传进来的是"",这样比就很尴尬,这种情况其实是没更新的,只是前后端传值不统一造成的**
Object newValue = newObjectClassDeclaredFields[i].get(newObject);
Object oldValue = oldObjectClassDeclaredFields[j].get(oldObject);
newValue = disposeValue(newValue);
oldValue = disposeValue(oldValue);
**//如果newObjectClassDeclaredFields[i]属性值与oldObjectClassDeclaredFields[j]属性值内容不相同**
if (!compareTwoObject(newValue, oldValue)) {
Map<String, Object> changeMap = new HashMap<String, Object>();
ApiModelProperty apiModelProperty = newObjectClassDeclaredFields[i].getAnnotation(ApiModelProperty.class);
String fieldName = "";
if (apiModelProperty != null) {
fieldName = apiModelProperty.value();
} else {
fieldName = newObjectClassDeclaredFields[i].getName();
}
changeMap.put("字段名", fieldName);
changeMap.put("新值", newValue);
changeMap.put("旧值", oldValue);
list.add(changeMap);
}
break;
}
}
}
return list;
}
/**
* 对比两个数据值是否相同
*
* @param object1,object2
* @return boolean类型
*/
public static boolean compareTwoObject(Object object1, Object object2) {
if (object1 == null && object2 == null) {
return true;
}
if (object1 == null && object2 != null) {
return false;
}
if (object1.equals(object2)) {
return true;
}
return false;
}
/**
* string集合转字符串
*
* @param list(string)
* @return
*/
public static String listToStr(List<String> list) {
final String SEPARATOR = ",";
String result = "";
StringBuilder stringBuilder = new StringBuilder();
if (CollectionUtils.isNotEmpty(list)) {
for (String string : list) {
stringBuilder.append(string);
stringBuilder.append(SEPARATOR);
}
}
result = stringBuilder.toString();
result = result.substring(0, result.length() - 1);
return result;
}
/**
* 日期转字符串
*
* @param date
* @param pattern
* @return
*/
public static String formatDate(Date date, String pattern) {
String format = pattern;
if (date == null) {
return "";
}
if (pattern == null) {
format = "yyyy-MM-dd";
}
SimpleDateFormat sdf = new SimpleDateFormat(format);
return sdf.format(date);
}
/**
* 处理下字段值,不然会影响判断和存储
*
* @param value 字段值
* @return
*/
public static Object disposeValue(Object value) {
**//新旧前后全部赋值为"",当做没改变**
if (Objects.isNull(value)) {
value = "";
}
**//日期类型还得处理下,免得出现时间戳**
if (StringUtils.isNotEmpty(value.toString())) {
if (value instanceof Date || value instanceof java.sql.Date) {
value = CommonUtil.formatDate((Date) value, "yyyy-MM-dd");
}
}
return value;
}