Hibernate4 拦截器(Interceptor) 实现实体类增删改的日志记录

转自:https://blog.csdn.net/he90227/article/details/44783099

开发应用程序的过程中,经常会对一些比较重要的数据修改都需要写日志。在实际工作的工程中,这些数据都是存在表中的, 一个常见的做法是用触发器,在增删改的时候,用触发器将数据写入到另一张表中去,但个人不推荐这么做,原因如下:
1. 如果有多个表,得写很多触发器。
2. 触发器与数据库特性关联太紧,不同的数据库,虽然思路一样,但语法却不太一样。
对数据库表操作的日志记录,完全可以利用Hibernate的Interceptor特性来实现,也就是拦截器。下面用一个具体的例子来说明如何使用Hibernate的Interceptor。

创建一个表,用来记录日志的表 

Create TABLE  `auditlog` (   `AUDIT_LOG_ID` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,   `ACTION` VARCHAR(100) NOT NULL,   `DETAIL` text NOT NULL,   `CreateD_DATE` DATE NOT NULL,   `ENTITY_ID` BIGINT(20) UNSIGNED NOT NULL,   `ENTITY_NAME` VARCHAR(255) NOT NULL,   PRIMARY KEY (`AUDIT_LOG_ID`) ) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8;



创建这个表对应的实体类:

@Entity
@Table(name = "auditlog") public class AuditLog implements java.io.Serializable {     private Long auditLogId;     private String action;     private String detail;     private Date createdDate;     private long entityId;     private String entityName;     public AuditLog() {     }     public AuditLog(String action, String detail, Date createdDate,             long entityId, String entityName) {         this.action = action;         this.detail = detail;         this.createdDate = createdDate;         this.entityId = entityId;         this.entityName = entityName;     }     @Id     @GeneratedValue(strategy = IDENTITY)     @Column(name = "AUDIT_LOG_ID", unique = true, nullable = false)     public Long getAuditLogId() {         return this.auditLogId;     }         .... 余下部分可以参考提供下载的源代码.



创建一个接口,所有实现了这个接口的实体类,都会写日志

package com.mkyong.interceptor; //market interface public interface IAuditLog {         public Long getId();         public String getLogDeatil(); }


这里有两个方法,getId,getLogDetail 需要实现类去实现具体的方法,也就是要被写入到日志表中的详细记录.

创建一个类实现了IAuditLog 接口,并给出接口方法的具体实现

@Entity
@Table(name="stock") public class Stock implements java.io.Serializable,IAuditLog  {     private static final long serialVersionUID = 1L;     @Id     @GeneratedValue(strategy=GenerationType.AUTO)     @Column(name="STOCK_ID")     private Integer stockId;          @Column(name="STOCK_CODE", length=10)     private String stockCode;          @Column(name="STOCK_NAME", length=20)     private String stockName;     public Stock() {     }     public Stock(String stockCode, String stockName) {         this.stockCode = stockCode;         this.stockName = stockName;     }     ....省略部分getter,setter     @Transient     public Long getId(){         return this.stockId.longValue();     }          @Transient     public String getLogDeatil(){         StringBuilder sb = new StringBuilder();         sb.append(" Stock Id : ").append(stockId)         .append(" Stock Code : ").append(stockCode)         .append(" Stock Name : ").append(stockName);         return sb.toString();     } }



创建记录日志的工具类,所有写日志公用 

public class AuditLogUtil{          public static void LogIt(String action,         IAuditLog entity){                  Session tempSession = HibernateUtil.getSessionFactory().openSession();                      try {             tempSession.getTransaction().begin();             AuditLog auditRecord = new AuditLog(action,entity.getLogDeatil()                     , new Date(),entity.getId(), entity.getClass().toString());             tempSession.save(auditRecord);             tempSession.getTransaction().commit();                      } finally {                 tempSession.close();                      }                  } }



创建 Hibernate interceptor 拦截器,这是重点,这里拦截所有需要记录日志的类,并处理 

public class AuditLogInterceptor extends EmptyInterceptor{          Session session;     private Set inserts = new HashSet();     private Set updates = new HashSet();     private Set deletes = new HashSet();          public void setSession(Session session) {         this.session=session;     }              @Override     public String onPrepareStatement(String sql) {         System.out.println("execute sql: " + sql);         return super.onPrepareStatement(sql);     }     public boolean onSave(Object entity,Serializable id,         Object[] state,String[] propertyNames,Type[] types)         throws CallbackException {                  System.out.println("onSave");                  if (entity instanceof IAuditLog){             inserts.add(entity);         }         return false;                  }          public boolean onFlushDirty(Object entity,Serializable id,         Object[] currentState,Object[] previousState,         String[] propertyNames,Type[] types)         throws CallbackException {              System.out.println("onFlushDirty");                  if (entity instanceof IAuditLog){             updates.add(entity);         }         return false;              }          public void onDelete(Object entity, Serializable id,         
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值