Hibernate的事件机制文档格式.docx
- 文档编号:18441471
- 上传时间:2022-12-16
- 格式:DOCX
- 页数:12
- 大小:19.20KB
Hibernate的事件机制文档格式.docx
《Hibernate的事件机制文档格式.docx》由会员分享,可在线阅读,更多相关《Hibernate的事件机制文档格式.docx(12页珍藏版)》请在冰豆网上搜索。
publicvoidonDelete(Objectentity,Serializableid,Object[]
state,String[]propertyNames,Type[]types)
{
//donothing
}
//同步Session和数据库中的数据
publicbooleanonFlushDirty(Objectentity,Serializableid,Object[]
currentState,Object[]previousState,String[]propertyNames,Type[]
types)
//每同步一次,修改的累加器加1
updates++;
for(inti=0;
i<
propertyNames.length;
i++)
if("
lastUpdateTimestamp"
.equals(propertyNames[i]))
currentState[i]=newDate();
returntrue;
returnfalse;
//加载持久化实例时,调用该方法
publicbooleanonLoad(Objectentity,Serializableid,Object[]
state,String[]propertyNames,Type[]types)
System.out.println("
========================"
);
name"
System.out.println(state[i]);
state[i]="
aaa"
;
//保存持久化实例时,调用该方法
publicbooleanonSave(Objectentity,Serializableid,Object[]
creates++;
i<
propertyNames.length;
createTimestamp"
state[i]=newDate();
//提交刷新
publicvoidpostFlush(Iteratorentities)
创建的次数:
"
+creates+"
更新的次数:
+
updates);
publicvoidpreFlush(Iteratorentities)
updates=0;
creates=0;
//事务提交前,触发该方法
publicvoidbeforeTransactionCompletion(Transactiontx)
事务即将结束"
//事务提交后,触发该方法
publicvoidafterTransactionCompletion(Transactiontx)
事务已经结束"
}
在上面的拦截器实现类中,实现了很多方法,这些方法都是在Hibernate执行特定动作时自动调用。
完成了拦截器的定义,下面是关于拦截器的使用。
拦截器的使用有两种方法:
●通过SessionFactory的openSession(Interceptorin)方法打开一个带局部拦截器的Session。
●通过Configuration的setInterceptor(Interceptorin)方法设置全局拦截器。
下面是使用局部拦截器的示例代码:
publicclassHibernateUtil
//静态类属性SessionFactory
publicstaticfinalSessionFactorysessionFactory;
//静态初始化块,完成静态属性的初始化
static
try
//采用默认的hibernate.cfg.xml来启动一个Configuration的实例
Configurationconfiguration=newConfiguration().configure();
//由Configuration的实例来创建一个SessionFactory实例
sessionFactory=configuration.buildSessionFactory();
catch(Throwableex)
System.err.println("
初始化sessionFactory失败."
+ex);
thrownewExceptionInInitializerError(ex);
//ThreadLocal是隔离多个线程的数据共享,不存在多个线程之间共享资源,因此不再需要
对线程同步
publicstaticfinalThreadLocalsession=newThreadLocal();
//不加拦截器的打开Session方法
publicstaticSessioncurrentSession()throwsHibernateException
Sessions=(Session)session.get();
//如果该线程还没有Session,则创建一个新的Session
if(s==null)
s=sessionFactory.openSession();
//将获得的Session变量存储在ThreadLocal变量的Session里
session.set(s);
returns;
//加拦截器的打开Session方法
publicstaticSessioncurrentSession(Interceptorit)throws
HibernateException
//以拦截器创建Session对象
s=sessionFactory.openSession(it);
//关闭Session对象
publicstaticvoidcloseSession()throwsHibernateException
if(s!
=null)
s.close();
session.set(null);
上面的Hibernate工具类提供了两个currentSession方法,分别用于不使用拦截器获取Session对象和使用拦截器获取Session对象。
下面是主程序使用拦截器的代码片段:
privatevoidtestUser()
//以拦截器开始Session
Sessionsession=HibernateUtil.currentSession(newMyInterceptor());
//开始事务
Transactiontx=session.beginTransaction();
//执行下面的代码时,可以看到系统回调onSave等方法
/*
Useru=newUser();
u.setName("
YeekuLee"
u.setAge(28);
u.setNationality("
中国"
session.persist(u);
u.setAge(29);
u.setAge(30);
*/
//执行下面的代码时,可以看到系统回调onLoad等方法
Objecto=session.load(User.class,newInteger
(1));
System.out.println(o);
Useru=(User)o;
System.out.println(u.getName());
//提交事务时,可以看到系统回调事务相关方法
mit();
HibernateUtil.closeSession();
4.8.2事件系统
Hibernate3的事件系统是功能更强大的事件框架,事件系统可以替代拦截器,也可以作为拦截器的补充来使用。
基本上,Session接口的每个方法都有对应的事件。
如LoadEvent和FlushEvent等。
当Session调用某个方法时,HibernateSession会生成对应的事件,并激活对应的事件监听器。
系统默认监听器实现的处理过程,完成了所有的数据持久化操作,包括插入和修改等操作。
如果用户定义了自己的监听器,则意味着用户必须完成对象的持久化操作。
例如,可以在系统中实现并注册LoadEventListener监听器,该监听器负责处理所有调用Session的load()方法的请求。
监听器是单态模式对象,即所有同类型的事件处理共享同一个监听器实例,因此监听器不应该保存任何状态,即不应该使用成员变量。
使用事件系统可按如下步骤进行:
(1)实现自己的事件监听器类;
(2)注册自定义事件监听器,代替系统默认的事件监听器。
实现用户的自定义监听器有如下3个方法:
●实现对应的监听器接口,这是不可思议的,实现接口必须实现接口内的所有方法,关键是必须实现Hibernate对应的持久化操作,即数据库访问,这意味着程序员完全取代了Hibernate的底层操作。
●继承事件适配器,可以选择性地实现需要关注的方法,但依然试图取代Hibernate完成数据库的访问,这也不太现实。
●继承系统默认的事件监听器,扩展特定方法。
实际上,前两种方法很少使用。
因为Hibernate的持久化操作也是通过这些监听器实现的,如果用户取代了这些监听器,则应该自己实现所有的持久化操作,这意味着用户放弃了Hibernate的持久化操作,而改为自己完成Hibernate的核心操作。
通常推荐采用第三种方法实现自己的事件监听器。
Hibernate默认的事件监听器都被声明成non-final,从而方便用户继承。
下面是用户自定义监听器的示例:
//自定义LoadListener,继承默认的DefaultLoadEventListener实现类
publicclassMyLoadListenerextendsDefaultLoadEventListener
//在LoadEventListener接口仅仅定义了这个方法
publicObjectonLoad(LoadEventevent,LoadEventListener.LoadType
loadType)throwsHibernateException
//先调用父类的onLoad方法,从而完成默认的持久化操作
Objecto=super.onLoad(event,loadType);
//加入用户的自定义处理
自定义的load事件"
System.out.println(event.getEntityClassName()+"
=========="
event.getEntityId());
returno;
下面还有一个MySaveListener,用于监听SaveEvent事件:
//自定义SavaListener,继承默认的DefaultSaveEventListener实现类
publicclassMySaveListenerextendsDefaultSaveEventListener
//该方法完成实际的数据插入动作
protectedSerializableperformSaveOrUpdate(SaveOrUpdateEventevent)
//先执行用户自定义的操作
System.out.println(event.getObject());
//调用父类的默认持久化操作
returnsuper.performSaveOrUpdate(event);
注意:
扩展用户自定义监听器时,别忘了在方法中调用父类的对应方法。
注册用户自定义监听器也有两种方法:
●编程式,通过使用Configuration对象编程注册。
●声明式,在Hibernate的XML格式配置文件中进行声明,使用Properties格式的配置文件将无法配置自定义监听器。
下面的示例代码,通过编程方式使用自定义监听器:
publicclassHibernateUtil2
Configurationcfg=newConfiguration();
//注册loadEventListener监听器
cfg.getSessionEventListenerConfig().setLoadEventListener
(newMyLoadListener());
//注册saveListener监听器
cfg.getSessionEventListenerConfig().setSaveEventListener
(newMySaveListener());
//由Configuration实例来创建一个SessionFactory实例
sessionFactory=cfg.configure().buildSessionFactory();
对线程同步
如果不想修改代码,也可以在配置文件中使用事件监听器,注册事件监听器的Hibernate配置文件代码如下:
<
?
xmlversion='
1.0'
encoding='
GBK'
>
!
--Hibernate配置文件的文件头,包含DTD等信息-->
DOCTYPEhibernate-configurationPUBLIC
-//Hibernate/HibernateConfigurationDTD3.0//EN"
dtd"
--Hibernate配置文件的根元素-->
hibernate-configuration>
<
session-factory>
—设置数据库驱动-->
propertyname="
connection.driver_class"
com.mysql.jdbc.Driver
/property>
--数据库服务的url-->
connection.url"
jdbc:
mysql:
//localhost/hibernate
--数据库服务的用户名-
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Hibernate 事件 机制