hibernate拦截器的用途之一

来源:互联网 发布:mac怎么共享 编辑:程序博客网 时间:2024/06/07 02:47


举个实际的例子, 偶们有时候会需要做Audit: 一条记录什么时候被谁创建, 以及最近由谁在何时更新, 以前的做法是在代码里面各处分散地写上:
Java代码
  1. entity.setCreated(new Date(););;    
  2. entity.setCreatedBy(userId);;    
  3. session.save(entity);;  


这样重复的代码就到处都是了, 很不爽呢, OOP号称的once and only once不应该是这样的吧, 让偶们来看看Interceptor它怎么帮忙解决这个问题

先来定义一个mark性质的interface:
Java代码
  1. public interface Auditable {    
  2.     public AuditInfo getAuditInfo();;    
  3.     public void setAuditInfo(AuditInfo auditInfo);;    
  4. }   

    然后是AuditInfo, 用来记录这些信息:
Java代码
  1. public final class AuditInfo implements Serializable {    
  2.     private Date lastUpdated;    
  3.     private Date created;    
  4.     private String updatedBy;    
  5.     private String createdBy;    
  6.     //getter, setter   
  7. }   

如果偶们的一个业务对象需要有这样能够被Audit的功能, 那么就让它实现Auditable这个接口:
Java代码
  1. public class FooBean implements Auditable {    
  2.     private Long id;   
  3.     private String bar;        
  4.     private AuditInfo auditInfo = new AuditInfo();;    
  5.     //getter, setter   
  6. }   


然后定义mapping文件:
Xml代码
  1. <class name="FooBean">    
  2.  <id name="id">    
  3.   <generator class="native"/>    
  4.  </id>    
  5.  <property name="bar"/>    
  6.  <property name="auditInfo" type="readonly.persistence.hibernate.type.AuditInfoType">    
  7.    <column name="LAST_UPDATED"/>    
  8.    <column name="CREATED"/>    
  9.    <column name="UPDATED_BY"/>    
  10.    <column name="CREATED_BY"/>    
  11.  </property>    
  12. </class>   


然后告诉Hibernate, 在打开session的时候用一个自定义的Interceptor :

Java代码
  1. public void testCreated(); {    
  2.     Session session = sf.openSession (new MockAuditInterceptor(););;   
  3.     FooBean foo = new FooBean();;    
  4.     foo.setBar("abc");;    
  5.     session.save(foo);;   
  6.     session.flush();;   
  7.     session.close();;   
  8.     assertNotNull(foo.getAuditInfo();.getCreated(););;    
  9.     assertEquals("mock", foo.getAuditInfo();.getCreatedBy(););;    
  10. }   


That's all, 比原来简单多了, 以后如果你有新的Entity需要这个特性的话, implements Auditable一下, 就OK了, 这样就达到了代码重用的目的了.

Interceptor的用处有很多, 就看偶们怎么从一堆代码中, 总结一些可以公用的特性了, 以此类推, 还能做EntityCRUDPermissionInterceptor, HistoryInterceptor, SearchIndexInterceptor等等......
原创粉丝点击