Hibernate Best Practices

Chapter 24. Best Practices

最佳实践

Write fine-grained classes and map them using .

Use an Address class to encapsulate street, suburb, state, postcode. This encourages code reuse and simplifies refactoring.

设计细颗粒度的持久类并且使用来实现映射。使用一个Address持久类来封装street,suburb,state,postcode,这将有利于代码重用和简化代码重构(refactoring)的工作。 Declare identifier properties on persistent classes.

Hibernate makes identifier properties optional. There are all sorts of reasons why you should use them. We recommend that identifiers be 'synthetic' (generated, with no business meaning).

对持久类声明标识符属性(identifier properties)H中标识符属性是可选的,不过有很多原因来说明你应该使用标识符属性。我们建议标识符应该是“人造”的(自动生成,不涉及业务含义)。 Identify natural keys.

Identify natural keys for all entities, and map them using . Implement equals() and hashCode() to compare the properties that make up the natural key.

使用自然键标识对所有的实体都标识出自然键,用进行映射。实现equals和hashCode,在其中用组成自然键的属性进行比较。 Place each class mapping in its own file.

Don't use a single monolithic mapping document. Map com.eg.Foo in the file com/eg/Foo.hbm.xml. This makes particularly good sense in a team environment.

为每个持久类写一个映射文件不要把所有的持久类映射都写到一个大文件中。把com.eg.Foo映射到com/eg/Foo.hbm.xml中,在团队开发环境中,这一点显得特别有意义。 Load mappings as resources.

Deploy the mappings along with the classes they map.

把映射文件作为资源加载把映射文件和他们和映射类放在一起进行部署 Consider externalising query strings.

This is a good practice if your queries call non-ANSI-standard SQL functions. Externalising the query strings to mapping files will make the application more portable.

考虑把查询字符串放在程序外面如果你的查询中调用了非ANSI标准的SQL函数,那么这条实践经验对你适用。把查询字符串放在映射外面可以让程序具有更好的可移植性。 Use bind variables.

As in JDBC, always replace non-constant values by "?". Never use string manipulation to bind a non-constant value in a query! Even better, consider using named parameters in queries.

应用绑定变量就像在JDBC编程中一样,应该总是用占位符?来替换非常量值,不要在查询中用字符串值来构造非常量值!更好 的办法是在查询中使用命名参数. Don't manage your own JDBC connections.

Hibernate lets the application manage JDBC connections. This approach should be considered a last-resort. If you can't use the built-in connections providers, consider providing your own implementation of org.hibernate.connection.ConnectionProvider.

不要自己来管理jdbc connectionH允许应用程序自己来管理JDBC connections,但是应该作为最后没有办法的办法。如果你不能使用Hibernate内建的connections providers,那么考虑实现自己来实现org.hibernate.connection.ConnectionProvider。 Consider using a custom type.

Suppose you have a Java type, say from some library, that needs to be persisted but doesn't provide the accessors needed to map it as a component. You should consider implementing org.hibernate.UserType. This approach frees the application code from implementing transformations to / from a Hibernate type.

考虑使用用户自定义类型(custom type)假设你有一个java类型,来自某些类库,需要被持久化,但是该类没有提供映射操作需要的存取方法。那么你应该考虑实现org.hibernae.UserType接口 。这种办法使用程序代码写起来更加自如,不再需要考虑类与Hibernate type之间的相互转换。 Use hand-coded JDBC in bottlenecks.

In performance-critical areas of the system, some kinds of operations might benefit from direct JDBC. But please, wait until you know something is a bottleneck. And don't assume that direct JDBC is necessarily faster. If you need to use direct JDBC, it might be worth opening a Hibernate Session and using that JDBC connection. That way you can still use the same transaction strategy and underlying connection provider.

在性能瓶颈的地方使用硬编码的JDBC在系统中对性能要求很严格的一些部分,某些操作也许直接使用JDBC会更好。但是请先确认这的确是一个瓶颈,并且不要想当然认为JDBC一定会更快。如果确实需要直接使用JDBC,那么最好打开一个Hibernate Session然后从Session获得connection,按照这种办法你仍然可以使用同样的transaction策略和底层的connection provider。 Understand Session flushing.

From time to time the Session synchronizes its persistent state with the database. Performance will be affected if this process occurs too often. You may sometimes minimize unnecessary flushing by disabling automatic flushing or even by changing the order of queries and other operations within a particular transaction.

理解session清洗session会不时的向数据库同步持久化状态,如果这种操作进行的过于频繁,性能会受到一定的影响。有时候你可以通过禁止自动flushing,尽量最小化非必要的flushing操作,或者更进一步,在一个特定的transaction中改变查询和其它操作的顺序。 In a three tiered architecture, consider using detached objects.

When using a servlet / session bean architecture, you could pass persistent objects loaded in the session bean to and from the servlet / JSP layer. Use a new session to service each request. Use Session.merge() or Session.saveOrUpdate() to synchronize objects with the database.

在三层结构中,考虑使用托管对象(detached object)当使用一个servlet/session bean类型的架构的时候,你可以把已加裁的持久对象在session bean层和servlet/jsp层之间来回传递。使用新的session来为每个请求服务,使用session.merge或者session.saveOrUpdate来与数据库同步。 In a two tiered architecture, consider using long persistence contexts.在两层结构中,考虑使用长持久上下文(long persistence contexts)

Database Transactions have to be as short as possible for best scalability. However, it is often neccessary to implement long running application transactions, a single unit-of-work from the point of view of a user. An application transaction might span several client request/response cycles. It is common to use detached objects to implement application transactions. An alternative, extremely appropriate in two tiered architecture, is to maintain a single open persistence contact (session) for the whole lifecycle of the application transaction and simply disconnect from the JDBC connection at the end of each request and reconnect at the beginning of the subsequent request. Never share a single session across more than one application transaction, or you will be working with stale data.

            为了得以最佳的可伸缩性,数据库事务(Database Transaction)应该尽可能的短。但是,程序常常需要实现长时间运行的应用程序事务,包含一个从用户的观点来看的原子操作。这个应用程序事务可能跨越多次从用户请求到得到反馈的循环。用脱管对象(与session脱离的对象)来实现应用程序事务是常见的。或者,尤其在两层结构中,把hibernate session从JDBC连接中脱离开,下次需要用的时候再连接上。绝不要把一个session用在多个应用程序事务中,否则你的数据可能会过期失效。
Don't treat exceptions as recoverable.

This is more of a necessary practice than a "best" practice. When an exception occurs, roll back the Transaction and close the Session. If you don't, Hibernate can't guarantee that in-memory state accurately represents persistent state. As a special case of this, do not use Session.load() to determine if an instance with the given identifier exists on the database; use Session.get() or a query instead.

不要把异常看成可恢复的这一点甚至比最佳实践还要重要,这是必备常识。当异常发生的时候,必须要回滚事务并关闭session。如果你不这样做,H无法保证内存状态精确的反应持久状态。尤其不要使用session.load来判断给定标识符的对象实例在数据库是否存在,应该使用session.get或者进行一次查询。 Prefer lazy fetching for associations.

Use eager fetching sparingly. Use proxies and lazy collections for most associations to classes that are not likely to be completely held in the second-level cache. For associations to cached classes, where there is an a extremely high probability of a cache hit, explicitly disable eager fetching using lazy="false". When an join fetching is appropriate to a particular use case, use a query with a left join fetch.

对于关联优先考虑lazy fetching谨慎的使用主动抓取。对于关联来说,若其目标是无法在第二级缓存中完全缓存所有实例的类,应该使用代理或具有延迟加载属性的集合。若目标是可以被缓存的,尤其是缓存的命中率非常高的情况下,应该使用lazy=false,明确的禁止掉主动抓取。如果那些特殊的确实适合使用join fetch的场合,请在查询中使用left join fetch.

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/118838/viewspace-526972/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/118838/viewspace-526972/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值