RSS

Hibernate的事件监听机制

12 Apr

Hibernate的事件监听机制

1. Hibernate中的事件监听机制可以对Session对象的动作进行监听,一旦发生了特殊的事件,Hibernate就会执行监听器中的事件处理方法

2. 在某些功能的设计中,我们即可以使用Hibernate的拦截器实现,也可以使用Hibernate的事件监听来实现

 

Hibernate中事件对应的监听器接口
 

事件类型

监听器(Listener)接口

auto-flush

AutoFlushEventListener

merge

mergeEventListener

delete

DeleteEventListener

persist

PersistEventListener

dirty-check

DirtyCheckEventListener

evict

EvictEventListener

flush

FlushEventListener

flush-entity

FlushEventListener

load

LoadEventListener

load-collection

InitializeCollectionEventListener

lock

LockEventListener

refres

RefreshEventListener

replicate

ReplicateEventListener

save-update

SaveOrUpdateEventListener

pre-load

PreLoadEventListener

pre-update

PreUpdateEventListener

pre-delete

PreDeleteEventListener

pre-insert

PreInsertEventListener

post-load

PreLoadEventListener

post-update

PreUpdateEventListener

post-delete

PreDeleteEventListener

post-insert

PostInsertEventListener

 

应用Hibernate事件监听器

1. 用户定制的事件监听器首先要实现与所要处理的事件相对应的接口,或者继承实现这个接口的类

2. 通过使用Hibernate的配置文件(hibernate.cfg.xml)配置事件监听器的对象,或者使用Configuration对象注册这个定制的事件监听器的对象

 

编写LogPostLoadEventListener.java

public class LogPostLoadEventListener implements PostLoadEventListener{

public void onPostLoad(PostLoadEvent event){

System.out.println("Class:" + event.getEntity().getClass().getName() + "id: " +event.getID());

}

}

修改hibernate.cfg.xml文件

<listener type="post-load" class="hibernate.example.listener.LogPostLoadEventListener"/>

或者通过Configuration对象注册这个监听器对象
Configuration config = new Configuration();
config.setListener("post-load", new LogPostLoadEventListener());
config.configure();
Session session = config.buildSessionFactory().getCurrentSession();
代码如下:
LogPostLoadEventListener.java
package hibernate.example.test;

import org.hibernate.Session;

import hibernate.example.util.HibernateSessionFactoryUtil;

import hibernate.example.vo.GuestBook;

public class LogPostLoadEventListenerTest {

 

    public static void main(String[] args) {

        Session session = HibernateSessionFactoryUtil.getSessionFactory().getCurrentSession();

        session.beginTransaction();

        GuestBook gb = (GuestBook)session.load(GuestBook.class, 10004);

        System.out.println(gb.getName());

        session.getTransaction().commit();

    }

 

}


hibernate.cfg.xml
<listener type="post-load" class="hibernate.example.listener.LogPostLoadEventListener"/>

GuestBook.java
package hibernate.example.vo;

import java.util.Date;

public class GuestBook {

private Integer id;

private String name;

private String email;

private String phone;

private String title;

private String content;

private Date createdTime;

public Integer getId() {

return id;

}

public void setId(Integer id) {

this.id = id;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public String getEmail() {

return email;

}

public void setEmail(String email) {

this.email = email;

}

public String getPhone() {

return phone;

}

public void setPhone(String phone) {

this.phone = phone;

}

public String getTitle() {

return title;

}

public void setTitle(String title) {

this.title = title;

}

public String getContent() {

return content;

}

public void setContent(String content) {

this.content = content;

}

public Date getCreatedTime() {

return createdTime;

}

public void setCreatedTime(Date createdTime) {

this.createdTime = createdTime;

}

}


GuestBook.hbm.xml

<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

                                   "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="hibernate.example.vo">

<class name="GuestBook" table="GUESTBOOK">

<id column="id" name="id">

<generator class="hilo">

<param name="table">HIBERNATE_KEY</param>

<param name="column">next_hivalue</param>

</generator>

</id>

<property column="name" generated="never" lazy="false" name="name"

type="java.lang.String" />

<property column="email" generated="never" lazy="false" name="email"

type="java.lang.String" />

<property column="phone" generated="never" lazy="false" name="phone"

type="java.lang.String" />

<property column="title" generated="never" lazy="false" name="title"

type="java.lang.String" />

<property column="content" generated="never" lazy="false"

name="content" type="java.lang.String" />

<property column="created_time" generated="never" lazy="false"

name="createdTime" type="java.util.Date" />

</class>

</hibernate-mapping>


LogPostLoadEventListenerTest.java
package hibernate.example.test;

import org.hibernate.Session;

import hibernate.example.util.HibernateSessionFactoryUtil;

import hibernate.example.vo.GuestBook;

public class LogPostLoadEventListenerTest {

 

