ITPub博客

首页 > Linux操作系统 > Linux操作系统 > Hibernate Best Practices

Hibernate Best Practices

原创 Linux操作系统 作者:grazier 时间:2009-01-05 17:47:38 0 删除 编辑

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/,如需转载,请注明出处,否则将追究法律责任。

下一篇: oracle dblink
请登录后发表评论 登录
全部评论

注册时间:2008-10-20

  • 博文量
    53
  • 访问量
    222716