📄 performance.html
字号:
... </set></class></pre><p> 如果整个的<tt class="literal">batch-size</tt>是3(笔误?),那么Hibernate将会分四次执行<tt class="literal">SELECT</tt>查询, 按照3、3、3、1的大小分别载入数据。这里的每次载入的数据量还具体依赖于当前<tt class="literal">Session</tt>中未实例化集合的个数。 </p><p> 如果你的模型中有嵌套的树状结构,例如典型的帐单-原料结构(bill-of-materials pattern),集合的批量抓取是非常有用的。 (尽管在更多情况下对树进行读取时,<span class="emphasis"><em>嵌套集合(nested set)</em></span>或<span class="emphasis"><em>原料路径(materialized path)</em></span>(××) 是更好的解决方法。) </p></div><div class="sect2" lang="zh-cn"><div class="titlepage"><div><div><h3 class="title"><a name="performance-fetching-subselect"></a>20.1.6. 使用子查询抓取(Using subselect fetching) </h3></div></div><div></div></div><p> 假若一个延迟集合或单值代理需要抓取,Hibernate会使用一个subselect重新运行原来的查询,一次性读入所有的实例。这和批量抓取的实现方法是一样的,不会有破碎的加载。 </p></div><div class="sect2" lang="zh-cn"><div class="titlepage"><div><div><h3 class="title"><a name="performance-fetching-lazyproperties"></a>20.1.7. 使用延迟属性抓取(Using lazy property fetching) </h3></div></div><div></div></div><p> Hibernate3对单独的属性支持延迟抓取,这项优化技术也被称为<span class="emphasis"><em>组抓取(fetch groups)</em></span>。 请注意,该技术更多的属于市场特性。在实际应用中,优化行读取比优化列读取更重要。但是,仅载入类的部分属性在某些特定情况下会有用,例如在原有表中拥有几百列数据、数据模型无法改动的情况下。 </p><p> 可以在映射文件中对特定的属性设置<tt class="literal">lazy</tt>,定义该属性为延迟载入。 </p><pre class="programlisting"><class name="Document"> <id name="id"> <generator class="native"/> </id> <property name="name" not-null="true" length="50"/> <property name="summary" not-null="true" length="200" lazy="true"/> <property name="text" not-null="true" length="2000" lazy="true"/></class></pre><p> 属性的延迟载入要求在其代码构建时加入二进制指示指令(bytecode instrumentation),如果你的持久类代码中未含有这些指令, Hibernate将会忽略这些属性的延迟设置,仍然将其直接载入。 </p><p> 你可以在Ant的Task中,进行如下定义,对持久类代码加入“二进制指令。” </p><pre class="programlisting"><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></pre><p> 还有一种可以优化的方法,它使用HQL或条件查询的投影(projection)特性,可以避免读取非必要的列, 这一点至少对只读事务是非常有用的。它无需在代码构建时“二进制指令”处理,因此是一个更加值得选择的解决方法。 </p><p> 有时你需要在HQL中通过<tt class="literal">抓取所有属性</tt>,强行抓取所有内容。 </p></div></div><div class="sect1" lang="zh-cn"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="performance-cache"></a>20.2. 二级缓存(The Second Level Cache) </h2></div></div><div></div></div><p> Hibernate的<tt class="literal">Session</tt>在事务级别进行持久化数据的缓存操作。 当然,也有可能分别为每个类(或集合),配置集群、或JVM级别(<tt class="literal">SessionFactory级别</tt>)的缓存。 你甚至可以为之插入一个集群的缓存。注意,缓存永远不知道其他应用程序对持久化仓库(数据库)可能进行的修改 (即使可以将缓存数据设定为定期失效)。 </p><p> 默认情况下,Hibernate使用EHCache进行JVM级别的缓存(目前,Hibernate已经废弃了对JCS的支持,未来版本中将会去掉它)。 你可以通过设置<tt class="literal">hibernate.cache.provider_class</tt>属性,指定其他的缓存策略, 该缓存策略必须实现<tt class="literal">org.hibernate.cache.CacheProvider</tt>接口。 </p><div class="table"><a name="cacheproviders"></a><p class="title"><b>表 20.1. 缓存策略提供商(Cache Providers) </b></p><table summary="
 缓存策略提供商(Cache Providers)
 " border="1"><colgroup><col align="left"><col align="left"><col align="left"><col align="left"><col align="left"></colgroup><thead><tr><th align="left">Cache</th><th align="left">Provider class</th><th align="left">Type</th><th align="left">Cluster Safe</th><th align="left">Query Cache Supported</th></tr></thead><tbody><tr><td align="left">Hashtable (not intended for production use)</td><td align="left"><tt class="literal">org.hibernate.cache.HashtableCacheProvider</tt></td><td align="left">memory</td><td align="left"> </td><td align="left">yes</td></tr><tr><td align="left">EHCache</td><td align="left"><tt class="literal">org.hibernate.cache.EhCacheProvider</tt></td><td align="left">memory, disk</td><td align="left"> </td><td align="left">yes</td></tr><tr><td align="left">OSCache</td><td align="left"><tt class="literal">org.hibernate.cache.OSCacheProvider</tt></td><td align="left">memory, disk</td><td align="left"> </td><td align="left">yes</td></tr><tr><td align="left">SwarmCache</td><td align="left"><tt class="literal">org.hibernate.cache.SwarmCacheProvider</tt></td><td align="left">clustered (ip multicast)</td><td align="left">yes (clustered invalidation)</td><td align="left"> </td></tr><tr><td align="left">JBoss TreeCache</td><td align="left"><tt class="literal">org.hibernate.cache.TreeCacheProvider</tt></td><td align="left">clustered (ip multicast), transactional</td><td align="left">yes (replication)</td><td align="left">yes (clock sync req.)</td></tr></tbody></table></div><div class="sect2" lang="zh-cn"><div class="titlepage"><div><div><h3 class="title"><a name="performance-cache-mapping"></a>20.2.1. 缓存映射(Cache mappings) </h3></div></div><div></div></div><p> 类或者集合映射的“<tt class="literal"><cache></tt>元素”可以有下列形式: </p><div class="programlistingco"><pre class="programlisting"><cache usage="transactional|read-write|nonstrict-read-write|read-only" <span class="co">(1)</span>/></pre><div class="calloutlist"><table border="0" summary="Callout list"><tr><td width="5%" valign="top" align="left">(1)</td><td valign="top" align="left"><p> <tt class="literal">usage</tt>说明了缓存的策略: <tt class="literal">transactional</tt>、 <tt class="literal">read-write</tt>、 <tt class="literal">nonstrict-read-write</tt>或 <tt class="literal">read-only</tt>。 </p></td></tr></table></div></div><p> 另外(首选?), 你可以在hibernate.cfg.xml中指定<tt class="literal"><class-cache></tt>和 <tt class="literal"><collection-cache></tt> 元素。 </p><p> 这里的<tt class="literal">usage</tt> 属性指明了<span class="emphasis"><em>缓存并发策略(cache concurrency strategy)</em></span>。 </p></div><div class="sect2" lang="zh-cn"><div class="titlepage"><div><div><h3 class="title"><a name="performance-cache-readonly"></a>20.2.2. 策略:只读缓存(Strategy: read only) </h3></div></div><div></div></div><p> 如果你的应用程序只需读取一个持久化类的实例,而无需对其修改,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -