你可以在Ant的Task中,进行如下定义,对持久类代码加入“二进制指令。”
<target name="instrument" depends="compile"> <taskdef name="instrument" classname="org.hibernate.tool.instrument.InstrumentTask"> <classpath path="${jar.path}"/> <classpath path="${classes.dir}"/> <classpath refid="lib.class.path"/> </taskdef> <instrument verbose="true"> <fileset dir="${testclasses.dir}/org/hibernate/auction/model"> <include name="*.class"/> </fileset> </instrument></target>
还有一种可以优化的方法,它使用HQL或条件查询的投影(projection)特性,可以避免读取非必要的列, 这一点至少对只读事务是非常有用的。它无需在代码构建时“二进制指令”处理,因此是一个更加值得选择的解决方法。
有时你需要在HQL中通过抓取所有属性 ,强行抓取所有内容。
20.2. 二级缓存(The Second Level Cache)
Hibernate的Session 在事务级别进行持久化数据的缓存操作。 当然,也有可能分别为每个类(或集合),配置集群、或JVM级别(SessionFactory级别 )的缓存。 你甚至可以为之插入一个集群的缓存。注意,缓存永远不知道其他应用程序对持久化仓库(数据库)可能进行的修改 (即使可以将缓存数据设定为定期失效)。
默认情况下,Hibernate使用EHCache进行JVM级别的缓存(目前,Hibernate已经废弃了对JCS的支持,未来版本中将会去掉它)。 你可以通过设置Hibernate.cache.provider_class 属性,指定其他的缓存策略, 该缓存策略必须实现org.hibernate.cache.CacheProvider 接口。
表 20.1. 缓存策略提供商(Cache Providers)
| Cache | Provider class | Type | Cluster Safe | Query Cache Supported |
|---|---|---|---|---|
| Hashtable (not intended for production use) | org.hibernate.cache.HashtableCacheProvider | memory | yes | |
| EHCache | org.hibernate.cache.EhCacheProvider | memory, disk | yes | |
| OSCache | org.hibernate.cache.OSCacheProvider | memory, disk | yes | |
| SwarmCache | org.hibernate.cache.SwarmCacheProvider | clustered (ip multicast) | yes (clustered invalidation) | |
| JBoss TreeCache | org.hibernate.cache.TreeCacheProvider | clustered (ip multicast), transactional | yes (replication) | yes (clock sync req.) |
20.2.1. 缓存映射(Cache mappings)
类或者集合映射的“<cache> 元素”可以有下列形式:
<cache usage="transactional|read-write|nonstrict-read-write|read-only" (1)/>
| (1) |
usage 说明了缓存的策略: transactional 、 read-write 、 nonstrict-read-write 或 read-only 。 |
另外(首选?), 你可以在hibernate.cfg.xml中指定<class-cache> 和 <collection-cache> 元素。
这里的usage 属性指明了缓存并发策略(cache concurrency strategy)。
20.2.2. 策略:只读缓存(Strategy: read only)
如果你的应用程序只需读取一个持久化类的实例,而无需对其修改, 那么就可以对其进行只读 缓存。这是最简单,也是实用性最好的方法。甚至在集群中,它也能完美地运作。
<class name="eg.Immutable" mutable="false"> <cache usage="read-only"/> ....</class>
20.2.3. 策略:读/写缓存(Strategy: read/write)
如果应用程序需要更新数据,那么使用读/写缓存 比较合适。 如果应用程序要求“序列化事务”的隔离级别(serializable transaction isolation level),那么就决不能使用这种缓存策略。 如果在JTA环境中使用缓存,你必须指定Hibernate.transaction.manager_lookup_class 属性的值, 通过它,Hibernate才能知道该应用程序中JTA的TransactionManager 的具体策略。 在其它环境中,你必须保证在Session.close() 、或Session.disconnect() 调用前, 整个事务已经结束。 如果你想在集群环境中使用此策略,你必须保证底层的缓存实现支持锁定(locking)。Hibernate内置的缓存策略并不支持锁定功能。
<class name="eg.Cat" .... > <cache usage="read-write"/> .... <set name="kittens" ... > <cache usage="read-write"/> .... </set></class>
20.2.4. 策略:非严格读/写缓存(Strategy: nonstrict read/write)
如果应用程序只偶尔需要更新数据(也就是说,两个事务同时更新同一记录的情况很不常见),也不需要十分严格的事务隔离, 那么比较适合使用非严格读/写缓存 策略。如果在JTA环境中使用该策略, 你必须为其指定Hibernate.transaction.manager_lookup_class 属性的值, 在其它环境中,你必须保证在Session.close() 、或Session.disconnect() 调用前, 整个事务已经结束。
20.2.5. 策略:事务缓存(transactional)
Hibernate的事务缓存 策略提供了全事务的缓存支持, 例如对JBoss TreeCache的支持。这样的缓存只能用于JTA环境中,你必须指定 为其Hibernate.transaction.manager_lookup_class 属性。
没有一种缓存提供商能够支持上列的所有缓存并发策略。下表中列出了各种提供器、及其各自适用的并发策略。
表 20.2. 各种缓存提供商对缓存并发策略的支持情况(Cache Concurrency Strategy Support)
| Cache | read-only | nonstrict-read-write | read-write | transactional |
|---|---|---|---|---|
| Hashtable (not intended for production use) | yes | yes | yes | |
| EHCache | yes | yes | yes | |
| OSCache | yes | yes | yes | |
| SwarmCache | yes | yes | ||
| JBoss TreeCache | yes | yes |






