Hibernate实践

一.             

在实际项目中使用Hibernate 有两年多了,在两年多的实践过程中既体验到了Hibernate 带来的N 多好处,同时也碰到不少的问题,特写此篇文章做个总结,记录自己在Hibernate 实践中的一些经验,希望对于新使用Hibernate 的朋友能有个帮助,避免走过多的弯路。

阅读本文前建议至少拥有Hibernate 的一些基本知识,因为本文不会去详细介绍相关的基本知识,最好就是先用Hibernate 开发了一个HelloWorld^_^

根据自己所经历的项目中使用Hibernate 所涉及的范围,本文从开发环境、开发、设计、性能、测试以及推荐的相关书籍方面进行讲述,本篇文档不会讲的非常细致,只是根据自己在实践时的经验提出一些建议,关于细致以及具体的部分请参阅《Hibernate Reference 》或推荐的相关书籍章节。

此文档的PDF 版本请到此下载:

http://www.blogjava.net/Files/BlueDavy/Hibernate 实践.rar

本文允许转载,但转载时请注明作者以及来源。

作者:BlueDavy

来源:www.blogjava.net/BlueDavy

二.              开发环境

Hibernate 开发环境的搭建非常的简单,不过为了提高基于Hibernate 开发的效率,通常都需要使用一些辅助工具,如xdocletmiddlegen 等。

尽管Hibernate 已经封装提供了很简单的进行持久的方法,但在实际项目的使用中基本还是要提供一些通用的代码,以便在进行持久的相关操作的时候能够更加的方便。

2.1. lib

2.1.1.        Hibernate lib

Hibernate 相关的 lib 自然是开发环境中首要的问题,这部分可以从 Hibernate 的官方网站进行下载,在其官方网站中同时提供了对于 Hibernate 所必须依赖的 lib 以及其他可选 lib 的介绍。

2.2. xdoclet

Hibernate 作为ORM 工具,从名字上就能看出它需要一个从O à RMapping 的描述,而这个描述就是在使用Hibernate 时常见的hbm.xml ,在没有工具支持的情况下,需要在编写持久层对象的同时手写这个文件,甚为不便。

jdk 5.0 未推出之前,xdoclet 支持的在javadoc 中编写注释生成相关配置文件的方式大受欢迎,减少了编写hibernate 映射文件的复杂性,手写一个完整的hibernate 映射文件出错几率比较的高,再加上手写容易造成编写出来的风格相差很大,因此,基于xdoclet 来生成hbm.xml 的方式被大量的采用,基于xdoclet 来编写能够基于我们在持久层对象上编写的javadoc 来生成hbm.xml 文件,非常的方便。

2.2.1.        Hibernate template

如果没记错的话,大概在 04 年的时候 javaeye 上有位同仁整理了一个这样的 template 文件, ^_^ ,非常感谢,我一直都在用着,呵呵。

这个文件的方便就是把它导入 eclipse 后,在 javadoc 中我们可以直接写 hibid ,然后按 eclipse 的代码辅助键 (alt+/) 来生成整个 hibernate.id 的相关的格式,呵呵,免得在写 hibernate.id 这些东西的时候过于麻烦, ^_^ ,这个 template 文件我稍微做了修改,可在这里下载:

http://www.blogjava.net/Files/BlueDavy/templates-eclipse-tags.rar

当然,你也可以选择直接用 xdoclet 提供的 template 文件,不过 xdoclet 官方网站上好像只提供了可直接导入 idea 的模板文件。

关于注释上的 hibernate.id 这些东西具体请参见 xdoclet 官方网站的说明。

如果你的项目采用的是 jdk 5 ,那么就可以直接使用 hibernate annotation 了,那就更为方便。

2.2.2.        Ant task build

Eclipse 里没有集成 xdoclet 的插件,你也可以去安装一个 jboss ide 的插件,里面有 xdoclet 的插件,反正我是觉得太麻烦了。

在项目中我仍然采用 ant task 的方式来生成 hbm.xmltarget 如下所示:

<path id="app.classpath">

<pathelement path="${java.class.path}"/>

<fileset dir="${xdoclib.dir}">

<include name="*.jar"/>

</fileset>

</path>

<target name="hbm" description=" 生成映射文件 ">

<tstamp>

<format property="TODAY" pattern="yy-MM-dd"/>

</tstamp>

<taskdef name="hibernatedoclet" classname="xdoclet.modules.hibernate.HibernateDocletTask" classpathref="app.classpath"/>

<hibernatedoclet destdir="src/java" force="true" verbose="true" excludedtags="@version,@author,@todo">

<fileset dir="src/java">  

<include name="**/po/**/*.java"/>

</fileset>

<hibernate version ="3.0"/>

</hibernatedoclet>

</target>

这个文件请根据项目情况以及环境稍做修改, ^_^ ,其中需要通过 properties 文件指明 xdocletlib.dir ,类似 xdocletlib.dir=c:\xdocletlib ,里面放置 xdoclet 的相关 jar 文件。

