hibernate 监听器记录数据变化信息

时间:2022-03-24 22:40:38
package com.ezparking.web;

import com.ezparking.model.CustomerServe;
import com.ezparking.model.UserDataLog;
import com.ezparking.util.WebUtils;
import org.hibernate.event.internal.DefaultLoadEventListener;
import org.hibernate.event.service.spi.EventListenerRegistry;
import org.hibernate.event.spi.*;
import org.hibernate.internal.SessionFactoryImpl;
import org.hibernate.persister.entity.EntityPersister;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.annotation.PostConstruct;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.servlet.http.HttpServletRequest;
import java.sql.Timestamp;
import java.util.Optional;

@Component
public class UserDataLogListener extends DefaultLoadEventListener implements PostUpdateEventListener, PostInsertEventListener, PostDeleteEventListener {

	private static final String[] OBJECTS_SKIPPED = {"PoiStatusLog", "CustomerLog", "UserLog", "UserDataLog", "UserCoordinate"};

	private static final Logger logger = LoggerFactory.getLogger(UserDataLogListener.class);

	@Autowired
	private EntityManagerFactory entityManagerFactory;

	@PostConstruct
	public void registerListeners() {
		logger.info("register listeners ******");
		SessionFactoryImpl sessionFactoryImpl = entityManagerFactory.unwrap(SessionFactoryImpl.class);
		EventListenerRegistry eventListenerRegistry = sessionFactoryImpl.getServiceRegistry().getService(EventListenerRegistry.class);
		eventListenerRegistry.getEventListenerGroup(EventType.POST_INSERT).appendListener(this);
		eventListenerRegistry.getEventListenerGroup(EventType.POST_UPDATE).appendListener(this);
		eventListenerRegistry.getEventListenerGroup(EventType.POST_DELETE).appendListener(this);
	}

	@Override
	public void onPostInsert(PostInsertEvent event) {
		logger.info("insert start***********");

		if (!requiresLog(event.getEntity().getClass())) {
			return;
		}

		if (StringUtils.isEmpty(getUserId()) || StringUtils.isEmpty(getLogId())) {
			return;
		}
		logger.debug(event.getEntity() + " inserted");

		long startTime = System.currentTimeMillis();
		StringBuilder fields = new StringBuilder();
		StringBuilder afterValues = new StringBuilder();
		StringBuilder remark = new StringBuilder();

		for (int i = 0; i < event.getState().length; i++) {
			fields.append(event.getPersister().getPropertyNames()[i] + "|");
			afterValues.append(event.getState()[i] + "|");
			remark.append(event.getPersister().getPropertyNames()[i] + ": ");
			remark.append(event.getState()[i] + "\r\n");
		}

		UserDataLog userDataLog = new UserDataLog();
		userDataLog.setUserId(getUserId());
		userDataLog.setLogId(getLogId());
		userDataLog.setFields(fields.toString());
		userDataLog.setAfterValues(afterValues.toString());
		userDataLog.setRemark(remark.toString());
		userDataLog.setObject(event.getEntity().getClass().getSimpleName());
		userDataLog.setObjectKey(event.getId().toString());
		userDataLog.setOperation("INSERT");
		userDataLog.setLogTime(new Timestamp(System.currentTimeMillis()));

		this.persistLog(userDataLog);

		long endTime = System.currentTimeMillis();
		logger.debug("日志时间: " + (endTime - startTime) + "ms");
	}

