现在项目有个需求,需要对现有业务中可编辑数据增加创建人、创建时间、修改人、修改时间。基本思路是对业务对应的表增加这四个字段,对应的Java Bean增加四个属性,在业务中的增加操作时填充创建人和创建时间信息到数据库,在修改操作时对修改人和修改时间进行填充。
由于业务繁多,所以重复这样操作比较麻烦,就想能不能有什么能够简化的操作,一开始想通过Spring的AOP实现,但是问题出现在前后置通知无法获得业务存放信息的Bean和各个操作业务的方法没有同意的规范在配置切入点时会很麻烦所以最终放弃了。最后决定利用反射技术将信息填充到Object对象中,写了一个工具类方便实现该功能。
先贴上工具类:
/**
* @author: sunzhen
* @date: 2019/7/31
* @time: 18:18
* @description: 填充用户信息(创建人、创建时间、修改人、修改时间)工具类
*/
public class FillUserInfoUtil {
/**
* @author: sunzhen
* @date: 2019-07-31 18:24
* @param: obj
* @param: request
* @return: void
* @throws:
* @description: 从request中获取创建人、创建时间信息通过反射填充到obj对象中
*/
public static void fillCreateUserInfo(Object obj, HttpServletRequest request){
try {
//从session中获取到当前登录者的信息
SessionInfo sessionInfo = (SessionInfo) request.getSession().getAttribute("sessionInfo");
Class<?> clazz = obj.getClass();
Method setCreateUserName = clazz.getMethod("setCreateUserName", String.class);
Method setCreateUserTime = clazz.getMethod("setCreateUserTime", Date.class);
setCreateUserName.invoke(obj,sessionInfo.getUser().getName());
setCreateUserTime.invoke(obj,new Date());
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
/**
* @author: sunzhen
* @date: 2019-07-31 18:24
* @param: obj
* @param: request
* @return: void
* @throws:
* @description: 从request中获取修改人、修改时间信息通过反射填充到obj对象中
*/
public static void fillUpdateUserInfo(Object obj, HttpServletRequest request){
try {
//从session中获取到当前登录者的信息
SessionInfo sessionInfo = (SessionInfo) request.getSession().getAttribute("sessionInfo");
Class<?> clazz = obj.getClass();
Method setUpdateUserName = clazz.getMethod("setUpdateUserName", String.class);
Method setUpdateUserTime = clazz.getMethod("setUpdateUserTime", Date.class);
setUpdateUserName.invoke(obj,sessionInfo.getUser().getName());
setUpdateUserTime.invoke(obj,new Date());
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
先解释下为什么用反射,因为作为工具类,是准备在后面的业务中广泛使用的,肯定不能指定参数中的Object对象为某一业务存放信息的Bean对象,所以先在各业务存放信息的Bean类中增加创建与修改相关的四个属性,就可以利用反射的特性填充数据进去了。
给各业务存放信息的Bean类中增加创建人、创建时间、修改人、修改时间这四个属性时,我采用的是创建一个基类让其他业务Bean继承可以减少代码的编写。贴上基类代码:
/**
* @author: sunzhen
* @date: 2019/7/31
* @time: 18:18
* @description: 基类Bean,可继承到创建人,创建时间,修改人,修改时间属性
*/
@MappedSuperclass
public class BaseEntity {
//创建人姓名
public String createUserName;
//创建时间
public Date createUserTime;
//修改人姓名
public String updateUserName;
//修改时间
public Date updateUserTime;
public String getCreateUserName() {
return createUserName;
}
public void setCreateUserName(String createUserName) {
this.createUserName = createUserName;
}
@DateTimeFormat(pattern = "yyyy-MM-dd")
public Date getCreateUserTime() {
return createUserTime;
}
@DateTimeFormat(pattern = "yyyy-MM-dd")
public void setCreateUserTime(Date createUserTime) {
this.createUserTime = createUserTime;
}
public String getUpdateUserName() {
return updateUserName;
}
public void setUpdateUserName(String updateUserName) {
this.updateUserName = updateUserName;
}
@DateTimeFormat(pattern = "yyyy-MM-dd")
public Date getUpdateUserTime() {
return updateUserTime;
}
@DateTimeFormat(pattern = "yyyy-MM-dd")
public void setUpdateUserTime(Date updateUserTime) {
this.updateUserTime = updateUserTime;
}
}
最后到业务代码中使用,下面举个新增的例子,需要增加创建人和创建时间信息,直接使用工具类就可以了(别忘了数据库表与Java Bean的映射关系,本项目使用的是Hibernate所以在xxxx.hbm.xml里编写四个属性的映射关系,由于基本上每个Bean都得写所以我找了个能够简化的方法,就是写一个公共xml文件存放四个字段的映射部分,让映射xml导入这个公共xml就好了,详情参考我的另外一篇文章讲解hbm.xml如何导入外部xml文件)
操作后我们可以查看数据库里是否插入成功
有记录代表成功!