使用 Hibernate 的 PostInsertEventListener, PostUpdateEventListener, PostDeleteEventListener 做日志管理
Hibernate 为我们提供了事件监听机制,我们只需要实现相应的监听器,就可以追踪到对象的修改,比如 PostInsertEventListener, PostUpdateEventListener, PostDeleteEventListener、PostLoadEventListener等等,都在 org.hibernate.event.spi 包中。
1、实现 PostInsertEventListener, PostUpdateEventListener, PostDeleteEventListener
package com.***.listener;
import com.***.entity.LogEntity;
import com.***.enums.LogType;
import com.***.manager.LogManager;
import com.***.utils.SysUserUtil;
import com.***.UserDto;
import org.hibernate.event.spi.*;
import org.hibernate.persister.entity.EntityPersister;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Date;
@Component
public class LogListener implements PostInsertEventListener, PostUpdateEventListener, PostDeleteEventListener {
@Autowired
private LogManager logManager;
@Override
public void onPostDelete(PostDeleteEvent event) {
UserDto user = SysUserUtil.getCurrentUser();
if(null != user) {
LogEntity log = new LogEntity();
log.setOperatorTime(new Date());
log.setObjectId((Long) event.getId());
log.setObjectName(event.getEntity().getClass().getSimpleName());
log.setEvent("delete");
log.setRemark("删除");
log.setOperatorName(user.getUsername());
log.setOperatorId(user.getId());
log.setType(LogType.MANAGER.getCode());
logManager.save(log);
}
}
@Override
public void onPostInsert(PostInsertEvent event) {
UserDto user = SysUserUtil.getCurrentUser();
if(null != user && !"LogEntity".equals(event.getEntity().getClass().getSimpleName())) {
LogEntity log = new LogEntity();
log.setOperatorTime(new Date());
log.setObjectId((Long) event.getId());
log.setObjectName(event.getEntity().getClass().getSimpleName());
log.setEvent("insert");
log.setRemark("新增");
log.setOperatorName(user.getUsername());
log.setOperatorId(user.getId());
log.setType(LogType.MANAGER.getCode());
logManager.save(log);
}
}
/**
* 当对属性进行更新操作时,记录日志,同时备注发生变更的字段以及变更前后的值
* @param event
*/
@Override
public void onPostUpdate(PostUpdateEvent event) {
UserDto user = SysUserUtil.getCurrentUser();
if(null != user) {
Object[] oldState = event.getOldState();
Object[] newState = event.getState();
if(!oldState.equals(newState)) {
LogEntity log = new LogEntity();
log.setOperatorTime(new Date());
log.setObjectId((Long) event.getId());
log.setObjectName(event.getEntity().getClass().getSimpleName());
log.setEvent("update");
log.setOperatorName(user.getUsername());
log.setOperatorId(user.getId());
log.setType(LogType.MANAGER.getCode());
StringBuilder remark = new StringBuilder("");
for(int i=0, length=oldState.length; i<length; i++) {
Object oldValue = oldState[i];
Object newValue = newState[i];
if(!(oldValue == null && newValue == null)) {
if(isDate(newValue)) {
newValue = formatDate(newValue);
}
if(isDate((oldValue))) {
oldValue = formatDate(oldValue);
}
if(oldValue == null || newValue == null) {
remark.append(event.getPersister().getPropertyNames()[i]+":"+oldValue+" -> "+newValue+";");
} else {
if(!oldValue.equals(newValue)) {
remark.append(event.getPersister().getPropertyNames()[i]+":"+oldValue+" -> "+newValue+";");
}
}
}
}
log.setRemark(remark.toString());
logManager.save(log);
}
}
}
@Override
public boolean requiresPostCommitHanding(EntityPersister persister) {
return false;
}
private boolean isDate(Object date) {
if(date == null) {
return false;
} else {
if(date instanceof Date || date instanceof java.sql.Date || date instanceof Timestamp) {
return true;
}
}
return false;
}
private String formatDate(Object date) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String dateStr = "";
if(date instanceof Date) {
dateStr = sdf.format(date);
} else if(date instanceof java.sql.Date) {
dateStr = sdf.format(new Date(((java.sql.Date) date).getTime()));
} else if(date instanceof Timestamp) {
dateStr = sdf.format(new Date(((Timestamp) date).getTime()));
} else {
dateStr = String.valueOf(date);
}
return dateStr;
}
}
2、注册监听器,可以在spring容器启动后进行注册(在Spring启动后执行一些操作)。
package *****;
import org.hibernate.SessionFactory;
import org.hibernate.event.service.spi.EventListenerRegistry;
import org.hibernate.event.spi.EventType;
import org.hibernate.internal.SessionFactoryImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;
import javax.persistence.EntityManagerFactory;
@Component
public class LogRegListener implements ApplicationListener<ContextRefreshedEvent> {
@Autowired
private EntityManagerFactory entityManagerFactory;
@Autowired
private LogListener logListener;
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
if (event.getApplicationContext().getParent() == null) {//父容器为null就表示是root applicationContext
/**
* 获取SessionFactory的方式:1、直接注入SessionFactory;2、如果用的是 JPA 的话,那么需要通过entityManagerFactory来得到SessionFactory
*/
EventListenerRegistry registry = ((SessionFactoryImpl)entityManagerFactory.unwrap(SessionFactory.class)).getServiceRegistry().getService(EventListenerRegistry.class);
registry.getEventListenerGroup(EventType.POST_INSERT).appendListener(logListener);
registry.getEventListenerGroup(EventType.POST_UPDATE).appendListener(logListener);
registry.getEventListenerGroup(EventType.POST_DELETE).appendListener(logListener);
}
}
}