在搭建好了这样的环境后,就可以在直接在 eclipse 中运行 ant 文件中的这个 target 来生成 hbm.xml

2.3. Hibernate3 Tools

如果采用Hibernate 3 ,则可以直接下载Hibernate 3 ToolsEclipse Plugin ,那就可以类似在PL/SQL 里执行sql 一样在eclipse 里执行hql^_^

2.4. HibernateUtil

为了方便项目中Hibernate 的使用,一般来说都会提供HibernateUtil 这样的类,这个类的作用主要是创建sessionFactory 和管理session ,在Hibernate 3 以前采用的是在这里建立ThreadLocal 来存放session ,在Hibernate 3 以后则可以直接使用SessionFactory.getCurrentSession 来获取session ,而session 的获取方式则可通过在hibernate.cfg.xml 中执行current_session_context_class 的属性来决定是采用threadjta 或自定义的方式来产生session

2.5. CommonDao

在持久层部分目前采用的较多的仍然是dao 模式,Hibernate 作为ORM 工具已经提供了CRUD 的封装,类如可以使用session.save()session.persist() 这样简单的方式来完成CRUD 的操作,但在实际的项目中还是需要提供一个通用的Dao ,来简化对于事务、异常处理以及session 的操作,同时提供一些项目中需要的相关操作。

三.              开发

在完成了Hibernate 的开发环境的搭建后,就可以基于Hibernate 进行持久层的开发了,对于持久层开发来说,会涉及到实体的编写、实体的维护以及实体的查询三个部分。

3.1. 实体的编写

Hibernate 的一个明显的优点就是在于可透明化的对对象进行持久,这也就意味着持久对象根本就不需要依赖任何的东西,可以采用POJO 的方式来编写,在Hibernate 3 以上版本还提供了对于MapXML 的方式的持久的支持,就更方便了,在项目中,更多采用的仍然是POJO 的方式。

在实体的编写上应该说不会有什么问题,只要仔细查看xdoclet 关于hibernatedoclet 部分的说明即可完成。

这块需要学习的主要是普通的值类型注释的编写、id 字段注释的编写、关联注释的编写,这些部分xdoclet 均提供了较详细的说明。

3.2. 实体的维护

3.2.1.        新增 / 编辑 / 删除

新增 / 编辑 / 删除是持久操作中最常使用的维护性操作,基于 Hibernate 做这样的维护就比采用 sql 的方式简单多了,通过上面 CommonDao ,就可以直接完成 dao.savedao.updatedao.delete 的操作,而且在 Hibernate 3 也支持了批量的 insertupdatedelete

这个部分中需要注意的是 Hibernate 对于对象的三种状态的定义:

u       Transient

很容易理解,就是从未与 session 发生过关系的对象, ^_^ ,例如在代码中直接 User user=new User() ;这样形成的 user 对象,就称为 Transient 对象了。

u       Detached

同样很容易理解,就是与 session 发生过关系的对象,但 session 已经关闭了的情况下存在的对象,例如:

User user=new User();

user.setName(“bluedavy”);

session.save(user);

session.close();

session.close() 后这个时候的 user 对象就处于 Detached 状态之中了,如果想将这个对象变为 Persistent 状态,可以通过 session.mergesession.saveOrUpdate() 等方式来实现。

Detached 状态的对象在实际的应用中最常采用,从概念上我们可以这么理解,处于 Detached 状态的对象可以看做是一个 DTO ,而不是 PO ,这从很大程度上就方便了 PO 在实际项目中的使用了。

u       Persistent

Persistent 状态就是指和 Session 发生了关系的对象,并且此时 session 未关闭,举例如下:

User user=new User();

user.setName(“bluedavy”);

session.save(user);

user.getName();

session.saveuser 就处于 Persistent 状态,此时如果通过 session 根据 userid 去获取 user 对象,则可发现获取的对象和之前的 user 是同一个对象,这是 session 一级缓存所起的作用了,当然,也可以强制的刷新 session 的一级缓存,让 session 从数据库中重新获取,只需要在获取前执行 session.evict(user)session.clear()

3.2.2.        关联维护

关联维护在 Hibernate 中表现出来可能会让熟悉使用 sql 的人有些的不熟,但其实以对象的观点去看是会觉得很正常的。

Hibernate 的关联维护中,最重要的是 inversecascade 两个概念。

u       inverse

inverse 从词义上看过去可能不是那么容易理解,其实它的意思就是由谁来控制关联关系的自动维护,当 inverse=true 就意味着当前对象是不能自动维护关联关系,当 inverse=false 就意味着当前对象可自动维护关联关系,还是举例来说:

假设 OrgUser 一对多关联,

orggetUsersinverse=false 的情况:

org.getUsers().add(user);

dao.save(org);

这样执行后将会看到数据库中 user 这条记录中的 orgId 已经被设置上去了。

inverse=true 的情况下,执行上面的代码,会发现在数据库中 user 这条记录中的 orgId 没有被设置上去。

^_^invers

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值