Hibernate4实战 之第七部分:最佳实践

设计细颗粒度的持久类而且使用<component>来实现映射。
例如使用一个Address持久类来封装 street, suburb, state, postcode. 这将有利于代码重用和简化代码重构(refactoring)的工做。
对持久类声明标识符属性( identifier properties)
Hibernate中标识符属性是可选的,不过有不少缘由来讲明你应该使用标识符属性。咱们建议标识符应该是“人造”的(自动生成,不涉及业务含义)。
使用天然键(natural keys)标识
对全部的实体都标识出天然键,用<natural-id>进行映射。实现equals()和hashCode(),在其中用组成天然键的属性进行比较。
为每一个持久类写一个映射文件
不要把全部的持久类映射都写到一个大文件中。把 com.eg.Foo 映射到com/eg/Foo.hbm.xml中, 在团队开发环境中,这一点显得特别有意义。
把映射文件做为资源加载
把映射文件和他们的映射类放在一块儿进行部署。
考虑把查询字符串放在程序外面
若是你的查询中调用了非ANSI标准的SQL函数,那么这条实践经验对你适用。把查询字符串放在映射文件中可让程序具备更好的可移植性。
使用绑定变量
就像在JDBC编程中同样,应该老是用占位符"?"来替换很是量值,不要在查询中用字符串值来构造很是量值!更好的办法是在查询中使用命名参数。
不要本身来管理JDBC connections
Hibernate容许应用程序本身来管理JDBC connections,可是应该做为最后没有办法的办法。若是你不能使用Hibernate内建的connections providers,那么考虑实现本身来实现org.hibernate.connection.ConnectionProvider
考虑使用用户自定义类型(custom type)
假设你有一个Java类型,来自某些类库,须要被持久化,可是该类没有提供映射操做须要的存取方法。那么你应该考虑实现org.hibernate.UserType接口。这种办法使程序代码写起来更加自如,再也不须要考虑类与Hibernate type之间的相互转换。 
在性能瓶颈的地方使用硬编码的JDBC
在系统中对性能要求很严格的一些部分,某些操做也许直接使用JDBC会更好。可是请先确认这的确是一个瓶颈,而且不要想固然认为JDBC必定会更快。若是确实须要直接使用JDBC,那么最好打开一个 Hibernate Session 而后从 Session得到connection,按照这种办法你仍然可使用一样的transaction策略和底层的connection provider。
理解Session清洗( flushing)
Session会不时的向数据库同步持久化状态,若是这种操做进行的过于频繁,性能会受到必定的影响。有时候你能够经过禁止自动flushing,尽可能最小化非必要的flushing操做,或者更进一步,在一个特定的transaction中改变查询和其它操做的顺序。
在三层结构中,考虑使用托管对象(detached object)
当使用一个servlet / session bean 类型的架构的时候, 你能够把已加载的持久对象在session bean层和servlet / JSP 层之间来回传递。使用新的session来为每一个请求服务,使用 Session.merge() 或者Session.saveOrUpdate()来与数据库同步。
在两层结构中,考虑使用长持久上下文(long persistence contexts).
为了获得最佳的可伸缩性,数据库事务(Database Transaction)应该尽量的
短。可是,程序经常须要实现长时间运行的“应用程序事务(Application
Transaction)”,包含一个从用户的观点来看的原子操做。这个应用程序事务
可能跨越屡次从用户请求到获得反馈的循环。用脱管对象(与session脱离的对
象)来实现应用程序事务是常见的。或者,尤为在两层结构中,把Hibernate
Session从JDBC链接中脱离开,下次须要用的时候再链接上。毫不要把一个
Session用在多个应用程序事务(Application Transaction)中,不然你的数据
可能会过时失效。
不要把异常当作可恢复的
这一点甚至比“最佳实践”还要重要,这是“必备常识”。当异常发生的时
候,必需要回滚 Transaction ,关闭Session。若是你不这样作的话,
Hibernate没法保证内存状态精确的反应持久状态。尤为不要使用
Session.load()来判断一个给定标识符的对象实例在数据库中是否存在,应该
使用Session.get()或者进行一次查询.
对于关联优先考虑lazy fetching
谨慎的使用主动抓取(eager fetching)。对于关联来讲,若其目标是没法在第二级缓存中彻底缓存全部实例的类,应该使用代理(proxies)与/或具备延迟加载属性的集合(lazy collections)。若目标是能够被缓存的,尤为是缓存的命中率很是高的状况下,应该使用lazy="false",明确的禁止掉eager fetching。若是那些特殊的确实适合使用join fetch 的场合,请在查询中使用left join fetch。
使用open session in view模式,或者执行严格的装配期(assembly phase)策略来避免再次抓取数据带来的问题
Hibernate让开发者们摆脱了繁琐的Data Transfer Objects (DTO)。在传统的EJB结构中,DTO有双重做用:首先,他们解决了entity bean没法序列化的问题;其次,他们隐含地定义了一个装配期,在此期间,全部在view层须要用到的数据,都被抓取、集中到了DTO中,而后控制才被装到表示层。Hibernate终结了第一个做用。然而,除非你作好了在整个渲染过程当中都维护一个打开的持久化上下文(session)的准备,你仍然须要一个装配期(想象一下,你的业务方法与你的表示层有严格的契约,数据老是被放置到托管对象中)。这并不是是Hibernate的限制!这是实现安全的事务化数据访问的基本需求。
考虑把Hibernate代码从业务逻辑代码中抽象出来
把Hibernate的数据存取代码隐藏到接口(interface)的后面,组合使用DAO和Thread Local Session模式。经过Hibernate的UserType,你甚至能够用硬编码的JDBC来持久化那些本该被Hibernate持久化的类。 (该建议更适用于规模足够大应用软件中,对于那些只有5张表的应用程序并不适合。)不要用怪异的链接映射
多对多链接用得好的例子实际上至关少见。大多数时候你在“链接表”中须要保存额外的信息。这种状况下,用两个指向中介类的一对多的链接比较好。实际上,咱们认为绝大多数的链接是一对多和多对一的,你应该谨慎使用其它链接风格,用以前问本身一句,是否真的必须这么作。
偏心双向关联
单向关联更加难于查询。在大型应用中,几乎全部的关联必须在查询中能够双向导航。
 
原创内容 转自请注明【 http://sishuok.com/forum/blogPost/list/2484.html#7183】 
视频配套PPT,视频地址【  Hibernate4实战-独家视频课程 】
相关文章
相关标签/搜索