论文部分内容阅读
摘要:文章在面向对象程序设计中的数据持久化问题的背景下,分析了Hibernate的结构及运行机理,并将其与CMP做了对比,然后根据实际项目经验总结出实际开发中的一些实践准则,使初级开发者可以能够尽快地把握Hibernate的应用技巧,充分利用Hibernate的优点,提高开发效率,增强系统的稳定性、可移植性。
关键字:面向对象;Hibernate;持久层;最佳实践
中图分类号:TP312文献标识码:A文章编号:1009-2374(2009)02-0074-02
OOP即面向对象的程序设计(Object-Oriented Programming),是目前占据主流地位的一种程序设计思想。在软件工程的各个阶段运用并体现面向对象的思想,已经成为软件分析、设计、开发的基本方法。但对象只能存在于内存中,而内存不能永久保存数据。如果要永远保存对象的状态,需要进行对象的持久化,即把对象存储到专门的数据存储中。
关系数据库是目前数据持久化存储的主要形式。关系数据库系统中存放的是关系数据,是非面向对象的,其操作的特点是“集合性”的,因而关系数据本身是无法表现出对象之间存在的关联和继承关系。
于是,在面向对象的软件设计中使用关系数据库做为数据的持久化方式,就必然需要进行对象-关系的映射(Object/Relation Mapping,简称ORM)。那么,如何能够以较低的代价在对象和关系模型之间相互转化,提高系统的开发效率就成了一个非常重要的问题。幸运的是ORM框架——Hibernate为人们解决了这一问题。越来越多的Java开发人员把Hibernate作为企业应用和关系数据库之间的中间件。使用Hibernate,开发者可以采用面向对象的方法操作数据库,提高工作效率[1]。
一、Hibernate
Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了轻量级的对象封装,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。Hibernate可以应用在任何使用JDBC的场合,既可以在Java的客户端程序使用,也可以在Servlet/JSP的Web应用中使用,最具革命意义的是,Hibernate可以在应用EJB的J2EE架构中取代CMP[2],完成数据持久化的重任。
(一)Hibernate体系结构
Hibernate体系结构如图一所示。可以看出,Hibernate是Java应用和关系数据库之间的桥梁,它将应用层对对象的操作通过XMLMapping转化为针对关系数据库特定操作,使程序员专注于业务逻辑的开发,而不用关心数据库的操作问题。Hibernate以hibernate.properties或hibernate.cfg.xml作为系统配置文件,并通过类映射文件(*.hbm.xml)将实体类映射到数据库中的表,为应用程序提供持久化服务[3]。
(二)Hibernate的核心接口
Hibernate的核心接口一共有5个,分别为:Session、SessionFactory、Transaction、Query和Configuration。这5个核心接口在任何开发中都会用到。下面对这五的核心接口分别加以介绍。
Session接口负责执行被持久化对象的CRUD(Create,Retrieve,Update,Delete)操作。但需要注意的是Session对象是非线程安全的。
SessionFactroy接口负责初始化Hibernate。它充当数据存储源的代理,并负责创建Session对象。需要注意的是SessionFactory并不是轻量级的,一般情况下,一个项目通常只需要一个SessionFactory就够,当需要操作多个数据库时,可以为每个数据库指定一个SessionFactory。
Configuration接口负责配置并启动Hibernate,创建SessionFactory对象。在Hibernate的启动的过程中,Configuration类的实例首先定位映射文档位置、读取配置,然后创建SessionFactory对象。
Transaction接口负责事务相关的操作。它是可选的,开发人员也可以设计编写自己的底层事务处理代码。
Query和Criteria接口负责执行各种数据库查询。它可以使用HQL语言或SQL语句两种表达方式。
二、Hibernate与CMP的对比
J2EE的标准是CMP Entity Bean,而实际应用中受到诟病最多的也是它。Hibernate至少比CMP2.0有以下优点:
1.兼容性。EJB的规范是固定的,但是各个软件厂商的实现却是各不相同的,这样就造成学习了厂商A的EJB使用后,在使用厂商B的EJB组件时又要重新学习相关的使用手册,这样就势必造成资源的浪费。
2.性能。Hibernate的操作是本地调用,CMP2.0虽然也有Local接口,但是Web层还是需要通过Remote接口访问EJB层的数据。那么序列化、网络调用等过程必将造成性能的下降。
3.动态Query。Entity Bean很难实现动态Query,这是因为它基于代码自动生成技术,即最终的执行代码是在部署编译时生成的。而Hibernate则有根本的改变,它基于reflection机制,运行时动态Query是很自然的事。另外,Hibernate几乎支持所有的SQL语法,传统数据库可以做的它就可以做。
4.发展速度。EJB是许多大的软件公司共同协商、制定的一套标准,其更新改进的速度远远无法与Hibernate相比。Hibernate的核心程序员只有一人,而且以开源的方式在全世界这个范围内发布,在大量的开发人员努力下不断地改进,它改进的速度是EJB无法相比的。
三、最佳实践
Hibernate是一个非常优秀的ORM框架,但这并不意味着它是万能的、自动的,就像好车还得要技术高超的司机来驾驶才能发挥出应有的性能一样。在实际使用中,用户需要深入了解应用的需求,并结合Hibernate的自身特点来进行准确而有效的设计。通过对许多项目的分析,笔者总结出一些实践准则如下:
1.设计细颗粒度的持久类并且使用来实现映射。
2.对持久类声明标识符属性(identifier properties),标识符应该是自动生成、不涉及业务含义。
3.对所有的实体都标识出自然键,用进行映射。实现equals()和hashCode()。
4.考虑把查询字符串放在程序外面,让程序具有更好的可移植性。
5.在查询中使用命名参数。
6.不要自己来管理JDBC connections。
7.考虑使用用户自定义类型(custom type)。
8.在性能瓶颈的地方使用硬编码的JDBC,但一定要确认这些操作直接使用JDBC会更好。
9.理解Session清洗(flushing),避免过于频繁flushing。
10.对于关联优先考虑lazy fetching,但要注意缓存限制。
11.考虑把Hibernate代码从业务逻辑代码中抽象出来。
12.不要用怪异的连接映射,偏爱双向关联,在大型应用中,几乎所有的关联必须在查询中可以双向导航。
13.关于Map文件的生成,既可以在数据库设计完成后使用工具一次性的生成Mapping文件,也可以在软件的编码中嵌入数据说明,然后使用XDoclet[4]来自动生成Mapping文件。
四、结语
虽然Hibernate有这诸多的优点,但目前来看Hibernate也存在着缺点,比如:Hibernate提供了自动生成mapping文件的工具,但还需根据具体应用做必要的手工调整。总之,Hibernate虽然是一个优秀的工具,但是其效能的发挥是以开发人员对系统的理解为基础的,只有合理设计关系数据库,并根据应用中不同的性能需求做相应的设计,才能充分地发挥Hibernate的优点,简化持久层开发,提高系统的开发效率。
参考文献
[1]孙卫琴.精通Hibernate:Java对象持久化技术详解[M].北京:电子工业出版社,2005.
[2]杨绍方.深入掌握J2EE编程技术[M].科学出版社,2002.
[3]蔡雪焘.Hibernate开发及整合应用大全[M].北京:清华大学出版社,2006.
[4](德)Christian Bauer,(澳)Gavin King 著,杨春花,彭永康,俞黎敏译.Hibernate实战(第2版)[M].北京:人民邮电出版社,2008.
关键字:面向对象;Hibernate;持久层;最佳实践
中图分类号:TP312文献标识码:A文章编号:1009-2374(2009)02-0074-02
OOP即面向对象的程序设计(Object-Oriented Programming),是目前占据主流地位的一种程序设计思想。在软件工程的各个阶段运用并体现面向对象的思想,已经成为软件分析、设计、开发的基本方法。但对象只能存在于内存中,而内存不能永久保存数据。如果要永远保存对象的状态,需要进行对象的持久化,即把对象存储到专门的数据存储中。
关系数据库是目前数据持久化存储的主要形式。关系数据库系统中存放的是关系数据,是非面向对象的,其操作的特点是“集合性”的,因而关系数据本身是无法表现出对象之间存在的关联和继承关系。
于是,在面向对象的软件设计中使用关系数据库做为数据的持久化方式,就必然需要进行对象-关系的映射(Object/Relation Mapping,简称ORM)。那么,如何能够以较低的代价在对象和关系模型之间相互转化,提高系统的开发效率就成了一个非常重要的问题。幸运的是ORM框架——Hibernate为人们解决了这一问题。越来越多的Java开发人员把Hibernate作为企业应用和关系数据库之间的中间件。使用Hibernate,开发者可以采用面向对象的方法操作数据库,提高工作效率[1]。
一、Hibernate
Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了轻量级的对象封装,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。Hibernate可以应用在任何使用JDBC的场合,既可以在Java的客户端程序使用,也可以在Servlet/JSP的Web应用中使用,最具革命意义的是,Hibernate可以在应用EJB的J2EE架构中取代CMP[2],完成数据持久化的重任。
(一)Hibernate体系结构
Hibernate体系结构如图一所示。可以看出,Hibernate是Java应用和关系数据库之间的桥梁,它将应用层对对象的操作通过XMLMapping转化为针对关系数据库特定操作,使程序员专注于业务逻辑的开发,而不用关心数据库的操作问题。Hibernate以hibernate.properties或hibernate.cfg.xml作为系统配置文件,并通过类映射文件(*.hbm.xml)将实体类映射到数据库中的表,为应用程序提供持久化服务[3]。
(二)Hibernate的核心接口
Hibernate的核心接口一共有5个,分别为:Session、SessionFactory、Transaction、Query和Configuration。这5个核心接口在任何开发中都会用到。下面对这五的核心接口分别加以介绍。
Session接口负责执行被持久化对象的CRUD(Create,Retrieve,Update,Delete)操作。但需要注意的是Session对象是非线程安全的。
SessionFactroy接口负责初始化Hibernate。它充当数据存储源的代理,并负责创建Session对象。需要注意的是SessionFactory并不是轻量级的,一般情况下,一个项目通常只需要一个SessionFactory就够,当需要操作多个数据库时,可以为每个数据库指定一个SessionFactory。
Configuration接口负责配置并启动Hibernate,创建SessionFactory对象。在Hibernate的启动的过程中,Configuration类的实例首先定位映射文档位置、读取配置,然后创建SessionFactory对象。
Transaction接口负责事务相关的操作。它是可选的,开发人员也可以设计编写自己的底层事务处理代码。
Query和Criteria接口负责执行各种数据库查询。它可以使用HQL语言或SQL语句两种表达方式。
二、Hibernate与CMP的对比
J2EE的标准是CMP Entity Bean,而实际应用中受到诟病最多的也是它。Hibernate至少比CMP2.0有以下优点:
1.兼容性。EJB的规范是固定的,但是各个软件厂商的实现却是各不相同的,这样就造成学习了厂商A的EJB使用后,在使用厂商B的EJB组件时又要重新学习相关的使用手册,这样就势必造成资源的浪费。
2.性能。Hibernate的操作是本地调用,CMP2.0虽然也有Local接口,但是Web层还是需要通过Remote接口访问EJB层的数据。那么序列化、网络调用等过程必将造成性能的下降。
3.动态Query。Entity Bean很难实现动态Query,这是因为它基于代码自动生成技术,即最终的执行代码是在部署编译时生成的。而Hibernate则有根本的改变,它基于reflection机制,运行时动态Query是很自然的事。另外,Hibernate几乎支持所有的SQL语法,传统数据库可以做的它就可以做。
4.发展速度。EJB是许多大的软件公司共同协商、制定的一套标准,其更新改进的速度远远无法与Hibernate相比。Hibernate的核心程序员只有一人,而且以开源的方式在全世界这个范围内发布,在大量的开发人员努力下不断地改进,它改进的速度是EJB无法相比的。
三、最佳实践
Hibernate是一个非常优秀的ORM框架,但这并不意味着它是万能的、自动的,就像好车还得要技术高超的司机来驾驶才能发挥出应有的性能一样。在实际使用中,用户需要深入了解应用的需求,并结合Hibernate的自身特点来进行准确而有效的设计。通过对许多项目的分析,笔者总结出一些实践准则如下:
1.设计细颗粒度的持久类并且使用
2.对持久类声明标识符属性(identifier properties),标识符应该是自动生成、不涉及业务含义。
3.对所有的实体都标识出自然键,用
4.考虑把查询字符串放在程序外面,让程序具有更好的可移植性。
5.在查询中使用命名参数。
6.不要自己来管理JDBC connections。
7.考虑使用用户自定义类型(custom type)。
8.在性能瓶颈的地方使用硬编码的JDBC,但一定要确认这些操作直接使用JDBC会更好。
9.理解Session清洗(flushing),避免过于频繁flushing。
10.对于关联优先考虑lazy fetching,但要注意缓存限制。
11.考虑把Hibernate代码从业务逻辑代码中抽象出来。
12.不要用怪异的连接映射,偏爱双向关联,在大型应用中,几乎所有的关联必须在查询中可以双向导航。
13.关于Map文件的生成,既可以在数据库设计完成后使用工具一次性的生成Mapping文件,也可以在软件的编码中嵌入数据说明,然后使用XDoclet[4]来自动生成Mapping文件。
四、结语
虽然Hibernate有这诸多的优点,但目前来看Hibernate也存在着缺点,比如:Hibernate提供了自动生成mapping文件的工具,但还需根据具体应用做必要的手工调整。总之,Hibernate虽然是一个优秀的工具,但是其效能的发挥是以开发人员对系统的理解为基础的,只有合理设计关系数据库,并根据应用中不同的性能需求做相应的设计,才能充分地发挥Hibernate的优点,简化持久层开发,提高系统的开发效率。
参考文献
[1]孙卫琴.精通Hibernate:Java对象持久化技术详解[M].北京:电子工业出版社,2005.
[2]杨绍方.深入掌握J2EE编程技术[M].科学出版社,2002.
[3]蔡雪焘.Hibernate开发及整合应用大全[M].北京:清华大学出版社,2006.
[4](德)Christian Bauer,(澳)Gavin King 著,杨春花,彭永康,俞黎敏译.Hibernate实战(第2版)[M].北京:人民邮电出版社,2008.