    public static void main(String[] args) {

        Session session = HibernateSessionFactoryUtil.getSessionFactory().getCurrentSession();

        session.beginTransaction();

        GuestBook gb = (GuestBook)session.load(GuestBook.class, 10004);

        System.out.println(gb.getName());

        session.getTransaction().commit();

    }

 

}

 

 

使用监听器实现审计日志

利用Hibernate的事件机制,不仅能够精确追踪到持久化对象的字段的修改、持久化对象关联关系的变更,还能记录更新前的数值和更新后的数值

Auditable.java

package hibernate.example.listener;

public interface Auditable {

 

}

GuestBook2.java

package hibernate.example.vo;

import hibernate.example.listener.Auditable;

import java.io.Serializable;

import java.util.Date;

@SuppressWarnings("serial")

public class GuestBook2 implements Serializable, Auditable{

    private Integer id;

    private String name;

    private String email;

    private String phone;

    private String title;

    private String content;

    private Date createdTime;

   

    public Integer getId() {

        return id;

    }

    public void setId(Integer id) {

        this.id = id;

    }

    public String getName() {

        return name;

    }

    public void setName(String name) {

        this.name = name;

    }

    public String getEmail() {

        return email;

    }

    public void setEmail(String email) {

        this.email = email;

    }

    public String getPhone() {

        return phone;

    }

    public void setPhone(String phone) {

        this.phone = phone;

    }

    public String getTitle() {

        return title;

    }

    public void setTitle(String title) {

        this.title = title;

    }

    public String getContent() {

        return content;

    }

    public void setContent(String content) {

        this.content = content;

    }

    public Date getCreatedTime() {

        return createdTime;

    }

    public void setCreatedTime(Date createdTime) {

        this.createdTime = createdTime;

    }

   

}

 

GuestBook2.hbm.xml

<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

                                   "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="hibernate.example.vo">

<class name="GuestBook2" table="GUESTBOOK">

<id column="id" name="id">

<generator class="hilo">

<param name="table">HIBERNATE_KEY</param>

<param name="column">next_hivalue</param>

</generator>

</id>

<property column="name" generated="never" lazy="false" name="name"

type="java.lang.String" />

<property column="email" generated="never" lazy="false" name="email"

type="java.lang.String" />

<property column="phone" generated="never" lazy="false" name="phone"

type="java.lang.String" />

<property column="title" generated="never" lazy="false" name="title"

type="java.lang.String" />

<property column="content" generated="never" lazy="false"

name="content" type="java.lang.String" />

<property column="created_time" generated="never" lazy="false"

name="createdTime" type="java.util.Date" />

</class>

</hibernate-mapping>

 

OperationType.java

package hibernate.example.listener;

public enum OperationType{

LOAD, CREATE, UPDATE, DELETE;

}

AuditLog.java

package hibernate.example.vo;

import java.util.Date;

public class AuditLog {

private Integer id;

private String entityName;

private String entityId;

private Date createdTime;

private String OperationType;

public AuditLog(){

}

public Integer getId() {

return id;

}

public void setId(Integer id) {

this.id = id;

}

public String getEntityName() {

return entityName;

}

public void setEntityName(String entityName) {

this.entityName = entityName;

}

public String getEntityId() {

return entityId;

}

public void setEntityId(String entityId) {

this.entityId = entityId;

}

public Date getCreatedTime() {

return createdTime;

}

public void setCreatedTime(Date createdTime) {

this.createdTime = createdTime;

}

public String getOperationType() {

return OperationType;

}

public void setOperationType(String operationType) {

OperationType = operationType;

}

}

 

AuditLog.hbm.xml

<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>

    <class name="hibernate.example.vo.AuditLog" table="AUDIT_LOG">

        <id name="id" type="java.lang.Integer">

            <column name="ID" />

            <generator class="increment" />

