Hibernate对象管理研究
2015-01-06王琦袁鹏博陈义明
王琦+袁鹏博+陈义明
摘要:该文分析了Hibernate框架在应用程序持久层的位置、原理和重要意义。深入研究了Hibernate对象生命周期中的三种状态及其转化关系,并用实际开发中的典型程序段进行了直观形象地说明。阐明了Hibernate的Session缓存对数据持久性能的优化机制[1]。对准确、高效地操作Hibernate对象,编写高质量的持久层应用程序具有重要的参考价值。
关键词:Hibernate实体对象;生命周期;Session缓存;ORM
中图分类号:TP311 文献标识码:A 文章编号:1009-3044(2014)34-8165-02
Java是一种纯粹的面向对象语言,适合于对现实世界的行为进行建模。JavaEE(Java Enterprise Edition)是Sun公司(现已被Oracle公司收购)提出的企业级分布式应用开发规范。因其开放性,有大量优秀的第三方软件公司提供组件支持而受到软件开发者的普遍推崇。
目前,大量的信息系统使用的都是关系型数据库,即以二维表的形式存储数据,应用系统将处理的数据长久地存储到数据库的过程叫做持久化。由于JavaEE系统操作的都是对象,持久化过程需要将对象转成关系表存储。反过来,应用系统操纵关系表中的数据时,需要将取出来的数据封装为java能够操作的对象。上述正反过程叫做ORM(Object-Relationship Mapping,对象关系映射)。为了避免重复书写ORM代码,给系统维护带来不便,同时也为了提高软件开发效率及质量,一些优秀的ORM映射框架脱颖而出,Hibernate就是一款优秀的ORM映射框架[1-2]。
1 Hibernate框架及ORM
Hibernate是JDBC(Java Database Connection,java数据库连接)轻量级的对象封装,是一个独立的对象持久层框架。具有如下显著优势:
1) 应用程序在访问数据库时,Hibernate简化了数据访问层代码,并且对这些代码进行了封装;
2) Hibernate是轻量级框架,很灵活、性能非常好,支持多种数据库平台;
3) 具有相对的独立性,如果底层数据库发生改变,修改持久层配置文件即可。只要提供的API(Application Programming Interface)不变,则上层的业务逻辑层不用修改[3];
Hibernate框架有两个重要功能:
1) 对象关系映射ORM
通常来说,一个持久化类对应数据库的一张表,类的每个实例对应表中的一条记录,对象的属性对应表的一个字段,关系数据表之间的关系体现为对象之间的关联关系。面向对象和面向关系概念之间的对应关系如表1所示[4]:
2) 对象管理
ORM(对象关系映射)在关系型数据库中的表和应用程序中对象之间作一个自动的映射关联会起到很大的作用,而在实际操作数据库时,只须通过HQL(Hibernate Query Language对象操作语言)直接操纵对象即可。Hibernate框架负责管理对象,其中的ORM工具会自动将对象的操作转换为SQL语句操作并进行事务管理。
2 Hibernate实体对象生命周期及状态转化[3]
2.1 实体对象生命周期[3]
在java语言中,当用new关键词开辟内存空间创建一个Java对象(以Customer对象为例)时,这个Java对象就开始进入其生命周期。如果没有变量对该对象进行引用,就结束其生命周期,而其所占用的内存就会被JVM的垃圾回收器回收。
应用Hibernate框架进行持久管理,支持下列三种对象状态:
1) 临时状态(Transient):当用new语句创建临时的一个对象,这个对象就占用了内存;但此时该对象在数据库中还没有对应记录,没有给对象分配持久化标识符或是还没有被持久化,与Hibernate的Session毫无关系。Java对象处于临时状态就称为临时对象[4-6]。
2) 持久化状态(Persistent):临时对象或是游离状态通过调用session的相应方法转化为持久化对象,此时已被分配到一个持久化标识符,在数据库中已有了相关记录;同时被加载到Session缓存中,与Session的实例关联,服从Session的统一调度。Java对象处于持久化状态下就称为持久化对象[4-6]。
3) 游离(脱管)状态(Detached):该状态下的对象已经被持久化过,是由持久化对象转化而来。即使不在session缓存中,但还会被分配一个持久化标志符,也就是在数据库中还有相对应的数据,这是不同于临时对象的。当相关Session被关闭后,调用相应的Session方法,但还是能够重新进入到一个新的会话缓存中。Java对象处于游离状态就称为游离对象[4-6]。
Hibernate实体对象三种状态的特征如表2所示。
2.2 Session接口与状态转化
Session作为Hibernate的第一级缓存,是Hibernate向应用程序提供对象操作的主要接口,它的特定方法能使对象从一个状态转化到另一个状态。Hibernate生命周期的各状态及他们之间的转换如图1所示。
图1显示:对象的临时状态经Session的save()方法或saveOrUpdate()转变为持久状态;持久状态经Session的close()、evict()、clear()方法转变为游离状态;游离状态或者持久状态转变为临时状态都是进行Session的delete()操作;临时状态或游离状态下的Java对象,没有其他变量引用它,或者没有与Session缓存关联,JVM的垃圾回收器就会回收java对象所占用的内存,随之它的生命周期彻底结束;若对象处于持久化状态中,在数据库中有对应记录,始终被分配一个持久化标志,Session缓存会引用它,始终占据着内存,如果不进行delete操作,它就始终处于生命周期中。endprint
图2中的代码段显示了对象Customer生命周期的三种状态及其转化。在语句(1)中实例化的customer对象没有与数据库中的记录关联,并且没有被Session缓存管理,因此属于临时对象。语句(2)打开一个会话,获取数据库连接,直到语句(5)关闭会话,将数据库连接归还到连接池,其中的对象受到Session缓存的管理。语句(3)开始一个数据库事务,直到语句(5)提交结束该事务,语句(3)和(5)之间是数据库的操作,通过语句(5)的事务提交使Session缓存对象持久化,和数据库保持一致。因此,可以判断语句(6)中的对象c是持久化对象。语句(8)中的对象在数据库中有对应的记录,但脱离了Session缓存的管理,属于游离对象,如果没有其他对象引用,将被java垃圾回收器回收[4]。
3 Hibernate对象持久优化[6]
Hibernate的Session具有一个由一些集合属性构成的缓存,持久对象的引用保存在集合中,在这些集合中的对象和数据库中的相关记录始终保持着对应,始终使这些Session中的持久化对象永远处于生命周期。Session在某些具体的时间点,按照缓存中持久化对象的属性和状态变化更新数据库,并且与关系数据库的记录保持一致的过程称为清理缓存[5]。
3.1 Session缓存的意义[5]
Session缓存对于数据持久具有十分重要的意义:
1) 降低数据库访问频率,优化数据库访问性能:从内存中读取对象,节省了访问数据库步骤和时间,从而提高程序运行效率。
2) 如果会话缓存中的持久化对象之间是相互循环关联的,Session缓存会杜绝出现程序访问对象图时出现死循环的现象,和由产生的死循环而引发的异常状况,比如内存泄露,堆栈溢出。
3) 实现Session缓存中的持久化对象与关系数据库中的数据保持一致。如果Session缓存中持久化对象的状态改变时,有可能变为临时对象或者游离对象,但在Session缓存中会按照相应的顺序调用session的方法,或者将多条相关的SQL语句合成,程序运行的效率提高,而数据库的访问减少,系统性能实现优化。
3.2 Session缓存清理行为
Hibernate的Session清理缓存是根据缓存中对象的状态变化,按特定顺序执行相关的SQL语句来同步更新数据库的。
1) 一开始程序会调用session.save()方法,将临时对象持久化,让对象变为持久化对象;
2) 再执行insert语句,插入所有的实体对象,刚插入进来的实体对象服从Session的调度管理;
3) 然后执行update语句,对所有实体对象进行更新操作;
4) 接着执行delete语句,对所有集合(List、Map、Set)进行删除操作;
5) 同样是插入、更新、删除的SQL语句,再对所有集合(List、Map、Set)里的元素进行对应操作;
6) 还是执行insert插入操作,这次是对所有集合(List、Map、Set)进行插入;
7) 最后一步调用session.delete()的方法,删除所有实体对象,清空缓存,腾出内存。以上为完整的Session清理缓存的过程,将缓存里的持久化对象转化为临时对象,再用JVM的垃圾回收器将不在占用内存的临时对象回收。
3.3 Session缓存清理时间点[6]
在Session缓存中用setFlushMode()方法来设置清理缓存的时间点。FlushMode类定义了三种不同的清理模式:FlushMode.AUTO、FlushMode.COMMIT、FlushMode.NEVER。
如果选用FulshMode.AUTO模式,在这种模式下session.find(),session.iterate(),transaction.commit(),session.flush()等Session的多种方法和事务管理都能执行清理缓存行为。
如果选用FlushMode.COMMIT模式,在这种模式下的session.flush(),transaction.commit()都能执行清理缓存;
如果选用FulshMode.NEVER模式,在这种模式下transaction.commit()不能清理缓存,session.find()也不清理缓存,就只能通过session.flush()来清理。
无论设置在哪种FlushMode清理模式,session.flush()都将会去清理缓存,从上述可知优先考虑使用FlusthMode.AUTO,很方便地无须手动执行session.flush()。
4 总结
Hibernate是一种轻量级的数据持久层框架,使用它能够高效、高质量地开发出JavaEE应用程序。论文对Hibernate对象管理机制进行了深入的研究和探讨,对准确、高效地开发持久层应用程序具有重要的意义。
参考文献:
[1] Gavin King,Christian Bauer,Max Rydahl Andersen,et,al.Hibernate Reference Documentation
[2] 李刚.轻量级Java EE企业应用实战:Struts 2+Spring 4+Hibernate整合开发[M]. 4版.北京:电子工业出版社,2014.
[3] 鲍尔,金著.Hibernate实战[M].2版·英文版.北京:人民邮电出版社,2009.
[4] 孙卫琴.精通Hibernate:Java对象持久化技术详解[M].2版.北京:电子工业出版社,2010.
[5] 树头孤鸟.妙解Hibernate.3.X-叩响面向对象思想之门[M].北京:电子工业出版社,2010.
[6] Christian Bauer,Gavin King.Hibernate实战[M]. 杨春花,译.2版·中文版.北京:人民邮电出版社,2008.endprint
图2中的代码段显示了对象Customer生命周期的三种状态及其转化。在语句(1)中实例化的customer对象没有与数据库中的记录关联,并且没有被Session缓存管理,因此属于临时对象。语句(2)打开一个会话,获取数据库连接,直到语句(5)关闭会话,将数据库连接归还到连接池,其中的对象受到Session缓存的管理。语句(3)开始一个数据库事务,直到语句(5)提交结束该事务,语句(3)和(5)之间是数据库的操作,通过语句(5)的事务提交使Session缓存对象持久化,和数据库保持一致。因此,可以判断语句(6)中的对象c是持久化对象。语句(8)中的对象在数据库中有对应的记录,但脱离了Session缓存的管理,属于游离对象,如果没有其他对象引用,将被java垃圾回收器回收[4]。
3 Hibernate对象持久优化[6]
Hibernate的Session具有一个由一些集合属性构成的缓存,持久对象的引用保存在集合中,在这些集合中的对象和数据库中的相关记录始终保持着对应,始终使这些Session中的持久化对象永远处于生命周期。Session在某些具体的时间点,按照缓存中持久化对象的属性和状态变化更新数据库,并且与关系数据库的记录保持一致的过程称为清理缓存[5]。
3.1 Session缓存的意义[5]
Session缓存对于数据持久具有十分重要的意义:
1) 降低数据库访问频率,优化数据库访问性能:从内存中读取对象,节省了访问数据库步骤和时间,从而提高程序运行效率。
2) 如果会话缓存中的持久化对象之间是相互循环关联的,Session缓存会杜绝出现程序访问对象图时出现死循环的现象,和由产生的死循环而引发的异常状况,比如内存泄露,堆栈溢出。
3) 实现Session缓存中的持久化对象与关系数据库中的数据保持一致。如果Session缓存中持久化对象的状态改变时,有可能变为临时对象或者游离对象,但在Session缓存中会按照相应的顺序调用session的方法,或者将多条相关的SQL语句合成,程序运行的效率提高,而数据库的访问减少,系统性能实现优化。
3.2 Session缓存清理行为
Hibernate的Session清理缓存是根据缓存中对象的状态变化,按特定顺序执行相关的SQL语句来同步更新数据库的。
1) 一开始程序会调用session.save()方法,将临时对象持久化,让对象变为持久化对象;
2) 再执行insert语句,插入所有的实体对象,刚插入进来的实体对象服从Session的调度管理;
3) 然后执行update语句,对所有实体对象进行更新操作;
4) 接着执行delete语句,对所有集合(List、Map、Set)进行删除操作;
5) 同样是插入、更新、删除的SQL语句,再对所有集合(List、Map、Set)里的元素进行对应操作;
6) 还是执行insert插入操作,这次是对所有集合(List、Map、Set)进行插入;
7) 最后一步调用session.delete()的方法,删除所有实体对象,清空缓存,腾出内存。以上为完整的Session清理缓存的过程,将缓存里的持久化对象转化为临时对象,再用JVM的垃圾回收器将不在占用内存的临时对象回收。
3.3 Session缓存清理时间点[6]
在Session缓存中用setFlushMode()方法来设置清理缓存的时间点。FlushMode类定义了三种不同的清理模式:FlushMode.AUTO、FlushMode.COMMIT、FlushMode.NEVER。
如果选用FulshMode.AUTO模式,在这种模式下session.find(),session.iterate(),transaction.commit(),session.flush()等Session的多种方法和事务管理都能执行清理缓存行为。
如果选用FlushMode.COMMIT模式,在这种模式下的session.flush(),transaction.commit()都能执行清理缓存;
如果选用FulshMode.NEVER模式,在这种模式下transaction.commit()不能清理缓存,session.find()也不清理缓存,就只能通过session.flush()来清理。
无论设置在哪种FlushMode清理模式,session.flush()都将会去清理缓存,从上述可知优先考虑使用FlusthMode.AUTO,很方便地无须手动执行session.flush()。
4 总结
Hibernate是一种轻量级的数据持久层框架,使用它能够高效、高质量地开发出JavaEE应用程序。论文对Hibernate对象管理机制进行了深入的研究和探讨,对准确、高效地开发持久层应用程序具有重要的意义。
参考文献:
[1] Gavin King,Christian Bauer,Max Rydahl Andersen,et,al.Hibernate Reference Documentation
[2] 李刚.轻量级Java EE企业应用实战:Struts 2+Spring 4+Hibernate整合开发[M]. 4版.北京:电子工业出版社,2014.
[3] 鲍尔,金著.Hibernate实战[M].2版·英文版.北京:人民邮电出版社,2009.
[4] 孙卫琴.精通Hibernate:Java对象持久化技术详解[M].2版.北京:电子工业出版社,2010.
[5] 树头孤鸟.妙解Hibernate.3.X-叩响面向对象思想之门[M].北京:电子工业出版社,2010.
[6] Christian Bauer,Gavin King.Hibernate实战[M]. 杨春花,译.2版·中文版.北京:人民邮电出版社,2008.endprint
图2中的代码段显示了对象Customer生命周期的三种状态及其转化。在语句(1)中实例化的customer对象没有与数据库中的记录关联,并且没有被Session缓存管理,因此属于临时对象。语句(2)打开一个会话,获取数据库连接,直到语句(5)关闭会话,将数据库连接归还到连接池,其中的对象受到Session缓存的管理。语句(3)开始一个数据库事务,直到语句(5)提交结束该事务,语句(3)和(5)之间是数据库的操作,通过语句(5)的事务提交使Session缓存对象持久化,和数据库保持一致。因此,可以判断语句(6)中的对象c是持久化对象。语句(8)中的对象在数据库中有对应的记录,但脱离了Session缓存的管理,属于游离对象,如果没有其他对象引用,将被java垃圾回收器回收[4]。
3 Hibernate对象持久优化[6]
Hibernate的Session具有一个由一些集合属性构成的缓存,持久对象的引用保存在集合中,在这些集合中的对象和数据库中的相关记录始终保持着对应,始终使这些Session中的持久化对象永远处于生命周期。Session在某些具体的时间点,按照缓存中持久化对象的属性和状态变化更新数据库,并且与关系数据库的记录保持一致的过程称为清理缓存[5]。
3.1 Session缓存的意义[5]
Session缓存对于数据持久具有十分重要的意义:
1) 降低数据库访问频率,优化数据库访问性能:从内存中读取对象,节省了访问数据库步骤和时间,从而提高程序运行效率。
2) 如果会话缓存中的持久化对象之间是相互循环关联的,Session缓存会杜绝出现程序访问对象图时出现死循环的现象,和由产生的死循环而引发的异常状况,比如内存泄露,堆栈溢出。
3) 实现Session缓存中的持久化对象与关系数据库中的数据保持一致。如果Session缓存中持久化对象的状态改变时,有可能变为临时对象或者游离对象,但在Session缓存中会按照相应的顺序调用session的方法,或者将多条相关的SQL语句合成,程序运行的效率提高,而数据库的访问减少,系统性能实现优化。
3.2 Session缓存清理行为
Hibernate的Session清理缓存是根据缓存中对象的状态变化,按特定顺序执行相关的SQL语句来同步更新数据库的。
1) 一开始程序会调用session.save()方法,将临时对象持久化,让对象变为持久化对象;
2) 再执行insert语句,插入所有的实体对象,刚插入进来的实体对象服从Session的调度管理;
3) 然后执行update语句,对所有实体对象进行更新操作;
4) 接着执行delete语句,对所有集合(List、Map、Set)进行删除操作;
5) 同样是插入、更新、删除的SQL语句,再对所有集合(List、Map、Set)里的元素进行对应操作;
6) 还是执行insert插入操作,这次是对所有集合(List、Map、Set)进行插入;
7) 最后一步调用session.delete()的方法,删除所有实体对象,清空缓存,腾出内存。以上为完整的Session清理缓存的过程,将缓存里的持久化对象转化为临时对象,再用JVM的垃圾回收器将不在占用内存的临时对象回收。
3.3 Session缓存清理时间点[6]
在Session缓存中用setFlushMode()方法来设置清理缓存的时间点。FlushMode类定义了三种不同的清理模式:FlushMode.AUTO、FlushMode.COMMIT、FlushMode.NEVER。
如果选用FulshMode.AUTO模式,在这种模式下session.find(),session.iterate(),transaction.commit(),session.flush()等Session的多种方法和事务管理都能执行清理缓存行为。
如果选用FlushMode.COMMIT模式,在这种模式下的session.flush(),transaction.commit()都能执行清理缓存;
如果选用FulshMode.NEVER模式,在这种模式下transaction.commit()不能清理缓存,session.find()也不清理缓存,就只能通过session.flush()来清理。
无论设置在哪种FlushMode清理模式,session.flush()都将会去清理缓存,从上述可知优先考虑使用FlusthMode.AUTO,很方便地无须手动执行session.flush()。
4 总结
Hibernate是一种轻量级的数据持久层框架,使用它能够高效、高质量地开发出JavaEE应用程序。论文对Hibernate对象管理机制进行了深入的研究和探讨,对准确、高效地开发持久层应用程序具有重要的意义。
参考文献:
[1] Gavin King,Christian Bauer,Max Rydahl Andersen,et,al.Hibernate Reference Documentation
[2] 李刚.轻量级Java EE企业应用实战:Struts 2+Spring 4+Hibernate整合开发[M]. 4版.北京:电子工业出版社,2014.
[3] 鲍尔,金著.Hibernate实战[M].2版·英文版.北京:人民邮电出版社,2009.
[4] 孙卫琴.精通Hibernate:Java对象持久化技术详解[M].2版.北京:电子工业出版社,2010.
[5] 树头孤鸟.妙解Hibernate.3.X-叩响面向对象思想之门[M].北京:电子工业出版社,2010.
[6] Christian Bauer,Gavin King.Hibernate实战[M]. 杨春花,译.2版·中文版.北京:人民邮电出版社,2008.endprint