	@Override
	public void onPostUpdate(PostUpdateEvent event) {
		logger.info("update start***********");
		if (!requiresLog(event.getEntity().getClass())) {
			return;
		}

		if (StringUtils.isEmpty(getUserId()) || StringUtils.isEmpty(getLogId())) {
			return;
		}
		logger.debug(event.getEntity() + " updated");

		long startTime = System.currentTimeMillis();
		StringBuilder fields = new StringBuilder();
		StringBuilder beforeValues = new StringBuilder();
		StringBuilder afterValues = new StringBuilder();
		StringBuilder remark = new StringBuilder();

		for (int i = 0; i < event.getState().length; i++) {
			// Object oldValue = event.getOldState()[i];
			// Object newValue = event.getState()[i];
			// String propertyName = event.getPersister().getPropertyNames()[i];
			// logger.info(propertyName + ": " + oldValue + " -> " + newValue);
			fields.append(event.getPersister().getPropertyNames()[i] + "|");
			beforeValues.append(event.getOldState()[i] + "|");
			afterValues.append(event.getState()[i] + "|");
		}

		for (int i = 0; i < event.getDirtyProperties().length; i++) {
			int j = event.getDirtyProperties()[i];
			remark.append(event.getPersister().getPropertyNames()[j] + ": ");
			remark.append(event.getOldState()[j] + " -> ");
			remark.append(event.getState()[j] + "\r\n");
		}

		UserDataLog userDataLog = new UserDataLog();
		userDataLog.setUserId(getUserId());
		userDataLog.setLogId(getLogId());
		userDataLog.setFields(fields.toString());
		userDataLog.setBeforeValues(beforeValues.toString());
		userDataLog.setAfterValues(afterValues.toString());
		//dl.setFields(serialize(event.getPersister().getPropertyNames()));
		//dl.setBeforeValues(serialize(event.getOldState()));
		//dl.setAfterValues(serialize(event.getState()));
		userDataLog.setRemark(remark.toString());
		userDataLog.setObject(event.getEntity().getClass().getSimpleName());
		userDataLog.setObjectKey(event.getId().toString());
		userDataLog.setOperation("UPDATE");
		userDataLog.setLogTime(new Timestamp(System.currentTimeMillis()));

		this.persistLog(userDataLog);

		long endTime = System.currentTimeMillis();
		logger.debug("日志时间: " + (endTime - startTime) + "ms");
	}

	@Override
	public void onPostDelete(PostDeleteEvent event) {
		logger.info("delete start***********");
		if (!requiresLog(event.getEntity().getClass())) {
			return;
		}

		if (StringUtils.isEmpty(getUserId()) || StringUtils.isEmpty(getLogId())) {
			return;
		}
		logger.debug(event.getEntity() + " removed");

		long startTime = System.currentTimeMillis();
		StringBuilder fields = new StringBuilder();
		StringBuilder beforeValues = new StringBuilder();
		UserDataLog userDataLog = new UserDataLog();
		userDataLog.setUserId(getUserId());
		userDataLog.setLogId(getLogId());
		userDataLog.setFields(fields.toString());
		userDataLog.setBeforeValues(beforeValues.toString());
		userDataLog.setObject(event.getEntity().getClass().getSimpleName());
		userDataLog.setObjectKey(event.getId().toString());
		userDataLog.setOperation("REMOVE");
		userDataLog.setLogTime(new Timestamp(System.currentTimeMillis()));
		this.persistLog(userDataLog);
		long endTime = System.currentTimeMillis();
		logger.debug("日志时间: " + (endTime - startTime) + "ms");
	}

	private void persistLog(UserDataLog userDataLog) {
		EntityManager em = entityManagerFactory.createEntityManager();
		try {
			em.getTransaction().begin();
			em.persist(userDataLog);
			em.getTransaction().commit();
		} finally {
			em.close();
		}
	}

	@Override
	public boolean requiresPostCommitHanding(EntityPersister persister) {
		return false;
	}

	private boolean requiresLog(Class<?> clazz) {
		for (String clsName : OBJECTS_SKIPPED) {
			if (clsName.equals(clazz.getSimpleName())) {
				return false;
			}
		}
		return true;
	}

	private Integer getLogId() {
		HttpServletRequest request = WebUtils.getHttpRequest();
		if (request == null) {
			return null;
		}
		Integer logId = (Integer) request.getSession().getAttribute("logId");
		return logId;
	}

	private String getUserId() {
		HttpServletRequest request = WebUtils.getHttpRequest();
		if (request == null) {
			return null;
		}
		CustomerServe customerServe = (CustomerServe) request.getAttribute("serve");
		if (customerServe == null || StringUtils.isEmpty(customerServe.getApp())) {
			return null;
		}

		return Optional.ofNullable(customerServe.getDeviceId()).orElse(customerServe.getLinkedKey());
	}
}