        </id>

        <property name="entityName" type="java.lang.String">

            <column name="ENTITY_NAME" />

        </property>

        <property name="entityId" type="java.lang.String">

            <column name="ENTITY_ID" />

        </property>

        <property name="createdTime" type="java.util.Date">

            <column name="CREATED_TIME" />

        </property>

        <property name="OperationType" type="java.lang.String">

            <column name="OPERATION_TYPE" />

        </property>

    </class>

</hibernate-mapping>

 

AuditLogEventListener.java

package hibernate.example.listener;

import hibernate.example.vo.AuditLog;

import org.hibernate.Session;

import org.hibernate.event.PostDeleteEvent;

import org.hibernate.event.PostDeleteEventListener;

import org.hibernate.event.PostInsertEvent;

import org.hibernate.event.PostInsertEventListener;

import org.hibernate.event.PostUpdateEvent;

import org.hibernate.event.PostUpdateEventListener;

 

@SuppressWarnings("serial")

public class AuditLogEventListener implements PostUpdateEventListener,

PostInsertEventListener, PostDeleteEventListener {

 

@Override

public void onPostDelete(PostDeleteEvent event) {

if(event.getEntity() instanceof Auditable){

String entityName = event.getEntity().getClass().getName();

AuditLog log = new AuditLog();

log.setEntityName(entityName);

log.setEntityId(event.getId().toString());

log.setOperationType(OperationType.DELETE.toString());

log.setCreatedTime(new java.util.Date());

saveAuditLog(event.getSession(), log);

}

}

 

@Override

public void onPostInsert(PostInsertEvent event) {

if(event.getEntity() instanceof Auditable){

String entityName = event.getEntity().getClass().getName();

AuditLog log = new AuditLog();

log.setEntityName(entityName);

log.setEntityId(event.getId().toString());

log.setOperationType(OperationType.CREATE.toString());

log.setCreatedTime(new java.util.Date());

saveAuditLog(event.getSession(), log);

}

 

}

 

@Override

public void onPostUpdate(PostUpdateEvent event) {

if(event.getEntity() instanceof Auditable){

String entityName = event.getEntity().getClass().getName();

AuditLog log = new AuditLog();

log.setEntityName(entityName);

log.setEntityId(event.getId().toString());

log.setOperationType(OperationType.UPDATE.toString());

log.setCreatedTime(new java.util.Date());

saveAuditLog(event.getSession(), log);

}

 

}

private void saveAuditLog(Session session, AuditLog log){

Session logsession = session.getSessionFactory().openSession();

logsession.beginTransaction();

logsession.save(log);

logsession.getTransaction().commit();

logsession.close();

}

 

}

AuditLogEventListenerTest.java

package hibernate.example.test;

import org.hibernate.Session;

import hibernate.example.util.HibernateSessionFactoryUtil;

import hibernate.example.vo.GuestBook2;

public class AuditLogEventListenerTest {

 

    public static void main(String[] args) {

        new AuditLogEventListenerTest().testAuditLogByEvent();

    }

   

    public void testAuditLogByEvent(){

        Session session = HibernateSessionFactoryUtil.getSessionFactory().getCurrentSession();

       

        GuestBook2 gb = new GuestBook2();

        gb.setName("Gabriel");

        gb.setEmail("gabriel@gmail.com");

        gb.setPhone("114");

        gb.setCreatedTime(new java.util.Date());

        gb.setTitle("Das is ein Buch!");

        gb.setContent("Das ist ein Buch");

       

        session.beginTransaction();

        session.save(gb);

        session.getTransaction().commit();

       

        gb.setName("Mike");

        session = HibernateSessionFactoryUtil.getSessionFactory().getCurrentSession();

        session.beginTransaction();

        session.update(gb);

        session.getTransaction().commit();     

       

        session = HibernateSessionFactoryUtil.getSessionFactory().getCurrentSession();

        session.beginTransaction();

        session.delete(gb);

        session.getTransaction().commit();             

       

    }

}

 

监听器与拦截器的比较

1. 监听器可以实现更加细粒度上的拦截

2. 通过监听器获取拦截的持久化对象的修改后和修改前的状态值

3. 能通过Event对象获取Session对象

Advertisements
 
Leave a comment

Posted by on 04/12/2011 in HIBERNATE

 

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

 
%d bloggers like this: