﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-semovy-文章分类-Hibernate</title><link>http://www.blogjava.net/WshmAndLily/category/10979.html</link><description /><language>zh-cn</language><lastBuildDate>Mon, 10 Sep 2007 12:37:21 GMT</lastBuildDate><pubDate>Mon, 10 Sep 2007 12:37:21 GMT</pubDate><ttl>60</ttl><item><title>Open Session In View</title><link>http://www.blogjava.net/WshmAndLily/articles/143817.html</link><dc:creator>semovy</dc:creator><author>semovy</author><pubDate>Sun, 09 Sep 2007 10:15:00 GMT</pubDate><guid>http://www.blogjava.net/WshmAndLily/articles/143817.html</guid><wfw:comment>http://www.blogjava.net/WshmAndLily/comments/143817.html</wfw:comment><comments>http://www.blogjava.net/WshmAndLily/articles/143817.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/WshmAndLily/comments/commentRss/143817.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/WshmAndLily/services/trackbacks/143817.html</trackback:ping><description><![CDATA[<font size="2"><font color="#4b4b4b"><font face="宋体">在没有使用</font><span style="font-size: 10pt; color: #4b4b4b; font-family: Verdana">Spring</span></font></font><span style="font-size: 10pt; color: #4b4b4b; font-family: 宋体">提供的</span><span style="font-size: 10pt; color: #4b4b4b; font-family: Verdana">Open Session In View</span><span style="font-size: 10pt; color: #4b4b4b; font-family: 宋体">情况下，因需要在</span><span style="font-size: 10pt; color: #4b4b4b; font-family: Verdana">service(or Dao)</span><span style="font-size: 10pt; color: #4b4b4b; font-family: 宋体">层里把</span><span style="font-size: 10pt; color: #4b4b4b; font-family: Verdana">session</span><span style="font-size: 10pt; color: #4b4b4b; font-family: 宋体">关闭，所以</span><span style="font-size: 10pt; color: #4b4b4b; font-family: Verdana">lazy loading </span><span style="font-size: 10pt; color: #4b4b4b; font-family: 宋体">为</span><span style="font-size: 10pt; color: #4b4b4b; font-family: Verdana">true</span><span style="font-size: 10pt; color: #4b4b4b; font-family: 宋体">的话，要在应用层内把关系集合都初始化，如</span><span style="font-size: 10pt; color: #4b4b4b; font-family: Verdana"> company.getEmployees()</span><span style="font-size: 10pt; color: #4b4b4b; font-family: 宋体">，否则</span><span style="font-size: 10pt; color: #4b4b4b; font-family: Verdana">Hibernate</span><span style="font-size: 10pt; color: #4b4b4b; font-family: 宋体">抛</span><span style="font-size: 10pt; color: #4b4b4b; font-family: Verdana">session already closed Exception;</span><span style="font-size: 10pt; color: #4b4b4b; font-family: Verdana">&nbsp;&nbsp;&nbsp; Open Session In View</span><span style="font-size: 10pt; color: #4b4b4b; font-family: 宋体">提供了一种简便的方法，较好地解决了</span><span style="font-size: 10pt; color: #4b4b4b; font-family: Verdana">lazy loading</span><span style="font-size: 10pt; color: #4b4b4b; font-family: 宋体">问题</span><span style="font-size: 10pt; color: #4b4b4b; font-family: Verdana">.</span>
<p><span style="font-size: 10pt; color: #4b4b4b; font-family: 宋体"><span style="font-size: 10pt; color: #4b4b4b; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span>它有两种配置方式<font face="Verdana">OpenSessionInViewInterceptor</font></span><span style="font-size: 10pt; color: #4b4b4b; font-family: 宋体">和<span style="font-size: 10pt; color: #4b4b4b; font-family: Verdana">OpenSessionInViewFilter(具体参看<a title="SpringSide" href="http://www.springside.org.cn/" target="_blank"><font color="#999999">SpringSide</font></a>)</span></span><span style="font-size: 10pt; color: #4b4b4b; font-family: 宋体">，功能相同，只是一个在</span><span style="font-size: 10pt; color: #4b4b4b; font-family: Verdana">web.xml</span><span style="font-size: 10pt; color: #4b4b4b; font-family: 宋体">配置，另一个在</span><span style="font-size: 10pt; color: #4b4b4b; font-family: Verdana">application.xml</span><span style="font-size: 10pt; color: #4b4b4b; font-family: 宋体">配置而已。</span></p>
<p><span style="font-size: 10pt; color: #4b4b4b; font-family: Verdana">&nbsp;&nbsp;&nbsp; Open Session In View</span><span style="font-size: 10pt; color: #4b4b4b; font-family: 宋体">在</span><span style="font-size: 10pt; color: #4b4b4b; font-family: Verdana">request</span><span style="font-size: 10pt; color: #4b4b4b; font-family: 宋体">把</span><span style="font-size: 10pt; color: #4b4b4b; font-family: Verdana">session</span><span style="font-size: 10pt; color: #4b4b4b; font-family: 宋体">绑定到当前</span><span style="font-size: 10pt; color: #4b4b4b; font-family: Verdana">thread</span><span style="font-size: 10pt; color: #4b4b4b; font-family: 宋体">期间一直保持</span><span style="font-size: 10pt; color: #4b4b4b; font-family: Verdana">hibernate session</span><span style="font-size: 10pt; color: #4b4b4b; font-family: 宋体">在</span><span style="font-size: 10pt; color: #4b4b4b; font-family: Verdana">open</span><span style="font-size: 10pt; color: #4b4b4b; font-family: 宋体">状态，使</span><span style="font-size: 10pt; color: #4b4b4b; font-family: Verdana">session</span><span style="font-size: 10pt; color: #4b4b4b; font-family: 宋体">在</span><span style="font-size: 10pt; color: #4b4b4b; font-family: Verdana">request</span><span style="font-size: 10pt; color: #4b4b4b; font-family: 宋体">的整个期间都可以使用，如在</span><span style="font-size: 10pt; color: #4b4b4b; font-family: Verdana">View</span><span style="font-size: 10pt; color: #4b4b4b; font-family: 宋体">层里</span><span style="font-size: 10pt; color: #4b4b4b; font-family: Verdana">PO</span><span style="font-size: 10pt; color: #4b4b4b; font-family: 宋体">也可以</span><span style="font-size: 10pt; color: #4b4b4b; font-family: Verdana">lazy loading</span><span style="font-size: 10pt; color: #4b4b4b; font-family: 宋体">数据，如</span><span style="font-size: 10pt; color: #4b4b4b; font-family: Verdana"> ${ company.employees }</span><span style="font-size: 10pt; color: #4b4b4b; font-family: 宋体">。当</span><span style="font-size: 10pt; color: #4b4b4b; font-family: Verdana">View </span><span style="font-size: 10pt; color: #4b4b4b; font-family: 宋体">层逻辑完成后，才会通过</span><span style="font-size: 10pt; color: #4b4b4b; font-family: Verdana">Filter</span><span style="font-size: 10pt; color: #4b4b4b; font-family: 宋体">的</span><span style="font-size: 10pt; color: #4b4b4b; font-family: Verdana">doFilter</span><span style="font-size: 10pt; color: #4b4b4b; font-family: 宋体">方法或</span><span style="font-size: 10pt; color: #4b4b4b; font-family: Verdana">Interceptor</span><span style="font-size: 10pt; color: #4b4b4b; font-family: 宋体">的</span><span style="font-size: 10pt; color: #4b4b4b; font-family: Verdana">postHandle</span><span style="font-size: 10pt; color: #4b4b4b; font-family: 宋体">方法自动关闭</span><span style="font-size: 10pt; color: #4b4b4b; font-family: Verdana">session</span><span style="font-size: 10pt; color: #4b4b4b; font-family: 宋体">。</span>&nbsp;</p>
<p><strong>OpenSessionInViewInterceptor配置</strong></p>
<div style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; background: #e6e6e6; padding-bottom: 4px; border-left: windowtext 0.5pt solid; width: 95%; word-break: break-all; padding-top: 4px; border-bottom: windowtext 0.5pt solid">
<div><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" /><span style="color: #0000ff">&lt;</span><span style="color: #800000">beans</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">bean&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="openSessionInViewInterceptor"</span><span style="color: #ff0000">&nbsp;class</span><span style="color: #0000ff">="org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">property&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="sessionFactory"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">ref&nbsp;</span><span style="color: #ff0000">bean</span><span style="color: #0000ff">="sessionFactory"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">property</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">bean</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">bean&nbsp;</span><span style="color: #ff0000">id</span><span style="color: #0000ff">="urlMapping"</span><span style="color: #ff0000">&nbsp;class</span><span style="color: #0000ff">="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">property&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="interceptors"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">list</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">ref&nbsp;</span><span style="color: #ff0000">bean</span><span style="color: #0000ff">="openSessionInViewInterceptor"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">list</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">property</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">property&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="mappings"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...&nbsp;<br />
<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">property</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">bean</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">&nbsp;...<br />
<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" /></span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">beans</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">&nbsp;</span></div>
</div>
<p><strong>OpenSessionInViewFilter配置</strong></p>
<div style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; background: #e6e6e6; padding-bottom: 4px; border-left: windowtext 0.5pt solid; width: 95%; word-break: break-all; padding-top: 4px; border-bottom: windowtext 0.5pt solid">
<div><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" /><span style="color: #0000ff">&lt;</span><span style="color: #800000">web-app</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />&nbsp;...&nbsp;<br />
<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">filter</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">filter-name</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">hibernateFilter</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">filter-name</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">filter-class</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">org.springframework.orm.hibernate3.support.OpenSessionInViewFilter&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">filter-class</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">&lt;!--</span><span style="color: #008000">&nbsp;singleSession默认为true,若设为false则等于没用OpenSessionInView&nbsp;</span><span style="color: #008000">--&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">init-param</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">param-name</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">singleSession</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">param-name</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">param-value</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">true</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">param-value</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">init-param</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">filter</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />&nbsp;...&nbsp;<br />
<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">filter-mapping</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">filter-name</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">hibernateFilter</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">filter-name</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">url-pattern</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">*.do</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">url-pattern</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">filter-mapping</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />&nbsp;...&nbsp;<br />
<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" /></span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">web-app</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">&nbsp;</span></div>
</div>
<p>很多人在使用OpenSessionInView过程中提及一个错误：</p>
<div style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; background: #e6e6e6; padding-bottom: 4px; border-left: windowtext 0.5pt solid; width: 95%; word-break: break-all; padding-top: 4px; border-bottom: windowtext 0.5pt solid">
<div><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" /><span style="color: #000000">org.springframework.dao.InvalidDataAccessApiUsageException:&nbsp;Write&nbsp;operations&nbsp;are&nbsp;not&nbsp;allowed&nbsp;in&nbsp;read-only&nbsp;mode&nbsp;(FlushMode.NEVER)&nbsp;-&nbsp;turn&nbsp;your&nbsp;Session&nbsp;into&nbsp;FlushMode.AUTO&nbsp;or&nbsp;remove&nbsp;'readOnly'&nbsp;marker&nbsp;from&nbsp;transaction&nbsp;definition&nbsp;</span></div>
</div>
<strong></strong>
<p>看看OpenSessionInViewFilter里的opensession方法</p>
<div style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; background: #e6e6e6; padding-bottom: 4px; border-left: windowtext 0.5pt solid; width: 95%; word-break: break-all; padding-top: 4px; border-bottom: windowtext 0.5pt solid">
<div><img id="_103_235_Open_Image" onclick="this.style.display='none'; document.getElementById('_103_235_Open_Text').style.display='none'; document.getElementById('_103_235_Closed_Image').style.display='inline'; document.getElementById('_103_235_Closed_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="_103_235_Closed_Image" style="display: none" onclick="this.style.display='none'; document.getElementById('_103_235_Closed_Text').style.display='none'; document.getElementById('_103_235_Open_Image').style.display='inline'; document.getElementById('_103_235_Open_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif" align="top" /><span style="color: #0000ff">protected</span><span style="color: #000000">&nbsp;Session&nbsp;openSession(SessionFactory&nbsp;sessionFactory)&nbsp;</span><span style="color: #0000ff">throws</span><span style="color: #000000">&nbsp;DataAccessResourceFailureException&nbsp;</span><span id="_103_235_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff">...</span><span id="_103_235_Open_Text"><span style="color: #000000">{<br />
<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;Session&nbsp;session&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;SessionFactoryUtils.getSession(sessionFactory,&nbsp;</span><span style="color: #0000ff">true</span><span style="color: #000000">);<br />
<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;session.setFlushMode(FlushMode.NEVER);<br />
<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;session;<br />
<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span></div>
</div>
<p>&nbsp;&nbsp;&nbsp; 可以看到OpenSessionInViewFilter在getSession的时候,会把获取回来的session的flush mode 设为FlushMode.NEVER。然后把该sessionFactory绑定到TransactionSynchronizationManager，使request的整个过程都使用同一个session，在请求过后再接除该sessionFactory的绑定，最后<span class="me1">closeSessionIfNecessary</span>根据该session是否已和transaction绑定来决定是否关闭session。在这个过程中，若HibernateTemplate 发现自当前session有不是readOnly的transaction，就会获取到FlushMode.AUTO Session，使方法拥有写权限。</p>
<p>&nbsp;&nbsp;&nbsp; 也即是，如果有不是readOnly的transaction就可以由Flush.NEVER转为Flush.AUTO,拥有insert,update,delete操作权限，如果没有transaction，并且没有另外人为地设flush model的话，则doFilter的整个过程都是Flush.NEVER。所以受transaction保护的方法有写权限，没受保护的则没有。</p>
<p><strong>采用spring的事务声明,使方法受transaction控制</strong></p>
<div style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; background: #e6e6e6; padding-bottom: 4px; border-left: windowtext 0.5pt solid; width: 95%; word-break: break-all; padding-top: 4px; border-bottom: windowtext 0.5pt solid">
<div><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" /><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">bean&nbsp;</span><span style="color: #ff0000">id</span><span style="color: #0000ff">="baseTransaction"</span><span style="color: #ff0000">&nbsp;class</span><span style="color: #0000ff">="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"</span><span style="color: #ff0000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;abstract</span><span style="color: #0000ff">="true"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">property&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="transactionManager"</span><span style="color: #ff0000">&nbsp;ref</span><span style="color: #0000ff">="transactionManager"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">property&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="proxyTargetClass"</span><span style="color: #ff0000">&nbsp;value</span><span style="color: #0000ff">="true"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">property&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="transactionAttributes"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">props</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">prop&nbsp;</span><span style="color: #ff0000">key</span><span style="color: #0000ff">="get*"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">PROPAGATION_REQUIRED,readOnly</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">prop</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">prop&nbsp;</span><span style="color: #ff0000">key</span><span style="color: #0000ff">="find*"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">PROPAGATION_REQUIRED,readOnly</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">prop</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">prop&nbsp;</span><span style="color: #ff0000">key</span><span style="color: #0000ff">="load*"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">PROPAGATION_REQUIRED,readOnly</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">prop</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">prop&nbsp;</span><span style="color: #ff0000">key</span><span style="color: #0000ff">="save*"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">PROPAGATION_REQUIRED</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">prop</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">prop&nbsp;</span><span style="color: #ff0000">key</span><span style="color: #0000ff">="add*"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">PROPAGATION_REQUIRED</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">prop</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">prop&nbsp;</span><span style="color: #ff0000">key</span><span style="color: #0000ff">="update*"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">PROPAGATION_REQUIRED</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">prop</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">prop&nbsp;</span><span style="color: #ff0000">key</span><span style="color: #0000ff">="remove*"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">PROPAGATION_REQUIRED</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">prop</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">props</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">property</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">bean</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" /><br />
<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">bean&nbsp;</span><span style="color: #ff0000">id</span><span style="color: #0000ff">="userService"</span><span style="color: #ff0000">&nbsp;parent</span><span style="color: #0000ff">="baseTransaction"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">property&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="target"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">bean&nbsp;</span><span style="color: #ff0000">class</span><span style="color: #0000ff">="com.phopesoft.security.service.impl.UserServiceImpl"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">property</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">bean</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">&nbsp;</span></div>
</div>
<p>对于上例，则以save,add,update,remove开头的方法拥有可写的事务，如果当前有某个方法，如命名为importExcel()，则因没有transaction而没有写权限，这时若方法内有insert,update,delete操作的话，则需要手动设置flush model为Flush.AUTO,如</p>
<div style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; background: #e6e6e6; padding-bottom: 4px; border-left: windowtext 0.5pt solid; width: 95%; word-break: break-all; padding-top: 4px; border-bottom: windowtext 0.5pt solid">
<div><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" /><span style="color: #000000">session.setFlushMode(FlushMode.AUTO);&nbsp;<br />
<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />session.save(user);&nbsp;&nbsp;<br />
<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />session.flush();&nbsp;</span></div>
</div>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;尽管Open Session In View看起来还不错，其实副作用不少。看回上面OpenSessionInViewFilter的doFilterInternal方法代码，这个方法实际上是被父类的doFilter调用的，因此，我们可以大约了解的OpenSessionInViewFilter调用流程: request(请求)-&gt;open session并开始transaction-&gt;controller-&gt;View(Jsp)-&gt;结束transaction并close session.</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; 一切看起来很正确，尤其是在本地开发测试的时候没出现问题，但试想下如果流程中的某一步被阻塞的话，那在这期间connection就一直被占用而不释放。最有可能被阻塞的就是在写Jsp这步，一方面可能是页面内容大，response.write的时间长，另一方面可能是网速慢，服务器与用户间传输时间久。当大量这样的情况出现时，就有连接池连接不足，造成页面假死现象。</p>
<p>Open Session In View是个双刃剑，放在公网上内容多流量大的网站请慎用。</p>
<p>&nbsp;</p>
<p><a id="viewpost1_TitleUrl" href="http://www.blogjava.net/dreamstone/archive/2007/07/29/133074.html"><font color="#002c99">hibernate open session in view 抛出异常解决方法</font></a> </p>
<p>&nbsp;在使用open-session-in-view的时候，如果使用不当，有可能抛出两种异常<br />
1，NonUniqueObjectException<br />
2，在配合spring使用的时候会可能会抛出org.<span class="me1">springframework</span>.<span class="me1">dao</span>.<span class="me1">InvalidDataAccessApiUsageException<br />
<br />
先说1，这个异常的抛出原因和解决办法见这里：<br />
<font color="#002c99">javaeye</font>上有了很好的事例:<a href="http://www.javaeye.com/topic/11581"><font color="#002c99">http://www.javaeye.com/topic/11581</font><font color="#000000"> </font></a><br />
解决办法可以用merge，也可以别的办法。<br />
出现的原因，可以参考一下我前边的文章中将merge和update的区别的内容。<br />
<a href="http://www.blogjava.net/dreamstone/archive/2007/07/29/133071.html"><font color="#002c99">http://www.blogjava.net/dreamstone/archive/2007/07/29/133071.html</font></a><br />
<br />
2的解决办法：在这里<br />
springside的一篇文章做了详细说明<br />
<a href="http://calvin.blog.javascud.org/post/46.htm"><font color="#002c99">http://calvin.blog.javascud.org/post/46.htm</font></a><br />
<br />
好了，现在问题解决了，但关于open-session-in-view的使用还有一些探讨，是否应该使用，使用的好处与坏处。<br />
见这两篇jdon上的文章:<br />
<a href="http://www.jdon.com/jivejdon/thread/22374.html"><font color="#002c99">http://www.jdon.com/jivejdon/thread/22374.html</font></a><br />
<a href="http://www.jdon.com/jivejdon/thread/28955.html"><font color="#002c99">http://www.jdon.com/jivejdon/thread/28955.html</font></a><br />
</span></p>
 <img src ="http://www.blogjava.net/WshmAndLily/aggbug/143817.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/WshmAndLily/" target="_blank">semovy</a> 2007-09-09 18:15 <a href="http://www.blogjava.net/WshmAndLily/articles/143817.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring 与 Hibernate 的延迟加载和 Dao 模式</title><link>http://www.blogjava.net/WshmAndLily/articles/143690.html</link><dc:creator>semovy</dc:creator><author>semovy</author><pubDate>Sat, 08 Sep 2007 14:49:00 GMT</pubDate><guid>http://www.blogjava.net/WshmAndLily/articles/143690.html</guid><wfw:comment>http://www.blogjava.net/WshmAndLily/comments/143690.html</wfw:comment><comments>http://www.blogjava.net/WshmAndLily/articles/143690.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/WshmAndLily/comments/commentRss/143690.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/WshmAndLily/services/trackbacks/143690.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Hibernate 与延迟加载： Hibernate 对象关系映射提供延迟的与非延迟的对象初始化。非延迟加载在读取一个对象的时候会将与这个对象所有相关的其他对象一起读取出来。这有时会导致成百的（如果不是成千的话） select 语句在读取对象的时候执行。这个问题有时出现在使用双向关系的时候，经常会导致整个数据库都在初始化的阶段被读出来了。当然，你可以不厌其烦地检查每一个对象与其他对象的关系...&nbsp;&nbsp;<a href='http://www.blogjava.net/WshmAndLily/articles/143690.html'>阅读全文</a><img src ="http://www.blogjava.net/WshmAndLily/aggbug/143690.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/WshmAndLily/" target="_blank">semovy</a> 2007-09-08 22:49 <a href="http://www.blogjava.net/WshmAndLily/articles/143690.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>hibernate延迟加载</title><link>http://www.blogjava.net/WshmAndLily/articles/143415.html</link><dc:creator>semovy</dc:creator><author>semovy</author><pubDate>Fri, 07 Sep 2007 07:05:00 GMT</pubDate><guid>http://www.blogjava.net/WshmAndLily/articles/143415.html</guid><wfw:comment>http://www.blogjava.net/WshmAndLily/comments/143415.html</wfw:comment><comments>http://www.blogjava.net/WshmAndLily/articles/143415.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/WshmAndLily/comments/commentRss/143415.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/WshmAndLily/services/trackbacks/143415.html</trackback:ping><description><![CDATA[<p>延迟加载的对象：<br />
hibernate 2针对实体对象和集合<br />
hibernate 3同时提供了属性的延迟加载功能。<br />
其中对集合的延迟加载特性意义最为重大。</p>
<p>实体对象的延迟加载:<br />
1.在hibernate配置文件中的class指定</p>
<p>集合类型的延迟加载：<br />
在set中指定lazy=true<br />
这样只有实际加载与对象相关联的集合对象的时候，再通过session从数据库中加载实际的数据集。<br />
Hibernate.initialize方法可以强制Hibernate立即加载关联的对象集，例如：<br />
Hibernate.initialize(user.getAddress());<br />
集合类型的缓存：<br />
如果为某个集合类设定了缓存，如<br />
&lt;set <br />
&nbsp;&nbsp;&nbsp;&nbsp; name="address"<br />
&nbsp;&nbsp;&nbsp;&nbsp; table="t_address"<br />
&nbsp;&nbsp;&nbsp;&nbsp; lazy="true"<br />
&nbsp;&nbsp;&nbsp;&nbsp; ......<br />
&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;cache usage="read-only"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;key column="user_id" /&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;one-to-many class="cn.blogjava.TAddress" /&gt;<br />
&lt;/set&gt;<br />
Hibernate对集合类型进行缓存的时候，分两部分保存。首先是这个集合中所有实体的id列表，其次才是各个实体对象。<br />
这里制定了cache usage="read-only"只会使得Hibernate对数据索引进行缓存。也就是说只缓存了集合中的数据索引，并不包含集合中的各个实体元素。<br />
如果指定cache usage="read-write"才会对集合中的实体进行缓存。</p>
<p>属性的延迟加载：<br />
在property节点中声明lazy=true,而且还需要借助Hibernate类增强器对POJO类的二进制Class文件进行强化处理。</p>
<p>&nbsp;</p>
<p>hibernate中的Collection<br />
Hibernate对JDK Collention接口的独立实现：<br />
由于传统的Java Set, Map, List实现不能满足要求，Hibernate根据这些接口提供了自己的实现。<br />
Hibernate的实现：<br />
无序集：Set, Bag, Map<br />
有序集：List<br />
Bag相当于一个允许重复元素存在的Set。<br />
因为Hibernate是自己的Collection实现，所以如下语句会出错，<br />
Set hset = (HashSet)user.getAddresses();<br />
会在运行期报告一个java.lang.ClassCastException,因为实际上返回的是一个类型为org.hibernate.collention.Set的对象。<br />
所有我们在写POJO时，必须用JDK Collection Interface(如Set, Map)，而非特定的JDK Collection实现类(如HashSet, HashMap)声明Collection型属性的原因。例如：<br />
应该是private Set addresses;<br />
而不是private HashSet addresses;</p>
<p>collection类型属性的保存过程。<br />
例如<br />
public class TUser implements Serializable {<br />
private Set addresses = new HashSet();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ......<br />
}</p>
<p>然后创建一个TUser实例后，就可以为其添加关联的address对象：<br />
TUser user = new TUser();<br />
TAddress addr = new TAddress();<br />
addr.setAddress("HongKong");<br />
user.getAddress().add(addr);<br />
session.save(user);<br />
user对象在经过Hibernate处理后发生了变化，首先，由于insert操作，产生了id值，并填充到user对象的id属性，另一方面Hibernate使用了自己的collection实现对user中的HashSet型addresses属性进行了替换，并用数据对其进行了填充。</p>
<img src ="http://www.blogjava.net/WshmAndLily/aggbug/143415.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/WshmAndLily/" target="_blank">semovy</a> 2007-09-07 15:05 <a href="http://www.blogjava.net/WshmAndLily/articles/143415.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Hibernate延迟加载机制[转]</title><link>http://www.blogjava.net/WshmAndLily/articles/137320.html</link><dc:creator>semovy</dc:creator><author>semovy</author><pubDate>Thu, 16 Aug 2007 08:36:00 GMT</pubDate><guid>http://www.blogjava.net/WshmAndLily/articles/137320.html</guid><wfw:comment>http://www.blogjava.net/WshmAndLily/comments/137320.html</wfw:comment><comments>http://www.blogjava.net/WshmAndLily/articles/137320.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/WshmAndLily/comments/commentRss/137320.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/WshmAndLily/services/trackbacks/137320.html</trackback:ping><description><![CDATA[<div class=tit>Hibernate延迟加载机制</div>
<div class=date>2007年07月26日 星期四 下午 04:00</div>
<table style="TABLE-LAYOUT: fixed">
    <tbody>
        <tr>
            <td>
            <div class=cnt>
            <div><strong><span style="FONT-SIZE: 14pt">延迟加载：</span></strong></div>
            <div><strong><span style="FONT-SIZE: 14pt">&nbsp;&nbsp;</span></strong><strong><span style="FONT-SIZE: 12pt">延迟加载机制是为了避免一些无谓的性能开销而提出来的，所谓延迟加载就是当在真正需要数据的时候，才真正执行数据加载操作。在</span></strong><strong><span style="FONT-SIZE: 12pt">Hibernate</span></strong><strong><span style="FONT-SIZE: 12pt">中提供了对实体对象的延迟加载以及对集合的延迟加载，另外在</span></strong><strong><span style="FONT-SIZE: 12pt">Hibernate3</span></strong><strong><span style="FONT-SIZE: 12pt">中还提供了对属性的延迟加载。下面我们就分别介绍这些种类的延迟加载的细节。</span></strong></div>
            <div style="MARGIN-LEFT: 27pt; TEXT-INDENT: -21pt"><strong><span style="FONT-SIZE: 12pt">A、</span></strong><strong><span style="FONT-SIZE: 12pt">实体对象的延迟加载：</span></strong></div>
            <div style="MARGIN-LEFT: 6pt"><strong><span style="FONT-SIZE: 12pt"></span></strong><strong><span style="FONT-SIZE: 12pt">如果想对实体对象使用延迟加载，必须要在实体的映射配置文件中进行相应的配置，如下所示：</span></strong></div>
            <div style="MARGIN-LEFT: 6pt"><strong><span style="FONT-SIZE: 12pt">&lt;hibernate-mapping&gt;</span></strong></div>
            <div style="MARGIN-LEFT: 6pt"><strong><span style="FONT-SIZE: 12pt">&lt;class name=&#8221;com.neusoft.entity.User&#8221; table=&#8221;user&#8221; <span style="COLOR: red">lazy=&#8221;true&#8221;</span>&gt;</span></strong></div>
            <div style="MARGIN-LEFT: 6pt"><strong><span style="FONT-SIZE: 12pt">&nbsp;&nbsp;&nbsp; &#8230;&#8230;</span></strong></div>
            <div style="MARGIN-LEFT: 6pt"><strong><span style="FONT-SIZE: 12pt">&lt;/class&gt;</span></strong></div>
            <div style="MARGIN-LEFT: 6pt"><strong><span style="FONT-SIZE: 12pt">&lt;/hibernate-mapping&gt;</span></strong></div>
            <div style="MARGIN-LEFT: 6pt"><strong><span style="FONT-SIZE: 12pt">通过将</span></strong><strong><span style="FONT-SIZE: 12pt">class</span></strong><strong><span style="FONT-SIZE: 12pt">的</span></strong><strong><span style="FONT-SIZE: 12pt">lazy</span></strong><strong><span style="FONT-SIZE: 12pt">属性设置为</span></strong><strong><span style="FONT-SIZE: 12pt">true</span></strong><strong><span style="FONT-SIZE: 12pt">，来开启实体的延迟加载特性。如果我们运行下面的代码：</span></strong></div>
            <div style="MARGIN-LEFT: 6pt"><strong><span style="FONT-SIZE: 12pt">User user=(User)session.load(User.class,&#8221;1&#8221;);</span></strong><strong><span style="FONT-SIZE: 12pt">（</span></strong><strong><span style="FONT-SIZE: 12pt">1</span></strong><strong><span style="FONT-SIZE: 12pt">）</span></strong></div>
            <div style="MARGIN-LEFT: 6pt"><strong><span style="FONT-SIZE: 12pt">System.out.println(user.getName());</span></strong><strong><span style="FONT-SIZE: 12pt">（</span></strong><strong><span style="FONT-SIZE: 12pt">2</span></strong><strong><span style="FONT-SIZE: 12pt">）</span></strong></div>
            <div style="MARGIN-LEFT: 6pt"><strong><span style="FONT-SIZE: 12pt">当运行到</span></strong><strong><span style="FONT-SIZE: 12pt">(1)</span></strong><strong><span style="FONT-SIZE: 12pt">处时，</span></strong><strong><span style="FONT-SIZE: 12pt">Hibernate</span></strong><strong><span style="FONT-SIZE: 12pt">并没有发起对数据的查询，如果我们此时通过一些调试工具</span></strong><strong><span style="FONT-SIZE: 12pt">(</span></strong><strong><span style="FONT-SIZE: 12pt">比如</span></strong><strong><span style="FONT-SIZE: 12pt">JBuilder2005</span></strong><strong><span style="FONT-SIZE: 12pt">的</span></strong><strong><span style="FONT-SIZE: 12pt">Debug</span></strong><strong><span style="FONT-SIZE: 12pt">工具</span></strong><strong><span style="FONT-SIZE: 12pt">)</span></strong><strong><span style="FONT-SIZE: 12pt">，观察此时</span></strong><strong><span style="FONT-SIZE: 12pt">user</span></strong><strong><span style="FONT-SIZE: 12pt">对象的内存快照，我们会惊奇的发现，此时返回的可能是</span></strong><strong><span style="FONT-SIZE: 12pt">User$EnhancerByCGLIB$$bede8986</span></strong><strong><span style="FONT-SIZE: 12pt">类型的对象，而且其属性为</span></strong><strong><span style="FONT-SIZE: 12pt">null,</span></strong><strong><span style="FONT-SIZE: 12pt">这是怎么回事？还记得前面我曾讲过</span></strong><strong><span style="FONT-SIZE: 12pt">session.load()</span></strong><strong><span style="FONT-SIZE: 12pt">方法，会返回实体对象的代理类对象，这里所返回的对象类型就是</span></strong><strong><span style="FONT-SIZE: 12pt">User</span></strong><strong><span style="FONT-SIZE: 12pt">对象的代理类对象。在</span></strong><strong><span style="FONT-SIZE: 12pt">Hibernate</span></strong><strong><span style="FONT-SIZE: 12pt">中通过使用</span></strong><strong><span style="FONT-SIZE: 12pt">CGLIB,</span></strong><strong><span style="FONT-SIZE: 12pt">来实现动态构造一个目标对象的代理类对象，并且在代理类对象中包含目标对象的所有属性和方法，而且所有属性均被赋值为</span></strong><strong><span style="FONT-SIZE: 12pt">null</span></strong><strong><span style="FONT-SIZE: 12pt">。通过调试器显示的内存快照，我们可以看出此时真正的</span></strong><strong><span style="FONT-SIZE: 12pt">User</span></strong><strong><span style="FONT-SIZE: 12pt">对象，是包含在代理对象的</span></strong><strong><span style="FONT-SIZE: 12pt">CGLIB$CALBACK_0.target</span></strong><strong><span style="FONT-SIZE: 12pt">属性中，当代码运行到（</span></strong><strong><span style="FONT-SIZE: 12pt">2</span></strong><strong><span style="FONT-SIZE: 12pt">）处时，此时调用</span></strong><strong><span style="FONT-SIZE: 12pt">user.getName()</span></strong><strong><span style="FONT-SIZE: 12pt">方法，这时通过</span></strong><strong><span style="FONT-SIZE: 12pt">CGLIB</span></strong><strong><span style="FONT-SIZE: 12pt">赋予的回调机制，实际上调用</span></strong><strong><span style="FONT-SIZE: 12pt">CGLIB$CALBACK_0.getName()</span></strong><strong><span style="FONT-SIZE: 12pt">方法，当调用该方法时，</span></strong><strong><span style="FONT-SIZE: 12pt">Hibernate</span></strong><strong><span style="FONT-SIZE: 12pt">会首先检查</span></strong><strong><span style="FONT-SIZE: 12pt">CGLIB$CALBACK_0.target</span></strong><strong><span style="FONT-SIZE: 12pt">属性是否为</span></strong><strong><span style="FONT-SIZE: 12pt">null</span></strong><strong><span style="FONT-SIZE: 12pt">，如果不为空，则调用目标对象的</span></strong><strong><span style="FONT-SIZE: 12pt">getName</span></strong><strong><span style="FONT-SIZE: 12pt">方法，如果为空，则会发起数据库查询，生成类似这样的</span></strong><strong><span style="FONT-SIZE: 12pt">SQL</span></strong><strong><span style="FONT-SIZE: 12pt">语句：</span></strong><strong><span style="FONT-SIZE: 12pt">select * from user where id=&#8217;1&#8217;;</span></strong><strong><span style="FONT-SIZE: 12pt">来查询数据，并构造目标对象，并且将它赋值到</span></strong><strong><span style="FONT-SIZE: 12pt">CGLIB$CALBACK_0.target</span></strong><strong><span style="FONT-SIZE: 12pt">属性中。</span></strong></div>
            <div style="MARGIN-LEFT: 6pt"><strong><span style="FONT-SIZE: 12pt">&nbsp;&nbsp;&nbsp;</span></strong><strong><span style="FONT-SIZE: 12pt">这样，通过一个中间代理对象，</span></strong><strong><span style="FONT-SIZE: 12pt">Hibernate</span></strong><strong><span style="FONT-SIZE: 12pt">实现了实体的延迟加载，只有当用户真正发起获得实体对象属性的动作时，才真正会发起数据库查询操作。所以实体的延迟加载是用通过中间代理类完成的，所以只有</span></strong><strong><span style="FONT-SIZE: 12pt">session.load()</span></strong><strong><span style="FONT-SIZE: 12pt">方法才会利用实体延迟加载，因为只有</span></strong><strong><span style="FONT-SIZE: 12pt">session.load()</span></strong><strong><span style="FONT-SIZE: 12pt">方法才会返回实体类的代理类对象。</span></strong></div>
            <div style="MARGIN-LEFT: 27pt; TEXT-INDENT: -21pt"><strong><span style="FONT-SIZE: 14pt">B、<span style="FONT: 7pt Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></span></strong><strong><span style="FONT-SIZE: 14pt">集合类型的延迟加载：</span></strong></div>
            <div style="MARGIN-LEFT: 6pt; TEXT-INDENT: 25.5pt"><strong><span style="FONT-SIZE: 12pt">在</span></strong><strong><span style="FONT-SIZE: 12pt">Hibernate</span></strong><strong><span style="FONT-SIZE: 12pt">的延迟加载机制中，针对集合类型的应用，意义是最为重大的，因为这有可能使性能得到大幅度的提高，为此</span></strong><strong><span style="FONT-SIZE: 12pt">Hibernate</span></strong><strong><span style="FONT-SIZE: 12pt">进行了大量的努力，其中包括对</span></strong><strong><span style="FONT-SIZE: 12pt">JDK Collection</span></strong><strong><span style="FONT-SIZE: 12pt">的独立实现，我们在一对多关联中，定义的用来容纳关联对象的</span></strong><strong><span style="FONT-SIZE: 12pt">Set</span></strong><strong><span style="FONT-SIZE: 12pt">集合，并不是</span></strong><strong><span style="FONT-SIZE: 12pt">java.util.Set</span></strong><strong><span style="FONT-SIZE: 12pt">类型或其子类型，而是</span></strong><strong><span style="FONT-SIZE: 12pt">net.sf.hibernate.collection.Set</span></strong><strong><span style="FONT-SIZE: 12pt">类型，通过使用自定义集合类的实现，</span></strong><strong><span style="FONT-SIZE: 12pt">Hibernate</span></strong><strong><span style="FONT-SIZE: 12pt">实现了集合类型的延迟加载。为了对集合类型使用延迟加载，我们必须如下配置我们的实体类的关于关联的部分：</span></strong></div>
            <div><strong><span style="FONT-SIZE: 12pt">&lt;hibernate-mapping&gt;</span></strong></div>
            <div><strong><span style="FONT-SIZE: 12pt">&nbsp;&nbsp;&nbsp; &lt;class name=&#8221;com.neusoft.entity.User&#8221; table=&#8221;user&#8221;&gt;</span></strong></div>
            <div style="TEXT-INDENT: 24pt"><strong><span style="FONT-SIZE: 12pt">&#8230;..</span></strong></div>
            <div style="TEXT-INDENT: 24pt"><strong><span style="FONT-SIZE: 12pt">&lt;set name=&#8221;addresses&#8221; table=&#8221;address&#8221;<span style="COLOR: red"> lazy=&#8221;true&#8221;</span> inverse=&#8221;true&#8221;&gt;</span></strong></div>
            <div style="TEXT-INDENT: 29.9pt"><strong><span style="FONT-SIZE: 12pt">&lt;key column=&#8221;user_id&#8221;/&gt;</span></strong></div>
            <div style="TEXT-INDENT: 24pt"><strong><span style="FONT-SIZE: 12pt">&lt;one-to-many class=&#8221;com.neusoft.entity.Arrderss&#8221;/&gt;</span></strong></div>
            <div style="TEXT-INDENT: 24pt"><strong><span style="FONT-SIZE: 12pt">&lt;/set&gt;</span></strong></div>
            <div><strong><span style="FONT-SIZE: 12pt">&nbsp;&nbsp;&nbsp; &lt;/class&gt;</span></strong></div>
            <div><strong><span style="FONT-SIZE: 12pt">&lt;/hibernate-mapping&gt;</span></strong></div>
            <div><strong><span style="FONT-SIZE: 12pt">通过将</span></strong><strong><span style="FONT-SIZE: 12pt">&lt;set&gt;</span></strong><strong><span style="FONT-SIZE: 12pt">元素的</span></strong><strong><span style="FONT-SIZE: 12pt">lazy</span></strong><strong><span style="FONT-SIZE: 12pt">属性设置为</span></strong><strong><span style="FONT-SIZE: 12pt">true</span></strong><strong><span style="FONT-SIZE: 12pt">来开启集合类型的延迟加载特性。我们看下面的代码：</span></strong></div>
            <div><strong><span style="FONT-SIZE: 12pt">User user=(User)session.load(User.class,&#8221;1&#8221;);</span></strong></div>
            <div><strong><span style="FONT-SIZE: 12pt">Collection addset=user.getAddresses();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1)</span></strong></div>
            <div><strong><span style="FONT-SIZE: 12pt">Iterator it=addset.iterator();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2)</span></strong></div>
            <div><strong><span style="FONT-SIZE: 12pt">while(it.hasNext()){</span></strong></div>
            <div><strong><span style="FONT-SIZE: 12pt">Address address=(Address)it.next();</span></strong></div>
            <div><strong><span style="FONT-SIZE: 12pt">System.out.println(address.getAddress());</span></strong></div>
            <div><strong><span style="FONT-SIZE: 12pt">}</span></strong></div>
            <div><strong><span style="FONT-SIZE: 12pt">当程序执行到</span></strong><strong><span style="FONT-SIZE: 12pt">(1)</span></strong><strong><span style="FONT-SIZE: 12pt">处时，这时并不会发起对关联数据的查询来加载关联数据，只有运行到</span></strong><strong><span style="FONT-SIZE: 12pt">(2)</span></strong><strong><span style="FONT-SIZE: 12pt">处时，真正的数据读取操作才会开始，这时</span></strong><strong><span style="FONT-SIZE: 12pt">Hibernate</span></strong><strong><span style="FONT-SIZE: 12pt">会根据缓存中符合条件的数据索引，来查找符合条件的实体对象。</span></strong></div>
            <div><strong><span style="FONT-SIZE: 12pt">这里我们引入了一个全新的概念——数据索引，下面我们首先将接一下什么是数据索引。在</span></strong><strong><span style="FONT-SIZE: 12pt">Hibernate</span></strong><strong><span style="FONT-SIZE: 12pt">中对集合类型进行缓存时，是分两部分进行缓存的，首先缓存集合中所有实体的</span></strong><strong><span style="FONT-SIZE: 12pt">id</span></strong><strong><span style="FONT-SIZE: 12pt">列表，然后缓存实体对象，这些实体对象的</span></strong><strong><span style="FONT-SIZE: 12pt">id</span></strong><strong><span style="FONT-SIZE: 12pt">列表，就是所谓的数据索引。当查找数据索引时，如果没有找到对应的数据索引，这时就会一条</span></strong><strong><span style="FONT-SIZE: 12pt">select SQL</span></strong><strong><span style="FONT-SIZE: 12pt">的执行，获得符合条件的数据，并构造实体对象集合和数据索引，然后返回实体对象的集合，并且将实体对象和数据索引纳入</span></strong><strong><span style="FONT-SIZE: 12pt">Hibernate</span></strong><strong><span style="FONT-SIZE: 12pt">的缓存之中。另一方面，如果找到对应的数据索引，则从数据索引中取出</span></strong><strong><span style="FONT-SIZE: 12pt">id</span></strong><strong><span style="FONT-SIZE: 12pt">列表，然后根据</span></strong><strong><span style="FONT-SIZE: 12pt">id</span></strong><strong><span style="FONT-SIZE: 12pt">在缓存中查找对应的实体，如果找到就从缓存中返回，如果没有找到，在发起</span></strong><strong><span style="FONT-SIZE: 12pt">select SQL</span></strong><strong><span style="FONT-SIZE: 12pt">查询。在这里我们看出了另外一个问题，这个问题可能会对性能产生影响，这就是集合类型的缓存策略。如果我们如下配置集合类型：</span></strong></div>
            <div><strong><span style="FONT-SIZE: 12pt">&lt;hibernate-mapping&gt;</span></strong></div>
            <div><strong><span style="FONT-SIZE: 12pt">&nbsp;&nbsp;&nbsp; &lt;class name=&#8221;com.neusoft.entity.User&#8221; table=&#8221;user&#8221;&gt;</span></strong></div>
            <div style="TEXT-INDENT: 24pt"><strong><span style="FONT-SIZE: 12pt">&#8230;..</span></strong></div>
            <div style="TEXT-INDENT: 24pt"><strong><span style="FONT-SIZE: 12pt">&lt;set name=&#8221;addresses&#8221; table=&#8221;address&#8221;<span style="COLOR: red"> lazy=&#8221;true&#8221;</span> inverse=&#8221;true&#8221;&gt;</span></strong></div>
            <div style="TEXT-INDENT: 24pt"><strong><span style="FONT-SIZE: 12pt"><span style="COLOR: red">&lt;cache usage=&#8221;read-only&#8221;/&gt;</span></span></strong></div>
            <div style="TEXT-INDENT: 29.9pt"><strong><span style="FONT-SIZE: 12pt">&lt;key column=&#8221;user_id&#8221;/&gt;</span></strong></div>
            <div style="TEXT-INDENT: 24pt"><strong><span style="FONT-SIZE: 12pt">&lt;one-to-many class=&#8221;com.neusoft.entity.Arrderss&#8221;/&gt;</span></strong></div>
            <div style="TEXT-INDENT: 24pt"><strong><span style="FONT-SIZE: 12pt">&lt;/set&gt;</span></strong></div>
            <div><strong><span style="FONT-SIZE: 12pt">&nbsp;&nbsp;&nbsp; &lt;/class&gt;</span></strong></div>
            <div><strong><span style="FONT-SIZE: 12pt">&lt;/hibernate-mapping&gt;</span></strong></div>
            <div><strong><span style="FONT-SIZE: 12pt">这里我们应用了</span></strong><strong><span style="FONT-SIZE: 12pt; COLOR: red">&lt;cache usage=&#8221;read-only&#8221;/&gt;</span></strong><strong><span style="FONT-SIZE: 12pt; COLOR: black">配置，如果采用这种策略来配置集合类型，</span></strong><strong><span style="FONT-SIZE: 12pt; COLOR: black">Hibernate</span></strong><strong><span style="FONT-SIZE: 12pt; COLOR: black">将只会对数据索引进行缓存，而不会对集合中的实体对象进行缓存。如上配置我们运行下面的代码：</span></strong></div>
            <div><strong><span style="FONT-SIZE: 12pt">User user=(User)session.load(User.class,&#8221;1&#8221;);</span></strong></div>
            <div><strong><span style="FONT-SIZE: 12pt">Collection addset=user.getAddresses();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></strong></div>
            <div><strong><span style="FONT-SIZE: 12pt">Iterator it=addset.iterator();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></strong></div>
            <div><strong><span style="FONT-SIZE: 12pt">while(it.hasNext()){</span></strong></div>
            <div><strong><span style="FONT-SIZE: 12pt">Address address=(Address)it.next();</span></strong></div>
            <div><strong><span style="FONT-SIZE: 12pt">System.out.println(address.getAddress());</span></strong></div>
            <div><strong><span style="FONT-SIZE: 12pt">}</span></strong></div>
            <div><strong><span style="FONT-SIZE: 12pt">System.out.println(&#8220;Second query&#8230;&#8230;&#8221;);</span></strong></div>
            <div><strong><span style="FONT-SIZE: 12pt">User user2=(User)session.load(User.class,&#8221;1&#8221;);</span></strong></div>
            <div><strong><span style="FONT-SIZE: 12pt">Collection it2=user2.getAddresses();</span></strong></div>
            <div><strong><span style="FONT-SIZE: 12pt">while(it2.hasNext()){</span></strong></div>
            <div><strong><span style="FONT-SIZE: 12pt">Address address2=(Address)it2.next();</span></strong></div>
            <div><strong><span style="FONT-SIZE: 12pt">System.out.println(address2.getAddress());</span></strong></div>
            <div><strong><span style="FONT-SIZE: 12pt">}</span></strong></div>
            <div><strong><span style="FONT-SIZE: 12pt">运行这段代码，会得到类似下面的输出：</span></strong></div>
            <div><strong><span style="FONT-SIZE: 12pt">Select * from user where id=&#8217;1&#8217;;</span></strong></div>
            <div><strong><span style="FONT-SIZE: 12pt">Select * from address where user_id=&#8217;1&#8217;;</span></strong></div>
            <div><strong><span style="FONT-SIZE: 12pt">Tianjin</span></strong></div>
            <div><strong><span style="FONT-SIZE: 12pt">Dalian</span></strong></div>
            <div><strong><span style="FONT-SIZE: 12pt">Second query&#8230;&#8230;</span></strong></div>
            <div><strong><span style="FONT-SIZE: 12pt">Select * from address where id=&#8217;1&#8217;;</span></strong></div>
            <div><strong><span style="FONT-SIZE: 12pt">Select * from address where id=&#8217;2&#8217;;</span></strong></div>
            <div><strong><span style="FONT-SIZE: 12pt">Tianjin</span></strong></div>
            <div><strong><span style="FONT-SIZE: 12pt">Dalian</span></strong></div>
            <div><strong><span style="FONT-SIZE: 12pt">我们看到，当第二次执行查询时，执行了两条对</span></strong><strong><span style="FONT-SIZE: 12pt">address</span></strong><strong><span style="FONT-SIZE: 12pt">表的查询操作，为什么会这样？这是因为当第一次加载实体后，根据集合类型缓存策略的配置，只对集合数据索引进行了缓存，而并没有对集合中的实体对象进行缓存，所以在第二次再次加载实体时，</span></strong><strong><span style="FONT-SIZE: 12pt">Hibernate</span></strong><strong><span style="FONT-SIZE: 12pt">找到了对应实体的数据索引，但是根据数据索引，却无法在缓存中找到对应的实体，所以</span></strong><strong><span style="FONT-SIZE: 12pt">Hibernate</span></strong><strong><span style="FONT-SIZE: 12pt">根据找到的数据索引发起了两条</span></strong><strong><span style="FONT-SIZE: 12pt">select SQL</span></strong><strong><span style="FONT-SIZE: 12pt">的查询操作，这里造成了对性能的浪费，怎样才能避免这种情况呢？我们必须对集合类型中的实体也指定缓存策略，所以我们要如下对集合类型进行配置：</span></strong></div>
            <div><strong><span style="FONT-SIZE: 12pt">&lt;hibernate-mapping&gt;</span></strong></div>
            <div><strong><span style="FONT-SIZE: 12pt">&nbsp;&nbsp;&nbsp; &lt;class name=&#8221;com.neusoft.entity.User&#8221; table=&#8221;user&#8221;&gt;</span></strong></div>
            <div style="TEXT-INDENT: 24pt"><strong><span style="FONT-SIZE: 12pt">&#8230;..</span></strong></div>
            <div style="TEXT-INDENT: 24pt"><strong><span style="FONT-SIZE: 12pt">&lt;set name=&#8221;addresses&#8221; table=&#8221;address&#8221;<span style="COLOR: red"> lazy=&#8221;true&#8221;</span> inverse=&#8221;true&#8221;&gt;</span></strong></div>
            <div style="TEXT-INDENT: 24pt"><strong><span style="FONT-SIZE: 12pt"><span style="COLOR: red">&lt;cache usage=&#8221;read-write&#8221;/&gt;</span></span></strong></div>
            <div style="TEXT-INDENT: 29.9pt"><strong><span style="FONT-SIZE: 12pt">&lt;key column=&#8221;user_id&#8221;/&gt;</span></strong></div>
            <div style="TEXT-INDENT: 24pt"><strong><span style="FONT-SIZE: 12pt">&lt;one-to-many class=&#8221;com.neusoft.entity.Arrderss&#8221;/&gt;</span></strong></div>
            <div style="TEXT-INDENT: 24pt"><strong><span style="FONT-SIZE: 12pt">&lt;/set&gt;</span></strong></div>
            <div><strong><span style="FONT-SIZE: 12pt">&nbsp;&nbsp;&nbsp; &lt;/class&gt;</span></strong></div>
            <div><strong><span style="FONT-SIZE: 12pt">&lt;/hibernate-mapping&gt;</span></strong></div>
            <div><strong><span style="FONT-SIZE: 12pt">此时</span></strong><strong><span style="FONT-SIZE: 12pt">Hibernate</span></strong><strong><span style="FONT-SIZE: 12pt">会对集合类型中的实体也进行缓存，如果根据这个配置再次运行上面的代码，将会得到类似如下的输出：</span></strong></div>
            <div><strong><span style="FONT-SIZE: 12pt">Select * from user where id=&#8217;1&#8217;;</span></strong></div>
            <div><strong><span style="FONT-SIZE: 12pt">Select * from address where user_id=&#8217;1&#8217;;</span></strong></div>
            <div><strong><span style="FONT-SIZE: 12pt">Tianjin</span></strong></div>
            <div><strong><span style="FONT-SIZE: 12pt">Dalian</span></strong></div>
            <div><strong><span style="FONT-SIZE: 12pt">Second query&#8230;&#8230;</span></strong></div>
            <div><strong><span style="FONT-SIZE: 12pt">Tianjin</span></strong></div>
            <div><strong><span style="FONT-SIZE: 12pt">Dalian</span></strong></div>
            <div><strong><span style="FONT-SIZE: 12pt">这时将不会再有根据数据索引进行查询的</span></strong><strong><span style="FONT-SIZE: 12pt">SQL</span></strong><strong><span style="FONT-SIZE: 12pt">语句，因为此时可以直接从缓存中获得集合类型中存放的实体对象。</span></strong></div>
            <div style="MARGIN-LEFT: 27pt; TEXT-INDENT: -21pt"><strong><span style="FONT-SIZE: 14pt">C、<span style="FONT: 7pt Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></span></strong><strong><span style="FONT-SIZE: 14pt">属性延迟加载：</span></strong></div>
            <div style="MARGIN-LEFT: 6pt"><strong><span style="FONT-SIZE: 14pt">&nbsp;&nbsp;</span></strong><strong><span style="FONT-SIZE: 12pt">在</span></strong><strong><span style="FONT-SIZE: 12pt">Hibernate3</span></strong><strong><span style="FONT-SIZE: 12pt">中，引入了一种新的特性——属性的延迟加载，这个机制又为获取高性能查询提供了有力的工具。在前面我们讲大数据对象读取时，在</span></strong><strong><span style="FONT-SIZE: 12pt">User</span></strong><strong><span style="FONT-SIZE: 12pt">对象中有一个</span></strong><strong><span style="FONT-SIZE: 12pt">resume</span></strong><strong><span style="FONT-SIZE: 12pt">字段，该字段是一个</span></strong><strong><span style="FONT-SIZE: 12pt">java.sql.Clob</span></strong><strong><span style="FONT-SIZE: 12pt">类型，包含了用户的简历信息，当我们加载该对象时，我们不得不每一次都要加载这个字段，而不论我们是否真的需要它，而且这种大数据对象的读取本身会带来很大的性能开销。在</span></strong><strong><span style="FONT-SIZE: 12pt">Hibernate2</span></strong><strong><span style="FONT-SIZE: 12pt">中，我们只有通过我们前面讲过的面性能的粒度细分，来分解</span></strong><strong><span style="FONT-SIZE: 12pt">User</span></strong><strong><span style="FONT-SIZE: 12pt">类，来解决这个问题（请参照那一节的论述），但是在</span></strong><strong><span style="FONT-SIZE: 12pt">Hibernate3</span></strong><strong><span style="FONT-SIZE: 12pt">中，我们可以通过属性延迟加载机制，来使我们获得只有当我们真正需要操作这个字段时，才去读取这个字段数据的能力，为此我们必须如下配置我们的实体类：</span></strong></div>
            <div style="MARGIN-LEFT: 6pt"><strong><span style="FONT-SIZE: 12pt">&lt;hibernate-mapping&gt;</span></strong></div>
            <div style="MARGIN-LEFT: 6pt"><strong><span style="FONT-SIZE: 12pt">&lt;class name=&#8221;com.neusoft.entity.User&#8221; table=&#8221;user&#8221;&gt;</span></strong></div>
            <div style="MARGIN-LEFT: 6pt; TEXT-INDENT: 24pt"><strong><span style="FONT-SIZE: 12pt">&#8230;&#8230;</span></strong></div>
            <div style="MARGIN-LEFT: 6pt; TEXT-INDENT: 24pt"><strong><span style="FONT-SIZE: 12pt">&lt;property name=&#8221;resume&#8221; type=&#8221;java.sql.Clob&#8221; column=&#8221;resume&#8221; <span style="COLOR: red">lazy=&#8221;true&#8221;</span>/&gt;</span></strong></div>
            <div><strong><span style="FONT-SIZE: 12pt">&nbsp;&nbsp;&nbsp; &lt;/class&gt;</span></strong></div>
            <div style="MARGIN-LEFT: 6pt"><strong><span style="FONT-SIZE: 12pt">&lt;/hibernate-mapping&gt;</span></strong></div>
            <div style="MARGIN-LEFT: 6pt"><strong><span style="FONT-SIZE: 12pt">通过对</span></strong><strong><span style="FONT-SIZE: 12pt">&lt;property&gt;</span></strong><strong><span style="FONT-SIZE: 12pt">元素的</span></strong><strong><span style="FONT-SIZE: 12pt">lazy</span></strong><strong><span style="FONT-SIZE: 12pt">属性设置</span></strong><strong><span style="FONT-SIZE: 12pt">true</span></strong><strong><span style="FONT-SIZE: 12pt">来开启属性的延迟加载，在</span></strong><strong><span style="FONT-SIZE: 12pt">Hibernate3</span></strong><strong><span style="FONT-SIZE: 12pt">中为了实现属性的延迟加载，使用了类增强器来对实体类的</span></strong><strong><span style="FONT-SIZE: 12pt">Class</span></strong><strong><span style="FONT-SIZE: 12pt">文件进行强化处理，通过增强器的增强，将</span></strong><strong><span style="FONT-SIZE: 12pt">CGLIB</span></strong><strong><span style="FONT-SIZE: 12pt">的回调机制逻辑，加入实体类，这里我们可以看出属性的延迟加载，还是通过</span></strong><strong><span style="FONT-SIZE: 12pt">CGLIB</span></strong><strong><span style="FONT-SIZE: 12pt">来实现的。</span></strong><strong><span style="FONT-SIZE: 12pt">CGLIB</span></strong><strong><span style="FONT-SIZE: 12pt">是</span></strong><strong><span style="FONT-SIZE: 12pt">Apache</span></strong><strong><span style="FONT-SIZE: 12pt">的一个开源工程，这个类库可以操纵</span></strong><strong><span style="FONT-SIZE: 12pt">java</span></strong><strong><span style="FONT-SIZE: 12pt">类的字节码，根据字节码来动态构造符合要求的类对象。根据上面的配置我们运行下面的代码：</span></strong></div>
            <div style="MARGIN-LEFT: 6pt"><strong><span style="FONT-SIZE: 12pt">String sql=&#8221;from User user where user.name=&#8217;zx&#8217; &#8221;;</span></strong></div>
            <div style="MARGIN-LEFT: 6pt"><strong><span style="FONT-SIZE: 12pt">Query query=session.createQuery(sql);&nbsp;&nbsp;&nbsp; (1)</span></strong></div>
            <div style="MARGIN-LEFT: 6pt"><strong><span style="FONT-SIZE: 12pt">List list=query.list();</span></strong></div>
            <div style="MARGIN-LEFT: 6pt"><strong><span style="FONT-SIZE: 12pt">for(int i=0;i&lt;list.size();i++){</span></strong></div>
            <div style="MARGIN-LEFT: 6pt"><strong><span style="FONT-SIZE: 12pt">User user=(User)list.get(i);</span></strong></div>
            <div style="MARGIN-LEFT: 6pt"><strong><span style="FONT-SIZE: 12pt">System.out.println(user.getName());</span></strong></div>
            <div style="MARGIN-LEFT: 6pt"><strong><span style="FONT-SIZE: 12pt">System.out.println(user.getResume());&nbsp;&nbsp;&nbsp; (2)</span></strong></div>
            <div style="MARGIN-LEFT: 6pt"><strong><span style="FONT-SIZE: 12pt">}</span></strong></div>
            <div style="MARGIN-LEFT: 6pt"><strong><span style="FONT-SIZE: 12pt">当执行到</span></strong><strong><span style="FONT-SIZE: 12pt">(1)</span></strong><strong><span style="FONT-SIZE: 12pt">处时，会生成类似如下的</span></strong><strong><span style="FONT-SIZE: 12pt">SQL</span></strong><strong><span style="FONT-SIZE: 12pt">语句：</span></strong></div>
            <div style="MARGIN-LEFT: 6pt"><strong><span style="FONT-SIZE: 12pt">Select id,age,name from user where name=&#8217;zx&#8217;;</span></strong></div>
            <div style="MARGIN-LEFT: 6pt"><strong><span style="FONT-SIZE: 12pt">这时</span></strong><strong><span style="FONT-SIZE: 12pt">Hibernate</span></strong><strong><span style="FONT-SIZE: 12pt">会检索</span></strong><strong><span style="FONT-SIZE: 12pt">User</span></strong><strong><span style="FONT-SIZE: 12pt">实体中所有非延迟加载属性对应的字段数据，当执行到</span></strong><strong><span style="FONT-SIZE: 12pt">(2)</span></strong><strong><span style="FONT-SIZE: 12pt">处时，会生成类似如下的</span></strong><strong><span style="FONT-SIZE: 12pt">SQL</span></strong><strong><span style="FONT-SIZE: 12pt">语句：</span></strong></div>
            <div style="MARGIN-LEFT: 6pt"><strong><span style="FONT-SIZE: 12pt">Select resume from user where id=&#8217;1&#8217;;</span></strong></div>
            <div style="MARGIN-LEFT: 6pt"><strong><span style="FONT-SIZE: 12pt">这时会发起对</span></strong><strong><span style="FONT-SIZE: 12pt">resume</span></strong><strong><span style="FONT-SIZE: 12pt">字段数据真正的读取操作。</span></strong></div>
            </div>
            </td>
        </tr>
    </tbody>
</table>
<img src ="http://www.blogjava.net/WshmAndLily/aggbug/137320.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/WshmAndLily/" target="_blank">semovy</a> 2007-08-16 16:36 <a href="http://www.blogjava.net/WshmAndLily/articles/137320.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>spring中配置二级缓存 </title><link>http://www.blogjava.net/WshmAndLily/articles/137244.html</link><dc:creator>semovy</dc:creator><author>semovy</author><pubDate>Thu, 16 Aug 2007 06:12:00 GMT</pubDate><guid>http://www.blogjava.net/WshmAndLily/articles/137244.html</guid><wfw:comment>http://www.blogjava.net/WshmAndLily/comments/137244.html</wfw:comment><comments>http://www.blogjava.net/WshmAndLily/articles/137244.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/WshmAndLily/comments/commentRss/137244.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/WshmAndLily/services/trackbacks/137244.html</trackback:ping><description><![CDATA[<p>1.首先,在spring的hibernate配置里(我的是applicationContext-hibernate.xml)&nbsp;加上如下属性:</p>
<p>&lt;bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"&gt;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&lt;property name="dataSource"&gt;<br>&nbsp;&nbsp;&nbsp;&lt;ref bean="dataSource"/&gt;<br>&nbsp;&nbsp;&lt;/property&gt;<br>&nbsp;&nbsp;&lt;property name="mappingResources"&gt;<br>&nbsp;&nbsp;&nbsp;&lt;list&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&lt;value&gt;org/appfteaching/model/TArticleclass.hbm.xml&lt;/value&gt;<br>&nbsp;&nbsp;&nbsp;&lt;/list&gt;<br>&nbsp;&nbsp;&lt;/property&gt;<br>&nbsp;&nbsp;&lt;property name="hibernateProperties"&gt;<br>&nbsp;&nbsp;&nbsp;&lt;props&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&lt;prop key="hibernate.dialect"&gt;${hibernate.dialect}&lt;/prop&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;prop key="hibernate.show_sql"&gt;${hibernate.show_sql}&lt;/prop&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;prop key="hibernate.jdbc.fetch_size"&gt;${hibernate.jdbc.fetch_size}&lt;/prop&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;prop key="hibernate.jdbc.batch_size"&gt;${hibernate.jdbc.batch_size}&lt;/prop&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font color=#ff0000>&lt;prop key="hibernate.cache.use_query_cache"&gt;true&lt;/prop&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;prop key="hibernate.cache.provider_class"&gt;org.hibernate.cache.EhCacheProvider&lt;/prop&gt;<br></font>&nbsp;&nbsp;&nbsp;&lt;/props&gt;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&lt;/property&gt;&nbsp;&nbsp;<br>&nbsp;&lt;/bean&gt;&nbsp;</p>
<p>2.其次,在src目录下的ehcache.xml中配置如下信息(如果是默认ehcache.xml则会有&lt;cache name="sampleCache1"&gt;和&lt;cache name="sampleCache2&gt;",去掉)</p>
<p>&lt;cache name="org.hibernate.cache.StandardQueryCache"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; maxElementsInMemory="10000"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; eternal="false"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; timeToIdleSeconds="300"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; timeToLiveSeconds="4200"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; overflowToDisk="true"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /&gt;</p>
<p>&nbsp;&nbsp;&nbsp; &lt;!-- Sample cache named sampleCache2<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; This cache contains 1000 elements. Elements will always be held in memory.<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; They are not expired. --&gt;</p>
<p>&nbsp;&nbsp;&nbsp; &lt;cache name="org.hibernate.cache.UpdateTimestampsCache"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; maxElementsInMemory="5000"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; eternal="true"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; timeToIdleSeconds="0"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; timeToLiveSeconds="0"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; overflowToDisk="false"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /&gt; </p>
<p>3.将你要缓存的model加进ehcache.xml里</p>
<p>&lt;cache name="org.appfteaching.model.TArticleclass" <br>&nbsp;&nbsp;&nbsp; &nbsp;maxElementsInMemory="1000"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; eternal="false"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; timeToIdleSeconds="100"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; timeToLiveSeconds="4200"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; overflowToDisk="true"<br>&nbsp;&nbsp;&nbsp; &nbsp;/&gt;&nbsp;&nbsp; </p>
<p>4.最后一步,在TArticleclass.hbm.xml里加上</p>
<p>&lt;cache usage="read-write"/&gt;</p>
<p>启动Tomcat,如发现如下错误</p>
<p>Could not find configuration [org.hibernate.cache.UpdateTimestampsCache]; using defaults.<br>Could not find configuration [org.hibernate.cache.StandardQueryCache]; using defaults.</p>
<p>则是第二步没有做,加上即可.配置完毕</p>
<img src ="http://www.blogjava.net/WshmAndLily/aggbug/137244.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/WshmAndLily/" target="_blank">semovy</a> 2007-08-16 14:12 <a href="http://www.blogjava.net/WshmAndLily/articles/137244.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>criteria</title><link>http://www.blogjava.net/WshmAndLily/articles/135998.html</link><dc:creator>semovy</dc:creator><author>semovy</author><pubDate>Sat, 11 Aug 2007 03:52:00 GMT</pubDate><guid>http://www.blogjava.net/WshmAndLily/articles/135998.html</guid><wfw:comment>http://www.blogjava.net/WshmAndLily/comments/135998.html</wfw:comment><comments>http://www.blogjava.net/WshmAndLily/articles/135998.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/WshmAndLily/comments/commentRss/135998.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/WshmAndLily/services/trackbacks/135998.html</trackback:ping><description><![CDATA[<div class=sect1 lang=zh-cn>
<div class=titlepage>
<div>
<div>
<h2 class=title style="CLEAR: both"><a name=querycriteria-creating></a>16.1.&nbsp;创建一个<tt class=literal>Criteria</tt> 实例</h2>
</div>
</div>
<div></div>
</div>
<p><tt class=literal>org.hibernate.Criteria</tt>接口表示特定持久类的一个查询。<tt class=literal>Session</tt>是 <tt class=literal>Criteria</tt>实例的工厂。 </p>
<pre class=programlisting>Criteria crit = sess.createCriteria(Cat.class);
crit.setMaxResults(50);
List cats = crit.list();</pre>
</div>
<div class=sect1 lang=zh-cn>
<div class=titlepage>
<div>
<div>
<h2 class=title style="CLEAR: both"><a name=querycriteria-narrowing></a>16.2.&nbsp;限制结果集内容</h2>
</div>
</div>
<div></div>
</div>
<p>一个单独的查询条件是<tt class=literal>org.hibernate.criterion.Criterion</tt> 接口的一个实例。<tt class=literal>org.hibernate.criterion.Restrictions</tt>类 定义了获得某些内置<tt class=literal>Criterion</tt>类型的工厂方法。 </p>
<pre class=programlisting>List cats = sess.createCriteria(Cat.class)
.add( Restrictions.like("name", "Fritz%") )
.add( Restrictions.between("weight", minWeight, maxWeight) )
.list();</pre>
<p>约束可以按逻辑分组。 </p>
<pre class=programlisting>List cats = sess.createCriteria(Cat.class)
.add( Restrictions.like("name", "Fritz%") )
.add( Restrictions.or(
Restrictions.eq( "age", new Integer(0) ),
Restrictions.isNull("age")
) )
.list();</pre>
<pre class=programlisting>List cats = sess.createCriteria(Cat.class)
.add( Restrictions.in( "name", new String[] { "Fritz", "Izi", "Pk" } ) )
.add( Restrictions.disjunction()
.add( Restrictions.isNull("age") )
.add( Restrictions.eq("age", new Integer(0) ) )
.add( Restrictions.eq("age", new Integer(1) ) )
.add( Restrictions.eq("age", new Integer(2) ) )
) )
.list();</pre>
<p>Hibernate提供了相当多的内置criterion类型(<tt class=literal>Restrictions</tt> 子类), 但是尤其有用的是可以允许你直接使用SQL。 </p>
<pre class=programlisting>List cats = sess.createCriteria(Cat.class)
.add( Restrictions.sql("lower({alias}.name) like lower(?)", "Fritz%", Hibernate.STRING) )
.list();</pre>
<p><tt class=literal>{alias}</tt>占位符应当被替换为被查询实体的列别名。 </p>
<p><tt class=literal>Property</tt>实例是获得一个条件的另外一种途径。你可以通过调用<tt class=literal>Property.forName()</tt> 创建一个<tt class=literal>Property</tt>。 </p>
<pre class=programlisting>Property age = Property.forName("age");
List cats = sess.createCriteria(Cat.class)
.add( Restrictions.disjunction()
.add( age.isNull() )
.add( age.eq( new Integer(0) ) )
.add( age.eq( new Integer(1) ) )
.add( age.eq( new Integer(2) ) )
) )
.add( Property.forName("name").in( new String[] { "Fritz", "Izi", "Pk" } ) )
.list();</pre>
</div>
<div class=sect1 lang=zh-cn>
<div class=titlepage>
<div>
<div>
<h2 class=title style="CLEAR: both"><a name=querycriteria-ordering></a>16.3.&nbsp;结果集排序</h2>
</div>
</div>
<div></div>
</div>
<p>你可以使用<tt class=literal>org.hibernate.criterion.Order</tt>来为查询结果排序。 </p>
<pre class=programlisting>List cats = sess.createCriteria(Cat.class)
.add( Restrictions.like("name", "F%")
.addOrder( Order.asc("name") )
.addOrder( Order.desc("age") )
.setMaxResults(50)
.list();</pre>
<pre class=programlisting>List cats = sess.createCriteria(Cat.class)
.add( Property.forName("name").like("F%") )
.addOrder( Property.forName("name").asc() )
.addOrder( Property.forName("age").desc() )
.setMaxResults(50)
.list();</pre>
</div>
<div class=sect1 lang=zh-cn>
<div class=titlepage>
<div>
<div>
<h2 class=title style="CLEAR: both"><a name=querycriteria-associations></a>16.4.&nbsp;关联</h2>
</div>
</div>
<div></div>
</div>
<p>你可以使用<tt class=literal>createCriteria()</tt>非常容易的在互相关联的实体间建立 约束。 </p>
<pre class=programlisting>List cats = sess.createCriteria(Cat.class)
.add( Restrictions.like("name", "F%")
.createCriteria("kittens")
.add( Restrictions.like("name", "F%")
.list();</pre>
<p>注意第二个 <tt class=literal>createCriteria()</tt>返回一个新的 <tt class=literal>Criteria</tt>实例，该实例引用<tt class=literal>kittens</tt> 集合中的元素。 </p>
<p>接下来，替换形态在某些情况下也是很有用的。 </p>
<pre class=programlisting>List cats = sess.createCriteria(Cat.class)
.createAlias("kittens", "kt")
.createAlias("mate", "mt")
.add( Restrictions.eqProperty("kt.name", "mt.name") )
.list();</pre>
<p>(<tt class=literal>createAlias()</tt>并不创建一个新的 <tt class=literal>Criteria</tt>实例。) </p>
<p><tt class=literal>Cat</tt>实例所保存的之前两次查询所返回的kittens集合是 <span class=emphasis><em>没有</em></span>被条件预过滤的。如果你希望只获得符合条件的kittens， 你必须使用<tt class=literal>returnMaps()</tt>。 </p>
<pre class=programlisting>List cats = sess.createCriteria(Cat.class)
.createCriteria("kittens", "kt")
.add( Restrictions.eq("name", "F%") )
.returnMaps()
.list();
Iterator iter = cats.iterator();
while ( iter.hasNext() ) {
Map map = (Map) iter.next();
Cat cat = (Cat) map.get(Criteria.ROOT_ALIAS);
Cat kitten = (Cat) map.get("kt");
}</pre>
</div>
<div class=sect1 lang=zh-cn>
<div class=titlepage>
<div>
<div>
<h2 class=title style="CLEAR: both"><a name=querycriteria-dynamicfetching></a>16.5.&nbsp;动态关联抓取</h2>
</div>
</div>
<div></div>
</div>
<p>你可以使用<tt class=literal>setFetchMode()</tt>在运行时定义动态关联抓取的语义。 </p>
<pre class=programlisting>List cats = sess.createCriteria(Cat.class)
.add( Restrictions.like("name", "Fritz%") )
.setFetchMode("mate", FetchMode.EAGER)
.setFetchMode("kittens", FetchMode.EAGER)
.list();</pre>
<p>这个查询可以通过外连接抓取<tt class=literal>mate</tt>和<tt class=literal>kittens</tt>。 查看<a title="20.1.&nbsp;&#10;&#9;&#10;&#9;&#9;&#9;抓取策略(Fetching strategies)&#10;&#9;&#9;" href="http://docs.huihoo.com/framework/hibernate/reference-v3_zh-cn/performance.html#performance-fetching" tppabs="http://www.hibernate.org/hib_docs/v3/reference/zh-cn/html/performance.html#performance-fetching">第&nbsp;20.1&nbsp;节 &#8220; 抓取策略(Fetching strategies) &#8221;</a>可以获得更多信息。 </p>
</div>
<div class=sect1 lang=zh-cn>
<div class=titlepage>
<div>
<div>
<h2 class=title style="CLEAR: both"><a name=querycriteria-examples></a>16.6.&nbsp;查询示例</h2>
</div>
</div>
<div></div>
</div>
<p><tt class=literal>org.hibernate.criterion.Example</tt>类允许你通过一个给定实例 构建一个条件查询。 </p>
<pre class=programlisting>Cat cat = new Cat();
cat.setSex('F');
cat.setColor(Color.BLACK);
List results = session.createCriteria(Cat.class)
.add( Example.create(cat) )
.list();</pre>
<p>版本属性、标识符和关联被忽略。默认情况下值为null的属性将被排除。 </p>
<p>你可以自行调整<tt class=literal>Example</tt>使之更实用。 </p>
<pre class=programlisting>Example example = Example.create(cat)
.excludeZeroes()           //exclude zero valued properties
.excludeProperty("color")  //exclude the property named "color"
.ignoreCase()              //perform case insensitive string comparisons
.enableLike();             //use like for string comparisons
List results = session.createCriteria(Cat.class)
.add(example)
.list();</pre>
<p>你甚至可以使用examples在关联对象上放置条件。 </p>
<pre class=programlisting>List results = session.createCriteria(Cat.class)
.add( Example.create(cat) )
.createCriteria("mate")
.add( Example.create( cat.getMate() ) )
.list();</pre>
</div>
<div class=sect1 lang=zh-cn>
<div class=titlepage>
<div>
<div>
<h2 class=title style="CLEAR: both"><a name=querycriteria-projection></a>16.7.&nbsp;投影(Projections)、聚合（aggregation）和分组（grouping）</h2>
</div>
</div>
<div></div>
</div>
<p><tt class=literal>org.hibernate.criterion.Projections</tt>是 <tt class=literal>Projection</tt> 的实例工厂。我们通过调用 <tt class=literal>setProjection()</tt>应用投影到一个查询。 </p>
<pre class=programlisting>List results = session.createCriteria(Cat.class)
.setProjection( Projections.rowCount() )
.add( Restrictions.eq("color", Color.BLACK) )
.list();</pre>
<pre class=programlisting>List results = session.createCriteria(Cat.class)
.setProjection( Projections.projectionList()
.add( Projections.rowCount() )
.add( Projections.avg("weight") )
.add( Projections.max("weight") )
.add( Projections.groupProperty("color") )
)
.list();</pre>
<p>在一个条件查询中没有必要显式的使用 "group by" 。某些投影类型就是被定义为<span class=emphasis><em> 分组投影</em></span>，他们也出现在SQL的<tt class=literal>group by</tt>子句中。 </p>
<p>你可以选择把一个别名指派给一个投影，这样可以使投影值被约束或排序所引用。下面是两种不同的实现方式： </p>
<pre class=programlisting>List results = session.createCriteria(Cat.class)
.setProjection( Projections.alias( Projections.groupProperty("color"), "colr" ) )
.addOrder( Order.asc("colr") )
.list();</pre>
<pre class=programlisting>List results = session.createCriteria(Cat.class)
.setProjection( Projections.groupProperty("color").as("colr") )
.addOrder( Order.asc("colr") )
.list();</pre>
<p><tt class=literal>alias()</tt>和<tt class=literal>as()</tt>方法简便的将一个投影实例包装到另外一个 别名的<tt class=literal>Projection</tt>实例中。简而言之，当你添加一个投影到一个投影列表中时 你可以为它指定一个别名： </p>
<pre class=programlisting>List results = session.createCriteria(Cat.class)
.setProjection( Projections.projectionList()
.add( Projections.rowCount(), "catCountByColor" )
.add( Projections.avg("weight"), "avgWeight" )
.add( Projections.max("weight"), "maxWeight" )
.add( Projections.groupProperty("color"), "color" )
)
.addOrder( Order.desc("catCountByColor") )
.addOrder( Order.desc("avgWeight") )
.list();</pre>
<pre class=programlisting>List results = session.createCriteria(Domestic.class, "cat")
.createAlias("kittens", "kit")
.setProjection( Projections.projectionList()
.add( Projections.property("cat.name"), "catName" )
.add( Projections.property("kit.name"), "kitName" )
)
.addOrder( Order.asc("catName") )
.addOrder( Order.asc("kitName") )
.list();</pre>
<p>你也可以使用<tt class=literal>Property.forName()</tt>来表示投影： </p>
<pre class=programlisting>List results = session.createCriteria(Cat.class)
.setProjection( Property.forName("name") )
.add( Property.forName("color").eq(Color.BLACK) )
.list();</pre>
<pre class=programlisting>List results = session.createCriteria(Cat.class)
.setProjection( Projections.projectionList()
.add( Projections.rowCount().as("catCountByColor") )
.add( Property.forName("weight").avg().as("avgWeight") )
.add( Property.forName("weight").max().as("maxWeight") )
.add( Property.forName("color").group().as("color" )
)
.addOrder( Order.desc("catCountByColor") )
.addOrder( Order.desc("avgWeight") )
.list();</pre>
</div>
<div class=sect1 lang=zh-cn>
<div class=titlepage>
<div>
<div>
<h2 class=title style="CLEAR: both"><a name=querycriteria-detachedqueries></a>16.8.&nbsp;离线(detached)查询和子查询</h2>
</div>
</div>
<div></div>
</div>
<p><tt class=literal>DetachedCriteria</tt>类使你在一个session范围之外创建一个查询，并且可以使用任意的 <tt class=literal>Session</tt>来执行它。 </p>
<pre class=programlisting>DetachedCriteria query = DetachedCriteria.forClass(Cat.class)
.add( Property.forName("sex").eq('F') );
Session session = ....;
Transaction txn = session.beginTransaction();
List results = query.getExecutableCriteria(session).setMaxResults(100).list();
txn.commit();
session.close();</pre>
<p><tt class=literal>DetachedCriteria</tt>也可以用以表示子查询。条件实例包含子查询可以通过 <tt class=literal>Subqueries</tt>或者<tt class=literal>Property</tt>获得。 </p>
<pre class=programlisting>DetachedCriteria avgWeight = DetachedCriteria.forClass(Cat.class)
.setProjection( Property.forName("weight").avg() );
session.createCriteria(Cat.class)
.add( Property.forName("weight).gt(avgWeight) )
.list();</pre>
<pre class=programlisting>DetachedCriteria weights = DetachedCriteria.forClass(Cat.class)
.setProjection( Property.forName("weight") );
session.createCriteria(Cat.class)
.add( Subqueries.geAll("weight", weights) )
.list();</pre>
<p>甚至相互关联的子查询也是有可能的： </p>
<pre class=programlisting>DetachedCriteria avgWeightForSex = DetachedCriteria.forClass(Cat.class, "cat2")
.setProjection( Property.forName("weight").avg() )
.add( Property.forName("cat2.sex").eqProperty("cat.sex") );
session.createCriteria(Cat.class, "cat")
.add( Property.forName("weight).gt(avgWeightForSex) )
.list();</pre>
</div>
<div class=navfooter>
<hr>
</div>
<img src ="http://www.blogjava.net/WshmAndLily/aggbug/135998.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/WshmAndLily/" target="_blank">semovy</a> 2007-08-11 11:52 <a href="http://www.blogjava.net/WshmAndLily/articles/135998.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关联关系映射</title><link>http://www.blogjava.net/WshmAndLily/articles/135807.html</link><dc:creator>semovy</dc:creator><author>semovy</author><pubDate>Fri, 10 Aug 2007 06:01:00 GMT</pubDate><guid>http://www.blogjava.net/WshmAndLily/articles/135807.html</guid><wfw:comment>http://www.blogjava.net/WshmAndLily/comments/135807.html</wfw:comment><comments>http://www.blogjava.net/WshmAndLily/articles/135807.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/WshmAndLily/comments/commentRss/135807.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/WshmAndLily/services/trackbacks/135807.html</trackback:ping><description><![CDATA[<div class=titlepage>
<div>
<div>
<h2 class=title><a name=associations></a>第&nbsp;8&nbsp;章&nbsp;关联关系映射</h2>
</div>
</div>
<div></div>
</div>
<div class=sect1 lang=zh-cn>
<div class=titlepage>
<div>
<div>
<h2 class=title style="CLEAR: both"><a name=assoc-intro></a>8.1.&nbsp;介绍</h2>
</div>
</div>
<div></div>
</div>
<p>关联关系映射通常情况是最难配置正确的。在这个部分中，我们从单向关系映射开始，然后考虑双向关系映射，由浅至深讲述一遍典型的案例。在所有的例子中，我们都使用 <tt class=literal>Person</tt>和<tt class=literal>Address</tt>。 </p>
<p>我们根据映射关系是否涉及连接表以及多样性来划分关联类型。 </p>
<p>在传统的数据建模中，允许为Null值的外键被认为是一种不好的实践，因此我们所有的例子中都使用不允许为Null的外键。这并不是Hibernate的要求，即使你删除掉不允许为Null的约束，Hibernate映射一样可以工作的很好。 </p>
</div>
<div class=sect1 lang=zh-cn>
<div class=titlepage>
<div>
<div>
<h2 class=title style="CLEAR: both"><a name=assoc-unidirectional></a>8.2.&nbsp;单向关联（Unidirectional associations）</h2>
</div>
</div>
<div></div>
</div>
<div class=sect2 lang=zh-cn>
<div class=titlepage>
<div>
<div>
<h3 class=title><a name=assoc-unidirectional-m21></a>8.2.1.&nbsp;多对一(many to one)</h3>
</div>
</div>
<div></div>
</div>
<p><span class=emphasis><em>单向many-to-one关联</em></span>是最常见的单向关联关系。 </p>
<pre class=programlisting>&lt;class name="Person"&gt;
&lt;id name="id" column="personId"&gt;
&lt;generator class="native"/&gt;
&lt;/id&gt;
&lt;many-to-one name="address"
column="addressId"
not-null="true"/&gt;
&lt;/class&gt;
&lt;class name="Address"&gt;
&lt;id name="id" column="addressId"&gt;
&lt;generator class="native"/&gt;
&lt;/id&gt;
&lt;/class&gt;</pre>
<pre class=programlisting>create table Person ( personId bigint not null primary key, addressId bigint not null )
create table Address ( addressId bigint not null primary key )
</pre>
</div>
<div class=sect2 lang=zh-cn>
<div class=titlepage>
<div>
<div>
<h3 class=title><a name=assoc-unidirectional-121></a>8.2.2.&nbsp;一对一（one to one）</h3>
</div>
</div>
<div></div>
</div>
<p><span class=emphasis><em>基于外键关联的单向一对一关联</em></span>和<span class=emphasis><em>单向多对一关联</em></span>几乎是一样的。唯一的不同就是单向一对一关联中的外键字段具有唯一性约束。 </p>
<pre class=programlisting>&lt;class name="Person"&gt;
&lt;id name="id" column="personId"&gt;
&lt;generator class="native"/&gt;
&lt;/id&gt;
&lt;many-to-one name="address"
column="addressId"
unique="true"
not-null="true"/&gt;
&lt;/class&gt;
&lt;class name="Address"&gt;
&lt;id name="id" column="addressId"&gt;
&lt;generator class="native"/&gt;
&lt;/id&gt;
&lt;/class&gt;</pre>
<pre class=programlisting>create table Person ( personId bigint not null primary key, addressId bigint not null unique )
create table Address ( addressId bigint not null primary key )
</pre>
<p><span class=emphasis><em>基于主键关联的单向一对一关联</em></span>通常使用一个特定的id生成器。（请注意，在这个例子中我们掉换了关联的方向。） </p>
<pre class=programlisting>&lt;class name="Person"&gt;
&lt;id name="id" column="personId"&gt;
&lt;generator class="native"/&gt;
&lt;/id&gt;
&lt;/class&gt;
&lt;class name="Address"&gt;
&lt;id name="id" column="personId"&gt;
&lt;generator class="foreign"&gt;
&lt;param name="property"&gt;person&lt;/param&gt;
&lt;/generator&gt;
&lt;/id&gt;
&lt;one-to-one name="person" constrained="true"/&gt;
&lt;/class&gt;</pre>
<pre class=programlisting>create table Person ( personId bigint not null primary key )
create table Address ( personId bigint not null primary key )
</pre>
</div>
<div class=sect2 lang=zh-cn>
<div class=titlepage>
<div>
<div>
<h3 class=title><a name=assoc-unidirectional-12m></a>8.2.3.&nbsp;一对多（one to many）</h3>
</div>
</div>
<div></div>
</div>
<p><span class=emphasis><em>基于外键关联的单向一对多关联</em></span>是一种很少见的情况，并不推荐使用。 </p>
<pre class=programlisting>&lt;class name="Person"&gt;
&lt;id name="id" column="personId"&gt;
&lt;generator class="native"/&gt;
&lt;/id&gt;
&lt;set name="addresses"&gt;
&lt;key column="personId"
not-null="true"/&gt;
&lt;one-to-many class="Address"/&gt;
&lt;/set&gt;
&lt;/class&gt;
&lt;class name="Address"&gt;
&lt;id name="id" column="addressId"&gt;
&lt;generator class="native"/&gt;
&lt;/id&gt;
&lt;/class&gt;</pre>
<pre class=programlisting>create table Person ( personId bigint not null primary key )
create table Address ( addressId bigint not null primary key, personId bigint not null )
</pre>
<p>我们认为对于这种关联关系最好使用连接表。 </p>
</div>
</div>
<div class=sect1 lang=zh-cn>
<div class=titlepage>
<div>
<div>
<h2 class=title style="CLEAR: both"><a name=assoc-unidirectional-join></a>8.3.&nbsp;使用连接表的单向关联（Unidirectional associations with join tables）</h2>
</div>
</div>
<div></div>
</div>
<div class=sect2 lang=zh-cn>
<div class=titlepage>
<div>
<div>
<h3 class=title><a name=assoc-unidirectional-join-12m></a>8.3.1.&nbsp;一对多(one to many)</h3>
</div>
</div>
<div></div>
</div>
<p><span class=emphasis><em>基于连接表的单向一对多关联</em></span> 应该优先被采用。请注意，通过指定<tt class=literal>unique="true"</tt>，我们可以把多样性从多对多改变为一对多。 </p>
<pre class=programlisting>&lt;class name="Person"&gt;
&lt;id name="id" column="personId"&gt;
&lt;generator class="native"/&gt;
&lt;/id&gt;
&lt;set name="addresses" table="PersonAddress"&gt;
&lt;key column="personId"/&gt;
&lt;many-to-many column="addressId"
unique="true"
class="Address"/&gt;
&lt;/set&gt;
&lt;/class&gt;
&lt;class name="Address"&gt;
&lt;id name="id" column="addressId"&gt;
&lt;generator class="native"/&gt;
&lt;/id&gt;
&lt;/class&gt;</pre>
<pre class=programlisting>create table Person ( personId bigint not null primary key )
create table PersonAddress ( personId not null, addressId bigint not null primary key )
create table Address ( addressId bigint not null primary key )
</pre>
</div>
<div class=sect2 lang=zh-cn>
<div class=titlepage>
<div>
<div>
<h3 class=title><a name=assoc-unidirectional-join-m21></a>8.3.2.&nbsp;多对一（many to one）</h3>
</div>
</div>
<div></div>
</div>
<p><span class=emphasis><em>基于连接表的单向多对一关联</em></span>在关联关系可选的情况下应用也很普遍。 </p>
<pre class=programlisting>&lt;class name="Person"&gt;
&lt;id name="id" column="personId"&gt;
&lt;generator class="native"/&gt;
&lt;/id&gt;
&lt;join table="PersonAddress"
optional="true"&gt;
&lt;key column="personId" unique="true"/&gt;
&lt;many-to-one name="address"
column="addressId"
not-null="true"/&gt;
&lt;/join&gt;
&lt;/class&gt;
&lt;class name="Address"&gt;
&lt;id name="id" column="addressId"&gt;
&lt;generator class="native"/&gt;
&lt;/id&gt;
&lt;/class&gt;</pre>
<pre class=programlisting>create table Person ( personId bigint not null primary key )
create table PersonAddress ( personId bigint not null primary key, addressId bigint not null )
create table Address ( addressId bigint not null primary key )
</pre>
</div>
<div class=sect2 lang=zh-cn>
<div class=titlepage>
<div>
<div>
<h3 class=title><a name=assoc-unidirectional-join-121></a>8.3.3.&nbsp;一对一（one to one）</h3>
</div>
</div>
<div></div>
</div>
<p><span class=emphasis><em>基于连接表的单向一对一关联</em></span>非常少见，但也是可行的。 </p>
<pre class=programlisting>&lt;class name="Person"&gt;
&lt;id name="id" column="personId"&gt;
&lt;generator class="native"/&gt;
&lt;/id&gt;
&lt;join table="PersonAddress"
optional="true"&gt;
&lt;key column="personId"
unique="true"/&gt;
&lt;many-to-one name="address"
column="addressId"
not-null="true"
unique="true"/&gt;
&lt;/join&gt;
&lt;/class&gt;
&lt;class name="Address"&gt;
&lt;id name="id" column="addressId"&gt;
&lt;generator class="native"/&gt;
&lt;/id&gt;
&lt;/class&gt;</pre>
<pre class=programlisting>create table Person ( personId bigint not null primary key )
create table PersonAddress ( personId bigint not null primary key, addressId bigint not null unique )
create table Address ( addressId bigint not null primary key )
</pre>
</div>
<div class=sect2 lang=zh-cn>
<div class=titlepage>
<div>
<div>
<h3 class=title><a name=assoc-unidirectional-join-m2m></a>8.3.4.&nbsp;多对多（many to many）</h3>
</div>
</div>
<div></div>
</div>
<p>最后，还有 <span class=emphasis><em>单向多对多关联</em></span>. </p>
<pre class=programlisting>&lt;class name="Person"&gt;
&lt;id name="id" column="personId"&gt;
&lt;generator class="native"/&gt;
&lt;/id&gt;
&lt;set name="addresses" table="PersonAddress"&gt;
&lt;key column="personId"/&gt;
&lt;many-to-many column="addressId"
class="Address"/&gt;
&lt;/set&gt;
&lt;/class&gt;
&lt;class name="Address"&gt;
&lt;id name="id" column="addressId"&gt;
&lt;generator class="native"/&gt;
&lt;/id&gt;
&lt;/class&gt;</pre>
<pre class=programlisting>create table Person ( personId bigint not null primary key )
create table PersonAddress ( personId bigint not null, addressId bigint not null, primary key (personId, addressId) )
create table Address ( addressId bigint not null primary key )
</pre>
</div>
</div>
<div class=sect1 lang=zh-cn>
<div class=titlepage>
<div>
<div>
<h2 class=title style="CLEAR: both"><a name=assoc-bidirectional></a>8.4.&nbsp;双向关联（Bidirectional associations）</h2>
</div>
</div>
<div></div>
</div>
<div class=sect2 lang=zh-cn>
<div class=titlepage>
<div>
<div>
<h3 class=title><a name=assoc-bidirectional-m21></a>8.4.1.&nbsp;一对多（one to many) / 多对一（many to one）</h3>
</div>
</div>
<div></div>
</div>
<p><span class=emphasis><em>双向多对一关联</em></span> 是最常见的关联关系。（这也是标准的父/子关联关系。） </p>
<pre class=programlisting>&lt;class name="Person"&gt;
&lt;id name="id" column="personId"&gt;
&lt;generator class="native"/&gt;
&lt;/id&gt;
&lt;many-to-one name="address"
column="addressId"
not-null="true"/&gt;
&lt;/class&gt;
&lt;class name="Address"&gt;
&lt;id name="id" column="addressId"&gt;
&lt;generator class="native"/&gt;
&lt;/id&gt;
&lt;set name="people" inverse="true"&gt;
&lt;key column="addressId"/&gt;
&lt;one-to-many class="Person"/&gt;
&lt;/set&gt;
&lt;/class&gt;</pre>
<pre class=programlisting>create table Person ( personId bigint not null primary key, addressId bigint not null )
create table Address ( addressId bigint not null primary key )
</pre>
</div>
<div class=sect2 lang=zh-cn>
<div class=titlepage>
<div>
<div>
<h3 class=title><a name=assoc-bidirectional-121></a>8.4.2.&nbsp;一对一（one to one）</h3>
</div>
</div>
<div></div>
</div>
<p><span class=emphasis><em>基于外键关联的双向一对一关联</em></span>也很常见。 </p>
<pre class=programlisting>&lt;class name="Person"&gt;
&lt;id name="id" column="personId"&gt;
&lt;generator class="native"/&gt;
&lt;/id&gt;
&lt;many-to-one name="address"
column="addressId"
unique="true"
not-null="true"/&gt;
&lt;/class&gt;
&lt;class name="Address"&gt;
&lt;id name="id" column="addressId"&gt;
&lt;generator class="native"/&gt;
&lt;/id&gt;
&lt;one-to-one name="person"
property-ref="address"/&gt;
&lt;/class&gt;</pre>
<pre class=programlisting>create table Person ( personId bigint not null primary key, addressId bigint not null unique )
create table Address ( addressId bigint not null primary key )
</pre>
<p><span class=emphasis><em>基于主键关联的一对一关联</em></span>需要使用特定的id生成器。 </p>
<pre class=programlisting>&lt;class name="Person"&gt;
&lt;id name="id" column="personId"&gt;
&lt;generator class="native"/&gt;
&lt;/id&gt;
&lt;one-to-one name="address"/&gt;
&lt;/class&gt;
&lt;class name="Address"&gt;
&lt;id name="id" column="personId"&gt;
&lt;generator class="foreign"&gt;
&lt;param name="property"&gt;person&lt;/param&gt;
&lt;/generator&gt;
&lt;/id&gt;
&lt;one-to-one name="person"
constrained="true"/&gt;
&lt;/class&gt;</pre>
<pre class=programlisting>create table Person ( personId bigint not null primary key )
create table Address ( personId bigint not null primary key )
</pre>
</div>
</div>
<div class=sect1 lang=zh-cn>
<div class=titlepage>
<div>
<div>
<h2 class=title style="CLEAR: both"><a name=assoc-bidirectional-join></a>8.5.&nbsp;使用连接表的双向关联（Bidirectional associations with join tables）</h2>
</div>
</div>
<div></div>
</div>
<div class=sect2 lang=zh-cn>
<div class=titlepage>
<div>
<div>
<h3 class=title><a name=assoc-bidirectional-join-12m></a>8.5.1.&nbsp;一对多（one to many） /多对一（ many to one）</h3>
</div>
</div>
<div></div>
</div>
<p><span class=emphasis><em>基于连接表的双向一对多关联</em></span>。注意<tt class=literal>inverse="true"</tt>可以出现在关联的任意一端，即collection端或者join端。 </p>
<pre class=programlisting>&lt;class name="Person"&gt;
&lt;id name="id" column="personId"&gt;
&lt;generator class="native"/&gt;
&lt;/id&gt;
&lt;set name="addresses"
table="PersonAddress"&gt;
&lt;key column="personId"/&gt;
&lt;many-to-many column="addressId"
unique="true"
class="Address"/&gt;
&lt;/set&gt;
&lt;/class&gt;
&lt;class name="Address"&gt;
&lt;id name="id" column="addressId"&gt;
&lt;generator class="native"/&gt;
&lt;/id&gt;
&lt;join table="PersonAddress"
inverse="true"
optional="true"&gt;
&lt;key column="addressId"/&gt;
&lt;many-to-one name="person"
column="personId"
not-null="true"/&gt;
&lt;/join&gt;
&lt;/class&gt;</pre>
<pre class=programlisting>create table Person ( personId bigint not null primary key )
create table PersonAddress ( personId bigint not null, addressId bigint not null primary key )
create table Address ( addressId bigint not null primary key )
</pre>
</div>
<div class=sect2 lang=zh-cn>
<div class=titlepage>
<div>
<div>
<h3 class=title><a name=assoc-bidirectional-join-121></a>8.5.2.&nbsp;一对一（one to one）</h3>
</div>
</div>
<div></div>
</div>
<p><span class=emphasis><em>基于连接表的双向一对一关联</em></span>极为罕见，但也是可行的。 </p>
<pre class=programlisting>&lt;class name="Person"&gt;
&lt;id name="id" column="personId"&gt;
&lt;generator class="native"/&gt;
&lt;/id&gt;
&lt;join table="PersonAddress"
optional="true"&gt;
&lt;key column="personId"
unique="true"/&gt;
&lt;many-to-one name="address"
column="addressId"
not-null="true"
unique="true"/&gt;
&lt;/join&gt;
&lt;/class&gt;
&lt;class name="Address"&gt;
&lt;id name="id" column="addressId"&gt;
&lt;generator class="native"/&gt;
&lt;/id&gt;
&lt;join table="PersonAddress"
optional="true"
inverse="true"&gt;
&lt;key column="addressId"
unique="true"/&gt;
&lt;many-to-one name="address"
column="personId"
not-null="true"
unique="true"/&gt;
&lt;/join&gt;
&lt;/class&gt;</pre>
<pre class=programlisting>create table Person ( personId bigint not null primary key )
create table PersonAddress ( personId bigint not null primary key, addressId bigint not null unique )
create table Address ( addressId bigint not null primary key )
</pre>
</div>
<div class=sect2 lang=zh-cn>
<div class=titlepage>
<div>
<div>
<h3 class=title><a name=assoc-bidirectional-join-m2m></a>8.5.3.&nbsp;多对多（many to many）</h3>
</div>
</div>
<div></div>
</div>
<p>最后，还有 <span class=emphasis><em>双向多对多关联</em></span>. </p>
<pre class=programlisting>&lt;class name="Person"&gt;
&lt;id name="id" column="personId"&gt;
&lt;generator class="native"/&gt;
&lt;/id&gt;
&lt;set name="addresses"&gt;
&lt;key column="personId"/&gt;
&lt;many-to-many column="addressId"
class="Address"/&gt;
&lt;/set&gt;
&lt;/class&gt;
&lt;class name="Address"&gt;
&lt;id name="id" column="addressId"&gt;
&lt;generator class="native"/&gt;
&lt;/id&gt;
&lt;set name="people" inverse="true"&gt;
&lt;key column="addressId"/&gt;
&lt;many-to-many column="personId"
class="Person"/&gt;
&lt;/set&gt;
&lt;/class&gt;</pre>
<pre class=programlisting>create table Person ( personId bigint not null primary key )
create table PersonAddress ( personId bigint not null, addressId bigint not null, primary key (personId, addressId) )
create table Address ( addressId bigint not null primary key )
</pre>
</div>
<div class=chapter lang=zh-cn>
<div class=titlepage>
<div>
<div>
<h2 class=title><a name=components></a>第&nbsp;9&nbsp;章&nbsp;组件（Component）映射</h2>
</div>
</div>
<div></div>
</div>
<p><span class=emphasis><em>Component</em></span>这个概念在Hibernate中几处不同的地方为了不同的目的被重复使用. </p>
<div class=sect1 lang=zh-cn>
<div class=titlepage>
<div>
<div>
<h2 class=title style="CLEAR: both"><a name=components-dependentobjects></a>9.1.&nbsp;依赖对象（Dependent objects）</h2>
</div>
</div>
<div></div>
</div>
<p>Component是一个被包含的对象,它作为值类型被持久化，而非一个被引用的实体。&#8220;component(组件)&#8221;这一术语指的是面向对象的合成概念（而并不是系统构架层次上的组件的概念）举个例子, 你可以对人（Person)如以下这样来建模： </p>
<pre class=programlisting>public class Person {
private java.util.Date birthday;
private Name name;
private String key;
public String getKey() {
return key;
}
private void setKey(String key) {
this.key=key;
}
public java.util.Date getBirthday() {
return birthday;
}
public void setBirthday(java.util.Date birthday) {
this.birthday = birthday;
}
public Name getName() {
return name;
}
public void setName(Name name) {
this.name = name;
}
......
......
}</pre>
<pre class=programlisting>public class Name {
char initial;
String first;
String last;
public String getFirst() {
return first;
}
void setFirst(String first) {
this.first = first;
}
public String getLast() {
return last;
}
void setLast(String last) {
this.last = last;
}
public char getInitial() {
return initial;
}
void setInitial(char initial) {
this.initial = initial;
}
}</pre>
<p>现在,<tt class=literal>姓名(Name)</tt>是作为<tt class=literal>人(Person)</tt>的一个组成部分。需要注意的是:需要对<tt class=literal>姓名</tt> 的持久化属性定义getter和setter方法,但是不需要实现任何的接口或申明标识符字段。 </p>
<p>以下是这个例子的Hibernate映射文件: </p>
<pre class=programlisting>&lt;class name="eg.Person" table="person"&gt;
&lt;id name="Key" column="pid" type="string"&gt;
&lt;generator class="uuid.hex"/&gt;
&lt;/id&gt;
&lt;property name="birthday" type="date"/&gt;
&lt;component name="Name" class="eg.Name"&gt; &lt;!-- class attribute optional --&gt;
&lt;property name="initial"/&gt;
&lt;property name="first"/&gt;
&lt;property name="last"/&gt;
&lt;/component&gt;
&lt;/class&gt;</pre>
<p>人员(Person)表中将包括<tt class=literal>pid</tt>, <tt class=literal>birthday</tt>, <tt class=literal>initial</tt>, <tt class=literal>first</tt>和 <tt class=literal>last</tt>等字段。 </p>
<p>就像所有的值类型一样, Component不支持共享引用。 换句话说，两个人可能重名，但是两个person对象应该包含两个独立的name对象，只不过是具有&#8220;同样&#8221;的值。 Component的值为空从语义学上来讲是<span class=emphasis><em>专有的(ad hoc)</em></span>。 每当 重新加载一个包含组件的对象,如果component的所有字段为空，那么将Hibernate将假定整个component为 空。对于绝大多数目的,这样假定是没有问题的。 </p>
<p>Component的属性可以是Hibernate类型（包括Collections, many-to-one 关联， 以及其它Component 等等）。嵌套Component不应该作为特殊的应用被考虑(Nested components should not be considered an exotic usage)。 Hibernate趋向于支持设计细致(fine-grained)的对象模型。 </p>
<p><tt class=literal>&lt;component&gt;</tt> 元素还允许有 <tt class=literal>&lt;parent&gt;</tt>子元素 ，用来表明component类中的一个属性返回包含它的实体的引用。 </p>
<pre class=programlisting>&lt;class name="eg.Person" table="person"&gt;
&lt;id name="Key" column="pid" type="string"&gt;
&lt;generator class="uuid.hex"/&gt;
&lt;/id&gt;
&lt;property name="birthday" type="date"/&gt;
&lt;component name="Name" class="eg.Name" unique="true"&gt;&gt;
&lt;parent name="namedPerson"/&gt; &lt;!-- reference back to the Person --&gt;
&lt;property name="initial"/&gt;
&lt;property name="first"/&gt;
&lt;property name="last"/&gt;
&lt;/component&gt;
&lt;/class&gt;</pre>
</div>
<div class=sect1 lang=zh-cn>
<div class=titlepage>
<div>
<div>
<h2 class=title style="CLEAR: both"><a name=components-incollections></a>9.2.&nbsp;在集合中出现的依赖对象</h2>
</div>
</div>
<div></div>
</div>
<p>Hibernate支持component的集合(例如: 一个元素是&#8220;姓名&#8221;这种类型的数组)。 你可以使用<tt class=literal>&lt;composite-element&gt;</tt>标签替代<tt class=literal>&lt;element&gt;</tt>标签来定义你的component集合。 </p>
<pre class=programlisting>&lt;set name="someNames" table="some_names" lazy="true"&gt;
&lt;key column="id"/&gt;
&lt;composite-element class="eg.Name"&gt; &lt;!-- class attribute required --&gt;
&lt;property name="initial"/&gt;
&lt;property name="first"/&gt;
&lt;property name="last"/&gt;
&lt;/composite-element&gt;
&lt;/set&gt;</pre>
<p>注意，如果你决定定义一个元素是联合元素的<tt class=literal>Set</tt>，正确地实现<tt class=literal>equals()</tt>和<tt class=literal>hashCode()</tt>是非常重要的。 </p>
<p>组合元素可以包含component但是不能包含集合。如果你的组合元素自身包含component, 必须使用<tt class=literal>&lt;nested-composite-element&gt;</tt>标签。这是一个相当特殊的案例 - 组合元素的集合自身可以包含component。 这个时候你就应该考虑一下使用one-to-many关联是否会更恰当。 尝试对这个组合元素重新建模为一个实体－但是需要注意的是，虽然Java模型和重新建模前 是一样的，关系模型和持久性语义上仍然存在轻微的区别。 </p>
<p>请注意如果你使用<tt class=literal>&lt;set&gt;</tt>标签,一个组合元素的映射不支持可能为空的属性. 当删除对象时, Hibernate必须使用每一个字段的来确定一条记录(在组合元素表中，没有单个的关键字段), 如果有为null的字段，这样做就不可能了。你必须作出一个选择，要么在组合元素中使用不能为空的属性， 要么选择使用<tt class=literal>&lt;list&gt;</tt>, <tt class=literal>&lt;map&gt;</tt>,<tt class=literal>&lt;bag&gt;</tt> 或者 <tt class=literal>&lt;idbag&gt;</tt>而不是 <tt class=literal>&lt;set&gt;</tt>。 </p>
<p>组合元素有个特别的案例，是组合元素可以包含一个<tt class=literal>&lt;many-to-one&gt;</tt> 元素。类似这样的映射允许你映射一个many-to-mang关联表作为组合元素额外的字段。(A mapping like this allows you to map extra columns of a many-to-many association table to the composite element class.) 接下来的的例子是从<tt class=literal>Order</tt>到<tt class=literal>Item</tt>的一个多对多的关联关系,而 <tt class=literal>purchaseDate</tt>, <tt class=literal>price</tt> 和 <tt class=literal>quantity</tt> 是<tt class=literal>Item</tt>的关联属性。 </p>
<pre class=programlisting>&lt;class name="eg.Order" .... &gt;
....
&lt;set name="purchasedItems" table="purchase_items" lazy="true"&gt;
&lt;key column="order_id"&gt;
&lt;composite-element class="eg.Purchase"&gt;
&lt;property name="purchaseDate"/&gt;
&lt;property name="price"/&gt;
&lt;property name="quantity"/&gt;
&lt;many-to-one name="item" class="eg.Item"/&gt; &lt;!-- class attribute is optional --&gt;
&lt;/composite-element&gt;
&lt;/set&gt;
&lt;/class&gt;</pre>
<p>当然，在另一方面，无法存在指向purchase的关联，因此不能实现双向关联查询。记住组建是值类型，并且不允许共享关联。单个<tt class=literal>Purchase</tt> 可以放在包含<tt class=literal>Order</tt>的集合中，但它不能同时被<tt class=literal>Item</tt>所关联。 </p>
<p>即使三重或多重管理都是可能的:</p>
<pre class=programlisting>&lt;class name="eg.Order" .... &gt;
....
&lt;set name="purchasedItems" table="purchase_items" lazy="true"&gt;
&lt;key column="order_id"&gt;
&lt;composite-element class="eg.OrderLine"&gt;
&lt;many-to-one name="purchaseDetails" class="eg.Purchase"/&gt;
&lt;many-to-one name="item" class="eg.Item"/&gt;
&lt;/composite-element&gt;
&lt;/set&gt;
&lt;/class&gt;</pre>
<p>在查询中，组合元素使用的语法是和关联到其他实体的语法一样的。 </p>
</div>
<div class=sect1 lang=zh-cn>
<div class=titlepage>
<div>
<div>
<h2 class=title style="CLEAR: both"><a name=components-asmapindex></a>9.3.&nbsp;组件作为Map的索引（Components as Map indices ）</h2>
</div>
</div>
<div></div>
</div>
<p><tt class=literal>&lt;composite-map-key&gt;</tt>元素允许你映射一个Component类作为<tt class=literal>Map</tt>的key， 但是你必须确定你正确的在这个类中重写了<tt class=literal>hashCode()</tt> 和 <tt class=literal>equals()</tt>方法。 </p>
</div>
<div class=sect1 lang=zh-cn>
<div class=titlepage>
<div>
<div>
<h2 class=title style="CLEAR: both"><a name=components-compositeid></a>9.4.&nbsp;组件作为联合标识符(Components as composite identifiers)</h2>
</div>
</div>
<div></div>
</div>
<p>你可以使用一个component作为一个实体类的标识符。 你的component类必须满足以下要求： </p>
<div class=itemizedlist>
<ul type=disc compact>
    <li>
    <p>它必须实现<tt class=literal>java.io.Serializable</tt>接口 </p>
    <li>
    <p>它必须重新实现<tt class=literal>equals()</tt>和<tt class=literal>hashCode()</tt>方法, 始终和组合关键字在数据库中的概念保持一致 </p>
    </li>
</ul>
</div>
<p><span class=emphasis><em>注意：在Hibernate3中，第二种要求并非是Hibernate强制必须的。但最好这样做。</em></span> </p>
<p>你不能使用一个<tt class=literal>IdentifierGenerator</tt>产生组合关键字。作为替代应用程序必须分配它自己的标识符。 </p>
<p>使用<tt class=literal>&lt;composite-id&gt;</tt> 标签(并且内嵌<tt class=literal>&lt;key-property&gt;</tt>元素)代替通常的<tt class=literal>&lt;id&gt;</tt>标签。 比如,<tt class=literal>OrderLine</tt>类具有一个依赖<tt class=literal>Order</tt>的(联合)主键的主键。 </p>
<pre class=programlisting>&lt;class name="OrderLine"&gt;
&lt;composite-id name="id" class="OrderLineId"&gt;
&lt;key-property name="lineId"/&gt;
&lt;key-property name="orderId"/&gt;
&lt;key-property name="customerId"/&gt;
&lt;/composite-id&gt;
&lt;property name="name"/&gt;
&lt;many-to-one name="order" class="Order"
insert="false" update="false"&gt;
&lt;column name="orderId"/&gt;
&lt;column name="customerId"/&gt;
&lt;/many-to-one&gt;
....
&lt;/class&gt;</pre>
<p>现在，任何关联到<tt class=literal>OrderLine</tt> 的外键都是复合的。在你的映射文件中，必须为其他类也这样声明。指向<tt class=literal>OrderLine</tt>的关联可能被这样映射： </p>
<pre class=programlisting>&lt;many-to-one name="orderLine" class="OrderLine"&gt;
&lt;!-- the "class" attribute is optional, as usual --&gt;
&lt;column name="lineId"/&gt;
&lt;column name="orderId"/&gt;
&lt;column name="customerId"/&gt;
&lt;/many-to-one&gt;</pre>
<p>（注意在各个地方<tt class=literal>&lt;column&gt;</tt>标签都是<tt class=literal>column</tt>属性的替代写法。） </p>
<p>指向<tt class=literal>OrderLine</tt>的<tt class=literal>多对多</tt>关联也使用联合外键: </p>
<pre class=programlisting>&lt;set name="undeliveredOrderLines"&gt;
&lt;key column name="warehouseId"/&gt;
&lt;many-to-many class="OrderLine"&gt;
&lt;column name="lineId"/&gt;
&lt;column name="orderId"/&gt;
&lt;column name="customerId"/&gt;
&lt;/many-to-many&gt;
&lt;/set&gt;</pre>
<p>在<tt class=literal>Order</tt>中, <tt class=literal>OrderLine</tt>的集合则是这样: </p>
<pre class=programlisting>&lt;set name="orderLines" inverse="true"&gt;
&lt;key&gt;
&lt;column name="orderId"/&gt;
&lt;column name="customerId"/&gt;
&lt;/key&gt;
&lt;one-to-many class="OrderLine"/&gt;
&lt;/set&gt;</pre>
<p>(与通常一样,<tt class=literal>&lt;one-to-many&gt;</tt>元素不声明任何列.) </p>
<p>假若<tt class=literal>OrderLine</tt>本身拥有一个集合,它也具有组合外键。 </p>
<pre class=programlisting>&lt;class name="OrderLine"&gt;
....
....
&lt;list name="deliveryAttempts"&gt;
&lt;key&gt;   &lt;!-- a collection inherits the composite key type --&gt;
&lt;column name="lineId"/&gt;
&lt;column name="orderId"/&gt;
&lt;column name="customerId"/&gt;
&lt;/key&gt;
&lt;list-index column="attemptId" base="1"/&gt;
&lt;composite-element class="DeliveryAttempt"&gt;
...
&lt;/composite-element&gt;
&lt;/set&gt;
&lt;/class&gt;</pre>
</div>
<div class=sect1 lang=zh-cn>
<div class=titlepage>
<div>
<div>
<h2 class=title style="CLEAR: both"><a name=components-dynamic></a>9.5.&nbsp;动态组件 （Dynamic components）</h2>
</div>
</div>
<div></div>
</div>
<p>你甚至可以映射<tt class=literal>Map</tt>类型的属性： </p>
<pre class=programlisting>&lt;dynamic-component name="userAttributes"&gt;
&lt;property name="foo" column="FOO"/&gt;
&lt;property name="bar" column="BAR"/&gt;
&lt;many-to-one name="baz" class="Baz" column="BAZ_ID"/&gt;
&lt;/dynamic-component&gt;</pre>
<p>从<tt class=literal>&lt;dynamic-component&gt;</tt>映射的语义上来讲，它和<tt class=literal>&lt;component&gt;</tt>是相同的。 这种映射类型的优点在于通过修改映射文件，就可以具有在部署时检测真实属性的能力.利用一个DOM解析器，是有可能在运行时刻操作映射文件的。 更好的是，你可以通过<tt class=literal>Configuration</tt>对象来访问（或者修改）Hibernate的运行时元模型。 </p>
</div>
</div>
<div class=chapter lang=zh-cn>
<div class=titlepage>
<div>
<div>
<h2 class=title><a name=inheritance></a>第&nbsp;10&nbsp;章&nbsp;继承映射(Inheritance Mappings)</h2>
</div>
</div>
<div></div>
</div>
<div class=sect1 lang=zh-cn>
<div class=titlepage>
<div>
<div>
<h2 class=title style="CLEAR: both"><a name=inheritance-strategies></a>10.1.&nbsp; 三种策略</h2>
</div>
</div>
<div></div>
</div>
<p>Hibernate支持三种基本的继承映射策略： </p>
<div class=itemizedlist>
<ul type=disc>
    <li>
    <p>每个类分层结构一张表(table per class hierarchy) </p>
    <li>
    <p>每个子类一张表(table per subclass) </p>
    <li>
    <p>每个具体类一张表(table per concrete class) </p>
    </li>
</ul>
</div>
<p>此外，Hibernate还支持第四种稍有不同的多态映射策略： </p>
<div class=itemizedlist>
<ul type=disc>
    <li>
    <p>隐式多态(implicit polymorphism) </p>
    </li>
</ul>
</div>
<p>对于同一个继承层次内的不同分支，可以采用不同的映射策略，然后用隐式多 态来完成跨越整个层次的多态。但是在同一个<tt class=literal>&lt;class&gt;</tt>根元素 下，Hibernate不支持混合了元素<tt class=literal>&lt;subclass&gt;</tt>、 <tt class=literal>&lt;joined-subclass&gt;</tt>和<tt class=literal>&lt;union-subclass&gt;</tt> 的映射。在同一个<tt class=literal>&lt;class&gt;</tt>元素下，可以混合使用 &#8220;每个类分层结构一张表&#8221;（table per hierarchy） 和&#8220;每个子类一张表&#8221;（table per subclass） 这两种映射策略，这是通过结合元素<tt class=literal>&lt;subclass&gt;</tt>和 <tt class=literal>&lt;join&gt;</tt>来实现的（见后）。 </p>
<div class=sect2 lang=zh-cn>
<div class=titlepage>
<div>
<div>
<h3 class=title><a name=inheritance-tableperclass></a>10.1.1.&nbsp;每个类分层结构一张表(Table per class hierarchy)</h3>
</div>
</div>
<div></div>
</div>
<p>假设我们有接口<tt class=literal>Payment</tt>和它的几个实现类： <tt class=literal>CreditCardPayment</tt>, <tt class=literal>CashPayment</tt>, 和<tt class=literal>ChequePayment</tt>。则&#8220;每个类分层结构一张表&#8221;(Table per class hierarchy)的映射代码如下所示： </p>
<pre class=programlisting>&lt;class name="Payment" table="PAYMENT"&gt;
&lt;id name="id" type="long" column="PAYMENT_ID"&gt;
&lt;generator class="native"/&gt;
&lt;/id&gt;
&lt;discriminator column="PAYMENT_TYPE" type="string"/&gt;
&lt;property name="amount" column="AMOUNT"/&gt;
...
&lt;subclass name="CreditCardPayment" discriminator-value="CREDIT"&gt;
&lt;property name="creditCardType" column="CCTYPE"/&gt;
...
&lt;/subclass&gt;
&lt;subclass name="CashPayment" discriminator-value="CASH"&gt;
...
&lt;/subclass&gt;
&lt;subclass name="ChequePayment" discriminator-value="CHEQUE"&gt;
...
&lt;/subclass&gt;
&lt;/class&gt;</pre>
<p>采用这种策略只需要一张表即可。它有一个很大的限制：要求那些由子类定义的字段， 如<tt class=literal>CCTYPE</tt>，不能有<tt class=literal>非空(NOT NULL)</tt>约束。 </p>
</div>
<div class=sect2 lang=zh-cn>
<div class=titlepage>
<div>
<div>
<h3 class=title><a name=inheritance-tablepersubclass></a>10.1.2.&nbsp;每个子类一张表(Table per subclass)</h3>
</div>
</div>
<div></div>
</div>
<p>对于上例中的几个类而言，采用&#8220;每个子类一张表&#8221;的映射策略，代码如下所示： </p>
<pre class=programlisting>&lt;class name="Payment" table="PAYMENT"&gt;
&lt;id name="id" type="long" column="PAYMENT_ID"&gt;
&lt;generator class="native"/&gt;
&lt;/id&gt;
&lt;property name="amount" column="AMOUNT"/&gt;
...
&lt;joined-subclass name="CreditCardPayment" table="CREDIT_PAYMENT"&gt;
&lt;key column="PAYMENT_ID"/&gt;
...
&lt;/joined-subclass&gt;
&lt;joined-subclass name="CashPayment" table="CASH_PAYMENT"&gt;
&lt;key column="PAYMENT_ID"/&gt;
&lt;property name="creditCardType" column="CCTYPE"/&gt;
...
&lt;/joined-subclass&gt;
&lt;joined-subclass name="ChequePayment" table="CHEQUE_PAYMENT"&gt;
&lt;key column="PAYMENT_ID"/&gt;
...
&lt;/joined-subclass&gt;
&lt;/class&gt;</pre>
<p>需要四张表。三个子类表通过主键关联到超类表(因而关系模型实际上是一对一关联)。 </p>
</div>
<div class=sect2 lang=zh-cn>
<div class=titlepage>
<div>
<div>
<h3 class=title><a name=inheritance-tablepersubclass-discriminator></a>10.1.3.&nbsp;每个子类一张表(Table per subclass)，使用辨别标志(Discriminator)</h3>
</div>
</div>
<div></div>
</div>
<p>注意，对&#8220;每个子类一张表&#8221;的映射策略，Hibernate的实现不需要辨别字段，而其他 的对象/关系映射工具使用了一种不同于Hibernate的实现方法，该方法要求在超类 表中有一个类型辨别字段(type discriminator column)。Hibernate采用的方法更 难实现，但从关系（数据库）这点上来看，按理说它更正确。若你愿意使用带有辨别字 段的&#8220;每个子类一张表&#8221;的策略，你可以结合使用<tt class=literal>&lt;subclass&gt;</tt> 与<tt class=literal>&lt;join&gt;</tt>，如下所示： </p>
<pre class=programlisting>&lt;class name="Payment" table="PAYMENT"&gt;
&lt;id name="id" type="long" column="PAYMENT_ID"&gt;
&lt;generator class="native"/&gt;
&lt;/id&gt;
&lt;discriminator column="PAYMENT_TYPE" type="string"/&gt;
&lt;property name="amount" column="AMOUNT"/&gt;
...
&lt;subclass name="CreditCardPayment" discriminator-value="CREDIT"&gt;
&lt;join table="CREDIT_PAYMENT"&gt;
&lt;property name="creditCardType" column="CCTYPE"/&gt;
...
&lt;/join&gt;
&lt;/subclass&gt;
&lt;subclass name="CashPayment" discriminator-value="CASH"&gt;
&lt;join table="CASH_PAYMENT"&gt;
...
&lt;/join&gt;
&lt;/subclass&gt;
&lt;subclass name="ChequePayment" discriminator-value="CHEQUE"&gt;
&lt;join table="CHEQUE_PAYMENT" fetch="select"&gt;
...
&lt;/join&gt;
&lt;/subclass&gt;
&lt;/class&gt;</pre>
<p>可选的声明<tt class=literal>fetch="select"</tt>，是用来告诉Hibernate，在查询超类时， 不要使用外部连接(outer join)来抓取子类<tt class=literal>ChequePayment</tt>的数据。 </p>
</div>
<div class=sect2 lang=zh-cn>
<div class=titlepage>
<div>
<div>
<h3 class=title><a name=inheritance-mixing-tableperclass-tablepersubclass></a>10.1.4.&nbsp;混合使用&#8220;每个类分层结构一张表&#8221;和&#8220;每个子类一张表&#8221;</h3>
</div>
</div>
<div></div>
</div>
<p>你甚至可以采取如下方法混和使用&#8220;每个类分层结构一张表&#8221;和&#8220;每个子类一张表&#8221;这两种策略： </p>
<pre class=programlisting>&lt;class name="Payment" table="PAYMENT"&gt;
&lt;id name="id" type="long" column="PAYMENT_ID"&gt;
&lt;generator class="native"/&gt;
&lt;/id&gt;
&lt;discriminator column="PAYMENT_TYPE" type="string"/&gt;
&lt;property name="amount" column="AMOUNT"/&gt;
...
&lt;subclass name="CreditCardPayment" discriminator-value="CREDIT"&gt;
&lt;join table="CREDIT_PAYMENT"&gt;
&lt;property name="creditCardType" column="CCTYPE"/&gt;
...
&lt;/join&gt;
&lt;/subclass&gt;
&lt;subclass name="CashPayment" discriminator-value="CASH"&gt;
...
&lt;/subclass&gt;
&lt;subclass name="ChequePayment" discriminator-value="CHEQUE"&gt;
...
&lt;/subclass&gt;
&lt;/class&gt;</pre>
<p>对上述任何一种映射策略而言，指向根类<tt class=literal>Payment</tt>的 关联是使用<tt class=literal>&lt;many-to-one&gt;</tt>进行映射的。 </p>
<pre class=programlisting>&lt;many-to-one name="payment" column="PAYMENT_ID" class="Payment"/&gt;</pre>
</div>
<div class=sect2 lang=zh-cn>
<div class=titlepage>
<div>
<div>
<h3 class=title><a name=inheritance-tableperconcrete></a>10.1.5.&nbsp;每个具体类一张表(Table per concrete class)</h3>
</div>
</div>
<div></div>
</div>
<p>对于&#8220;每个具体类一张表&#8221;的映射策略，可以采用两种方法。第一种方法是使用 <tt class=literal>&lt;union-subclass&gt;</tt>。 </p>
<pre class=programlisting>&lt;class name="Payment"&gt;
&lt;id name="id" type="long" column="PAYMENT_ID"&gt;
&lt;generator class="sequence"/&gt;
&lt;/id&gt;
&lt;property name="amount" column="AMOUNT"/&gt;
...
&lt;union-subclass name="CreditCardPayment" table="CREDIT_PAYMENT"&gt;
&lt;property name="creditCardType" column="CCTYPE"/&gt;
...
&lt;/union-subclass&gt;
&lt;union-subclass name="CashPayment" table="CASH_PAYMENT"&gt;
...
&lt;/union-subclass&gt;
&lt;union-subclass name="ChequePayment" table="CHEQUE_PAYMENT"&gt;
...
&lt;/union-subclass&gt;
&lt;/class&gt;</pre>
<p>这里涉及三张表。每张表为对应类的所有属性（包括从超类继承的属性）定义相应字段。 </p>
<p>这种方式的局限在于，如果一个属性在超类中做了映射，其字段名必须与所有子类 表中定义的相同。(我们可能会在Hibernate的后续发布版本中放宽此限制。) 不允许在联合子类(union subclass)的继承层次中使用标识生成器策略(identity generator strategy), 实际上, 主键的种子(primary key seed)不得不为同一继承层次中的全部被联合子类所共用. </p>
</div>
<div class=sect2 lang=zh-cn>
<div class=titlepage>
<div>
<div>
<h3 class=title><a name=inheritance-tableperconcreate-polymorphism></a>10.1.6.&nbsp;Table per concrete class, using implicit polymorphism</h3>
</div>
<div>
<h3 class=title><a name=inheritance-tableperconcreate-polymorphism></a>10.1.6.&nbsp;Table per concrete class, using implicit polymorphism</h3>
</div>
</div>
<div></div>
</div>
<p>另一种可供选择的方法是采用隐式多态： </p>
<pre class=programlisting>&lt;class name="CreditCardPayment" table="CREDIT_PAYMENT"&gt;
&lt;id name="id" type="long" column="CREDIT_PAYMENT_ID"&gt;
&lt;generator class="native"/&gt;
&lt;/id&gt;
&lt;property name="amount" column="CREDIT_AMOUNT"/&gt;
...
&lt;/class&gt;
&lt;class name="CashPayment" table="CASH_PAYMENT"&gt;
&lt;id name="id" type="long" column="CASH_PAYMENT_ID"&gt;
&lt;generator class="native"/&gt;
&lt;/id&gt;
&lt;property name="amount" column="CASH_AMOUNT"/&gt;
...
&lt;/class&gt;
&lt;class name="ChequePayment" table="CHEQUE_PAYMENT"&gt;
&lt;id name="id" type="long" column="CHEQUE_PAYMENT_ID"&gt;
&lt;generator class="native"/&gt;
&lt;/id&gt;
&lt;property name="amount" column="CHEQUE_AMOUNT"/&gt;
...
&lt;/class&gt;</pre>
<p>注意，我们没有在任何地方明确的提及接口<tt class=literal>Payment</tt>。同时注意 <tt class=literal>Payment</tt>的属性在每个子类中都进行了映射。如果你想避免重复， 可以考虑使用XML实体(例如：位于<tt class=literal>DOCTYPE</tt>声明内的 <tt class=literal>[ &lt;!ENTITY allproperties SYSTEM "allproperties.xml"&gt; ]</tt> 和映射中的<tt class=literal>&amp;allproperties;</tt>)。 </p>
<p>这种方法的缺陷在于，在Hibernate执行多态查询时(polymorphic queries)无法生成带 <tt class=literal>UNION</tt>的SQL语句。 </p>
<p>对于这种映射策略而言，通常用<tt class=literal>&lt;any&gt;</tt>来实现到 <tt class=literal>Payment</tt>的多态关联映射。 </p>
<pre class=programlisting>&lt;any name="payment" meta-type="string" id-type="long"&gt;
&lt;meta-value value="CREDIT" class="CreditCardPayment"/&gt;
&lt;meta-value value="CASH" class="CashPayment"/&gt;
&lt;meta-value value="CHEQUE" class="ChequePayment"/&gt;
&lt;column name="PAYMENT_CLASS"/&gt;
&lt;column name="PAYMENT_ID"/&gt;
&lt;/any&gt;</pre>
</div>
<div class=sect2 lang=zh-cn>
<div class=titlepage>
<div>
<div>
<h3 class=title><a name=inheritace-mixingpolymorphism></a>10.1.7.&nbsp;隐式多态和其他继承映射混合使用</h3>
</div>
</div>
<div></div>
</div>
<p>对这一映射还有一点需要注意。因为每个子类都在各自独立的元素<tt class=literal>&lt;class&gt;</tt> 中映射(并且<tt class=literal>Payment</tt>只是一个接口)，每个子类可以很容易的成为另一 个继承体系中的一部分！(你仍然可以对接口<tt class=literal>Payment</tt>使用多态查询。) </p>
<pre class=programlisting>&lt;class name="CreditCardPayment" table="CREDIT_PAYMENT"&gt;
&lt;id name="id" type="long" column="CREDIT_PAYMENT_ID"&gt;
&lt;generator class="native"/&gt;
&lt;/id&gt;
&lt;discriminator column="CREDIT_CARD" type="string"/&gt;
&lt;property name="amount" column="CREDIT_AMOUNT"/&gt;
...
&lt;subclass name="MasterCardPayment" discriminator-value="MDC"/&gt;
&lt;subclass name="VisaPayment" discriminator-value="VISA"/&gt;
&lt;/class&gt;
&lt;class name="NonelectronicTransaction" table="NONELECTRONIC_TXN"&gt;
&lt;id name="id" type="long" column="TXN_ID"&gt;
&lt;generator class="native"/&gt;
&lt;/id&gt;
...
&lt;joined-subclass name="CashPayment" table="CASH_PAYMENT"&gt;
&lt;key column="PAYMENT_ID"/&gt;
&lt;property name="amount" column="CASH_AMOUNT"/&gt;
...
&lt;/joined-subclass&gt;
&lt;joined-subclass name="ChequePayment" table="CHEQUE_PAYMENT"&gt;
&lt;key column="PAYMENT_ID"/&gt;
&lt;property name="amount" column="CHEQUE_AMOUNT"/&gt;
...
&lt;/joined-subclass&gt;
&lt;/class&gt;</pre>
<p>我们还是没有明确的提到<tt class=literal>Payment</tt>。 如果我们针对接口<tt class=literal>Payment</tt>执行查询 ——如<tt class=literal>from Payment</tt>—— Hibernate 自动返回<tt class=literal>CreditCardPayment</tt>(和它的子类，因为 它们也实现了接口<tt class=literal>Payment</tt>)、 <tt class=literal>CashPayment</tt>和<tt class=literal>Chequepayment</tt>的实例， 但不返回<tt class=literal>NonelectronicTransaction</tt>的实例。 </p>
</div>
</div>
<div class=sect1 lang=zh-cn>
<div class=titlepage>
<div>
<div>
<h2 class=title style="CLEAR: both"><a name=inheritance-limitations></a>10.2.&nbsp;限制</h2>
</div>
</div>
<div></div>
</div>
<p>对&#8220;每个具体类映射一张表&#8221;（table per concrete-class）的映射策略而言，隐式多态的 方式有一定的限制。而<tt class=literal>&lt;union-subclass&gt;</tt>映射的限制则没有那 么严格。 </p>
<p>下面表格中列出了在Hibernte中&#8220;每个具体类一张表&#8221;的策略和隐式多态的限制。 </p>
<div class=table><a name=d0e8645></a>
<p class=title><strong>表&nbsp;10.1.&nbsp;继承映射特性(Features of inheritance mappings) </strong></p>
<table summary="继承映射特性(Features of inheritance mappings)&#9;&#9;&#9;" border=1>
    <colgroup>
    <col align=left>
    <col align=left>
    <col align=left>
    <col align=left>
    <col align=left>
    <col align=left>
    <col align=left>
    <col align=left></colgroup>
    <thead>
        <tr>
            <th align=left>继承策略(Inheritance strategy)</th>
            <th align=left>多态多对一</th>
            <th align=left>多态一对一</th>
            <th align=left>多态一对多</th>
            <th align=left>多态多对多</th>
            <th align=left>多态 <tt class=literal>load()/get()</tt></th>
            <th align=left>多态查询</th>
            <th align=left>多态连接(join)</th>
            <th align=left>外连接(Outer join)抓取</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td align=left>每个类分层结构一张表</td>
            <td align=left><tt class=literal>&lt;many-to-one&gt;</tt></td>
            <td align=left><tt class=literal>&lt;one-to-one&gt;</tt></td>
            <td align=left><tt class=literal>&lt;one-to-many&gt;</tt></td>
            <td align=left><tt class=literal>&lt;many-to-many&gt;</tt></td>
            <td align=left><tt class=literal>s.get(Payment.class, id)</tt></td>
            <td align=left><tt class=literal>from Payment p</tt></td>
            <td align=left><tt class=literal>from Order o join o.payment p</tt></td>
            <td align=left><span class=emphasis><em>支持</em></span></td>
        </tr>
        <tr>
            <td align=left>每个子类一张表</td>
            <td align=left><tt class=literal>&lt;many-to-one&gt;</tt></td>
            <td align=left><tt class=literal>&lt;one-to-one&gt;</tt></td>
            <td align=left><tt class=literal>&lt;one-to-many&gt;</tt></td>
            <td align=left><tt class=literal>&lt;many-to-many&gt;</tt></td>
            <td align=left><tt class=literal>s.get(Payment.class, id)</tt></td>
            <td align=left><tt class=literal>from Payment p</tt></td>
            <td align=left><tt class=literal>from Order o join o.payment p</tt></td>
            <td align=left><span class=emphasis><em>支持</em></span></td>
        </tr>
        <tr>
            <td align=left>每个具体类一张表(union-subclass)</td>
            <td align=left><tt class=literal>&lt;many-to-one&gt;</tt></td>
            <td align=left><tt class=literal>&lt;one-to-one&gt;</tt></td>
            <td align=left><tt class=literal>&lt;one-to-many&gt;</tt> (仅对于<tt class=literal>inverse="true"</tt>的情况)</td>
            <td align=left><tt class=literal>&lt;many-to-many&gt;</tt></td>
            <td align=left><tt class=literal>s.get(Payment.class, id)</tt></td>
            <td align=left><tt class=literal>from Payment p</tt></td>
            <td align=left><tt class=literal>from Order o join o.payment p</tt></td>
            <td align=left><span class=emphasis><em>支持</em></span></td>
        </tr>
        <tr>
            <td align=left>每个具体类一张表(隐式多态)</td>
            <td align=left><tt class=literal>&lt;any&gt;</tt></td>
            <td align=left><span class=emphasis><em>不支持</em></span></td>
            <td align=left><span class=emphasis><em>不支持</em></span></td>
            <td align=left><tt class=literal>&lt;many-to-any&gt;</tt></td>
            <td align=left><tt class=literal>s.createCriteria(Payment.class).add( Restrictions.idEq(id) ).uniqueResult()</tt></td>
            <td align=left><tt class=literal>from Payment p</tt></td>
            <td align=left><span class=emphasis><em>不支持</em></span></td>
            <td align=left><span class=emphasis><em>不支持</em></span></td>
        </tr>
    </tbody>
</table>
</div>
</div>
</div>
<div class=navfooter>
<hr>
</div>
</div>
<img src ="http://www.blogjava.net/WshmAndLily/aggbug/135807.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/WshmAndLily/" target="_blank">semovy</a> 2007-08-10 14:01 <a href="http://www.blogjava.net/WshmAndLily/articles/135807.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Hibernate查询语言</title><link>http://www.blogjava.net/WshmAndLily/articles/135801.html</link><dc:creator>semovy</dc:creator><author>semovy</author><pubDate>Fri, 10 Aug 2007 05:55:00 GMT</pubDate><guid>http://www.blogjava.net/WshmAndLily/articles/135801.html</guid><wfw:comment>http://www.blogjava.net/WshmAndLily/comments/135801.html</wfw:comment><comments>http://www.blogjava.net/WshmAndLily/articles/135801.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/WshmAndLily/comments/commentRss/135801.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/WshmAndLily/services/trackbacks/135801.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 第&nbsp;14&nbsp;章&nbsp;批量处理（Batch processing）使用Hibernate将 100 000 条记录插入到数据库的一个很自然的做法可能是这样的 Session session = sessionFactory.openSession();Transaction tx = session.beginTransaction();for...&nbsp;&nbsp;<a href='http://www.blogjava.net/WshmAndLily/articles/135801.html'>阅读全文</a><img src ="http://www.blogjava.net/WshmAndLily/aggbug/135801.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/WshmAndLily/" target="_blank">semovy</a> 2007-08-10 13:55 <a href="http://www.blogjava.net/WshmAndLily/articles/135801.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>有关Criteria</title><link>http://www.blogjava.net/WshmAndLily/articles/135478.html</link><dc:creator>semovy</dc:creator><author>semovy</author><pubDate>Thu, 09 Aug 2007 05:57:00 GMT</pubDate><guid>http://www.blogjava.net/WshmAndLily/articles/135478.html</guid><wfw:comment>http://www.blogjava.net/WshmAndLily/comments/135478.html</wfw:comment><comments>http://www.blogjava.net/WshmAndLily/articles/135478.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/WshmAndLily/comments/commentRss/135478.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/WshmAndLily/services/trackbacks/135478.html</trackback:ping><description><![CDATA[<p><strong><span>Criteria</span></strong><strong><span>:</span></strong></p>
<p align=left><span>Criteria criteria = session.createCriteria(User.class);</span></p>
<p align=left><strong><span>1)</span></strong><span>criteria.add(Restrictions.gt("age", new Integer(20)));</span></p>
<p align=left><strong><span>2)</span></strong><span>criteria.add(Restrictions.lt("age", new Integer(40)));</span></p>
<p align=left><strong><span>3)</span></strong><span>criteria.add(Restrictions.or(Restrictions.eq("age", new Integer(20)), Restrictions.isNull("age")));</span></p>
<p align=left><code><strong><span>crit.add(Restrictions.ilike(</span></strong></code><code><strong><span>"name"</span></strong></code><code><strong><span>,</span></strong></code><code><strong><span>"1"</span></strong></code><code><strong><span>,&nbsp;MatchMode.END));</span></strong></code><code><strong></strong></code></p>
<p align=left><code><strong><span>//</span></strong></code><span> //</span><span> <span>ilike</span></span><span>的</span><span>i</span><span>即</span><span>ignore</span><span>之意</span><span>,</span><span>所以</span><span>这</span><span>里</span><span>查询</span><span>出</span><span>englishName"Optima?XL?100K?Ultracentrifuge"</span><span>（忽略大小写）的</span><span>记录</span><strong></strong></p>
<p align=left><strong><span>4)</span></strong><span>criteria.add(Restrictions.sqlRestriction("{alias}.name LIKE (?)", "cater%", Hibernate.STRING));</span></p>
<p align=left><strong><span>5)</span></strong><strong><span> </span></strong><span>Integer[] ages = {new Integer(20), new Integer(40)};</span></p>
<p align=left><span>Type[] types = {Hibernate.INTEGER, Hibernate.INTEGER};</span></p>
<p align=left><span>criteria.add(Restrictions.sqlRestriction("{alias}.age BETWEEN (?) AND (?)", ages, types));</span></p>
<p align=left>&nbsp;</p>
<p align=left><strong><span>6)</span></strong><strong><span> </span></strong><span>criteria.setFirstResult(51); </span></p>
<p align=left><span>criteria.setMaxResult(50);</span></p>
<p align=left><span>&nbsp;<strong>&nbsp;7)</strong></span><strong><span> </span></strong><strong><span>统计表</span></strong><span>rowCount()</span><span>、</span><span>count()</span><span>、</span><span>max()</span><span>、</span><span>min()</span><span>、</span><span>countDistinct()</span><strong></strong></p>
<p align=left><span>criteria.setProjection(Projections.avg("age"));</span></p>
<p align=left><span>&nbsp;<strong>&nbsp;8)</strong></span><strong><span>分组</span></strong><span>20,20,25,30 </span><span><span>&#224;</span></span><span> 20.25.30</span></p>
<p align=left><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&nbsp;</span><span>criteria.setProjection(Projections.groupProperty("age"));</span><span> </span></p>
<p align=left><span>&nbsp;<strong>9)</strong></span><strong><span>结合统计分组</span></strong><strong></strong></p>
<p align=left><strong><span><span>&nbsp;&nbsp; </span></span></strong><span>ProjectionList projectionList = Projections.projectionList();</span></p>
<p align=left><span>projectionList.add(Projections.groupProperty("age"));</span></p>
<p align=left><span>projectionList.add(Projections.rowCount());</span></p>
<p align=left><span>Criteria criteria = session.createCriteria(User.class);</span></p>
<p align=left><span>criteria.setProjection(projectionList);</span></p>
<p align=left><strong><span>10)</span></strong><strong><span> </span></strong><strong><span>Query Criteria Id: data type Long</span></strong><strong></strong></p>
<p align=left><span>projectionList.add(</span><code><span>crit.add(&nbsp;Expression.idEq(&nbsp;</span></code><code><span>11111L</span></code><code><span>)&nbsp;);</span></code><code></code></p>
<p align=left><strong><span>11)</span></strong><strong><span> </span></strong><strong><span>Query Criteria Id: Not Equal</span></strong><code><strong></strong></code></p>
<p align=left><code>&nbsp;</code><code><span>crit.add(&nbsp;Expression.ne(&nbsp;</span></code><code><span>"name"</span></code><code><span>,&nbsp;</span></code><code><span>"noName"&nbsp;</span></code><code><span>)&nbsp;);</span></code><code><span>)</span></code></p>
<p align=left><code><strong><span>12)</span></strong></code><code><span>crit.setProjection(Projections.rowCount());</span></code></p>
<p align=left><code><strong><span>13</span></strong></code><code><strong><span>）</span></strong></code><code><strong><span>这</span></strong></code><code><strong><span>是</span></strong></code><code><strong><span>显</span></strong></code><code><strong><span>示不重</span></strong></code><code><strong><span>复记录</span></strong></code><code><strong></strong></code></p>
<p align=left><code><span>criteria.setResultTransformer(criteria.DISTINCT_ROOT_ENTITY);</span></code></p>
<p align=left><span>List users = criteria.list();</span></p>
<p align=left><span>Restrictions</span><span>的幾個常用限定</span><span>查</span><span>詢方法如下表所示：</span></p>
<table cellPadding=0 width="100%" border=1>
    <tbody>
        <tr>
            <td>
            <p align=left><span>方法</span></p>
            </td>
            <td>
            <p align=left><span>說</span><span>明</span></p>
            </td>
        </tr>
        <tr>
            <td>
            <p align=left><span>Restrictions.eq</span></p>
            </td>
            <td>
            <p align=left><span>等於</span></p>
            </td>
        </tr>
        <tr>
            <td>
            <p align=left><span>Restrictions.allEq</span></p>
            </td>
            <td>
            <p align=left><span>使用</span><span>Map</span><span>，使用</span><span>key/value</span><span>進行多個等於的比對</span></p>
            </td>
        </tr>
        <tr>
            <td>
            <p align=left><span>Restrictions.gt</span></p>
            </td>
            <td>
            <p align=left><span>大於</span><span> &gt;</span></p>
            </td>
        </tr>
        <tr>
            <td>
            <p align=left><span>Restrictions.ge</span></p>
            </td>
            <td>
            <p align=left><span>大於等於</span><span> &gt;=</span></p>
            </td>
        </tr>
        <tr>
            <td>
            <p align=left><span>Restrictions.lt</span></p>
            </td>
            <td>
            <p align=left><span>小於</span><span> &lt;</span></p>
            </td>
        </tr>
        <tr>
            <td>
            <p align=left><span>Restrictions.le</span></p>
            </td>
            <td>
            <p align=left><span>小於等於</span><span> &lt;=</span></p>
            </td>
        </tr>
        <tr>
            <td>
            <p align=left><span>Restrictions.between</span></p>
            </td>
            <td>
            <p align=left><span>對應</span><span>SQL</span><span>的</span><span>BETWEEN</span><span>子句</span></p>
            </td>
        </tr>
        <tr>
            <td>
            <p align=left><span>Restrictions.like</span></p>
            </td>
            <td>
            <p align=left><span>對應</span><span>SQL</span><span>的</span><span>LIKE</span><span>子句</span></p>
            </td>
        </tr>
        <tr>
            <td>
            <p align=left><span>Restrictions.in</span></p>
            </td>
            <td>
            <p align=left><span>對應</span><span>SQL</span><span>的</span><span>in</span><span>子句</span></p>
            </td>
        </tr>
        <tr>
            <td>
            <p align=left><span>Restrictions.and</span></p>
            </td>
            <td>
            <p align=left><span>and</span><span>關係</span></p>
            </td>
        </tr>
        <tr>
            <td>
            <p align=left><span>Restrictions.or</span></p>
            </td>
            <td>
            <p align=left><span>or</span><span>關係</span></p>
            </td>
        </tr>
        <tr>
            <td>
            <p align=left><span>Restrictions.sqlRestriction</span></p>
            </td>
            <td>
            <p align=left><span>SQL</span><span>限定</span><span>查</span><span>詢</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p align=left><strong><span>HQL</span></strong><strong><span>（</span></strong><strong><span>Hibernate Query Language</span></strong><strong><span>）</span></strong><strong></strong></p>
<p><span>&nbsp;<strong><span>PS:</span></strong></span></p>
<p><span>&nbsp;1:HOL</span><span>是不区分大小写的</span><span>,</span><span>但名称是区分大小写的</span><span>.</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span>2:</span><span>如果</span><span>User</span><span>類別提供有適當的建構方法，則可以在使用</span><span>HQL</span><span>時直接指定新建一個物件傳回</span></p>
<p><span>Query query = session.createQuery("select new User(user.name, user.age) from User as user");</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>3.</span><span> </span><span>如果試圖使用</span><span>Session</span><span>的</span><span>saveOrupdate()</span><span>方法，則會新增一筆資料而不是更新原有的資料。</span></p>
<p><span><span>&nbsp;&nbsp; </span>&nbsp;4. </span><span>還可以結合</span><span>having</span><span>子句，例如只將平均大於</span><span>20</span><span>的資料分組顯示出來：</span></p>
<p align=left><span>Query query = session.createQuery("select user.sex, avg(user.age) from User user group by user.sex having avg(user.age) &gt; 20");</span></p>
<p><span><span>&nbsp;&nbsp; </span>5. </span><span>更新与删除的时候</span><span> </span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span>Session session = sessionFactory.openSession();</span></p>
<p><span>Transaction tx= session.beginTransaction();</span></p>
<p><span>Query query = session.createQuery("update User set name='momor' where name='bbb'");</span></p>
<p><span>query.executeUpdate();</span></p>
<p><span>tx.commit();</span></p>
<p><span>session.close();</span></p>
<p>&nbsp;</p>
<p><strong><span>Hibernate:HQL/QBC</span></strong><strong><span>查询语</span></strong><strong><span>言比</span></strong><strong><span>较</span></strong><strong><span>的用法</span></strong><strong></strong></p>
<p align=left><strong><span>Hib</span></strong><strong><span>的</span></strong><strong><span>检</span></strong><strong><span>索方式</span></strong><span><br>1'</span><span>导</span><span>航</span><span>对</span><span>象</span><span>图检</span><span>索方式。通</span><span>过</span><span>已</span><span>经</span><span>加</span><span>载</span><span>的</span><span>对</span><span>象，</span><span>调</span><span>用</span><span>.iterator()</span><span>方法可以得到</span><span>order</span><span>对</span><span>象</span><span><br></span><span>如果是首次</span><span>执</span><span>行此方法，</span><span>Hib</span><span>会从数据</span><span>库</span><span>加</span><span>载关联</span><span>的</span><span>order</span><span>对</span><span>象，否</span><span>则</span><span>就从</span><span>缓</span><span>存中得到。</span><span><br></span><span>2'OID</span><span>检</span><span>索方式。通</span><span>过</span><span>session</span><span>的</span><span>get</span><span>，</span><span>load</span><span>方法知道了</span><span>OID</span><span>的情况下可以使用</span><span><br>3'HQL</span><span>检</span><span>索方式。使用面向</span><span>对</span><span>象的</span><span>HQL</span><span>查询语</span><span>句</span><span>session</span><span>的</span><span>find</span><span>方法利用</span><span>HQL</span><span>来</span><span>查询</span><span><br>4'QBC</span><span>检</span><span>索方式。</span><span>利用</span><span>QBCAPI</span><span>来</span><span>检</span><span>索它是封装了基于字符串的</span><span>查询语</span><span>句</span><span><br>5'</span><span>本地的</span><span>SQL</span><span>检</span><span>索方式。使用本地数据</span><span>库</span><span>的</span><span>SQL</span><span>查询语</span><span>句</span><span>Hib</span><span>会</span><span>负责</span><span>把</span><span>检</span><span>索到的</span><span>JDBC</span><span>结</span><span>果集映射</span><span>为</span><span>持久化</span><span>对</span><span>象</span><span>图</span><span>。</span><span><br><br></span><span>五</span><span>种检</span><span>索方式的使用</span><span>场</span><span>合和特点：</span><span><br><br>HQL&nbsp;</span><span>：</span>&nbsp;<span>是面向</span><span>对</span><span>象的</span><span>查询语</span><span>言，同</span><span>SQL</span><span>有些相似是</span><span>Hib</span><span>中最常用的方式。</span><span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>查询设</span><span>定各</span><span>种查询</span><span>条件。</span><span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>支持投影</span><span>查询</span><span>，</span><span>检</span><span>索出</span><span>对</span><span>象的部分属性。</span><span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>支持分</span><span>页查询</span><span>，允</span><span>许</span><span>使用</span><span>having</span><span>和</span><span>group&nbsp;by<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>提供内制的聚集函数，</span><span>sum()</span><span>，</span><span>min()</span><span>，</span><span>max()<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>能</span><span>调</span><span>用用</span><span>户</span><span>的自定</span><span>义</span><span>SQL<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>支持子</span><span>查询</span><span>，嵌入式</span><span>查询</span><span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>支持</span><span>动态绑</span><span>定参数</span><span><br></span><span>建</span><span>议</span><span>使用</span><span>Query</span><span>接口替</span><span>换</span><span>session</span><span>的</span><span>find</span><span>方法。</span><span><br>&nbsp;&nbsp;&nbsp;Query&nbsp;Q&nbsp;=&nbsp;session.createQuery("from&nbsp;customer&nbsp;as&nbsp;c&nbsp;where&nbsp;c.name&nbsp;=&nbsp;:customerName"&nbsp;+&nbsp;"and&nbsp;c.age&nbsp;=&nbsp;:customerAge");<br>&nbsp;&nbsp;&nbsp;query.setString&nbsp;("customerName"&nbsp;,&nbsp;"tom");<br>&nbsp;&nbsp;&nbsp;query.setInteger("customerAge"&nbsp;,&nbsp;"21");<br>&nbsp;&nbsp;&nbsp;list&nbsp;result&nbsp;=&nbsp;query.list();<br>QBC&nbsp;:&nbsp;&nbsp;QBCAPI</span><span>提供了另一</span><span>种</span><span>方式，主要是</span><span>Criteria</span><span>接口、</span><span>Criterion</span><span>接口和</span><span>Expression</span><span>类</span><span><br>&nbsp;&nbsp;&nbsp;Criteria&nbsp;criteria&nbsp;=&nbsp;session.createCriteria(customer.class);<br>&nbsp;&nbsp;&nbsp;Criterion&nbsp;criterion1&nbsp;=&nbsp;Expression.like("name","t%");<br>&nbsp;&nbsp;&nbsp;Criterion&nbsp;criterion2&nbsp;=&nbsp;Expression.eq("age",new&nbsp;Integer(21));<br>&nbsp;&nbsp;&nbsp;Critera&nbsp;=&nbsp;criteria.add(criterion1)&nbsp;;<br>&nbsp;&nbsp;&nbsp;Critera&nbsp;=&nbsp;criteria.add(criterion2)&nbsp;;<br>&nbsp;&nbsp;&nbsp;list&nbsp;result&nbsp;=&nbsp;criteria.list();&nbsp;<br>&nbsp;&nbsp;&nbsp;</span><span>或是：</span><span>&nbsp;list&nbsp;result&nbsp;=&nbsp;session.createCriteria(Customer.class).add(Expression.eq("this.name","tom")).list();&nbsp;<br>SQL&nbsp;:&nbsp;&nbsp;</span><span>采用</span><span>HQL</span><span>和</span><span>QBC</span><span>检</span><span>索</span><span>时</span><span>，</span><span>Hib</span><span>生成</span><span>SQL</span><span>语</span><span>句适用所有数据</span><span>库</span><span>。</span><span><br>&nbsp;&nbsp;&nbsp;Query&nbsp;query&nbsp;&nbsp;=&nbsp;session.createSQLQuery("select&nbsp;{c.*}&nbsp;from&nbsp;customers&nbsp;c&nbsp;where&nbsp;c.name&nbsp;like&nbsp;:&nbsp;customername&nbsp;"&nbsp;+&nbsp;"and&nbsp;c.age&nbsp;=&nbsp;:customerage","c",customer.calss);<br>&nbsp;&nbsp;&nbsp;query.setString("customername","tom");<br>&nbsp;&nbsp;&nbsp;query.setInteger("customerage","21");<br>&nbsp;&nbsp;&nbsp;list&nbsp;result&nbsp;=&nbsp;query.list();<br>/////////////</span><span>多</span><span>态查询</span><span><br>&nbsp;&nbsp;&nbsp;HQL&nbsp;</span><span>：</span><span>session.createQuery("from&nbsp;employee");<br>&nbsp;&nbsp;&nbsp;QBC&nbsp;</span><span>：</span><span>session.createCriteria(employee.class);<br>&nbsp;&nbsp;&nbsp;HQL&nbsp;:&nbsp;session.createQuery("from&nbsp;hourlyEmployee");<br>&nbsp;&nbsp;&nbsp;QBC&nbsp;:&nbsp;session.createCriteria(hourlyEmployee.class);<br>&nbsp;&nbsp;&nbsp;</span><span>下面的</span><span>HQL</span><span>查询语</span><span>句将</span><span>检</span><span>索出所有的持久化</span><span>对</span><span>象：</span><span><br>&nbsp;&nbsp;&nbsp;from&nbsp;java.lang.Object&nbsp;;<br>&nbsp;&nbsp;&nbsp;from&nbsp;java.io.serializable&nbsp;;<br>////////////</span><span>查询</span><span>的排序</span><span><br>&nbsp;&nbsp;&nbsp;1'</span><span>查询结</span><span>果按照客</span><span>户</span><span>姓名升序排列：</span><span><br>&nbsp;&nbsp;&nbsp;HQL&nbsp;</span><span>：</span><span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Query&nbsp;query&nbsp;=&nbsp;session.createQuery&nbsp;("from&nbsp;customer&nbsp;c&nbsp;order&nbsp;by&nbsp;c.name");<br>&nbsp;&nbsp;&nbsp;QBC&nbsp;</span><span>：</span><span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Criteria&nbsp;criteria&nbsp;=&nbsp;session.createCriteria(customer.class);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;criteria.addOrder(order.asc("name"));<br>&nbsp;&nbsp;&nbsp;HQL&nbsp;:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Query&nbsp;query&nbsp;=&nbsp;session.createQuery&nbsp;("from&nbsp;customer&nbsp;c&nbsp;order&nbsp;by&nbsp;c.name&nbsp;asc&nbsp;,&nbsp;c.age&nbsp;desc");<br>&nbsp;&nbsp;&nbsp;QBC&nbsp;:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Criteria&nbsp;criteria&nbsp;=&nbsp;session.createCriteria(customer.class);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;criteria.addOrder(order.asc&nbsp;("name"));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;criteria.addOrder(order.desc("age"));&nbsp;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;import&nbsp;net.sf.hibernate.pression.Order<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;import&nbsp;mypack.Order<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...........<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Criteria&nbsp;criteria&nbsp;=&nbsp;session.createCritria&nbsp;(mypack.Order.class);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;criteria.addOrder(net.sf.hibernate.Order.asc("name"));<br>///////////HQL</span><span>语</span><span>句的参数</span><span>绑</span><span>定</span><span>Query</span><span>接口提供了</span><span>绑</span><span>定各</span><span>种</span><span>Hib</span><span>映射</span><span>类</span><span>型的方法。</span><span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setBinary()<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setString()<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setBoolean()<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setByte()<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setCalendar()<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setCharacter()<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setDate()<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setDouble()<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setText()<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setTime()<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setTimestamp()<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setEntity()//</span><span>把参数与一个持久化</span><span>类</span><span>的事例</span><span>绑</span><span>定</span><span>lsit&nbsp;result&nbsp;=&nbsp;session.createQuery("from&nbsp;order&nbsp;o&nbsp;where&nbsp;o.customer&nbsp;=&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:customer").setEntity("customer"&nbsp;,&nbsp;customer).list&nbsp;;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setParameter()//</span><span>绑</span><span>定任意</span><span>类</span><span>型的参数</span><span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setProperties()//</span><span>把命名参数与一个</span><span>对</span><span>象的属性</span><span>值绑</span><span>定</span><span>&nbsp;Query&nbsp;query&nbsp;=&nbsp;session.createQuery("from&nbsp;customer&nbsp;c&nbsp;where&nbsp;c.name&nbsp;=:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;name&nbsp;"&nbsp;+&nbsp;"and&nbsp;c.age&nbsp;=:age"&nbsp;);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Query.setProperties(customer);&nbsp;</span></p>
<p>&nbsp;</p>
<img src ="http://www.blogjava.net/WshmAndLily/aggbug/135478.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/WshmAndLily/" target="_blank">semovy</a> 2007-08-09 13:57 <a href="http://www.blogjava.net/WshmAndLily/articles/135478.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于DetachedCriteria</title><link>http://www.blogjava.net/WshmAndLily/articles/135376.html</link><dc:creator>semovy</dc:creator><author>semovy</author><pubDate>Wed, 08 Aug 2007 15:16:00 GMT</pubDate><guid>http://www.blogjava.net/WshmAndLily/articles/135376.html</guid><wfw:comment>http://www.blogjava.net/WshmAndLily/comments/135376.html</wfw:comment><comments>http://www.blogjava.net/WshmAndLily/articles/135376.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/WshmAndLily/comments/commentRss/135376.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/WshmAndLily/services/trackbacks/135376.html</trackback:ping><description><![CDATA[<p>DetachedCriteria detachedCriteria =DetachedCriteria.forClass(UserVO.class)<br>&nbsp;//.add(Restrictions.like("username","sz",MatchMode.ANYWHERE));<br>&nbsp;&nbsp;&nbsp;.add(org.hibernate.criterion.Expression.disjunction()&nbsp; //or查询把add放到外面是and查询,MatchMode.ANYWHERE糊查询<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .add(org.hibernate.criterion.Property.forName("username").like("s", MatchMode.ANYWHERE))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .add(org.hibernate.criterion.Property.forName("password").like("c", MatchMode.ANYWHERE))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; );</p>
<p>&nbsp;</p>
<p>多对一情况&nbsp;&nbsp;<br>DetachedCriteria&nbsp; zlbdc=DetachedCriteria.forClass(ZlZlxm.class, "zlb");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp; .createAlias("zlb.zl", "t")<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // .setProjection(Property.forName("t.id").count())<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //.add(Property.forName("t.id").eq(new&nbsp; Long(1)))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; org.hibernate.criterion.Projection projection=org.hibernate.criterion.Projections.projectionList()<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .add(org.hibernate.criterion.Property.forName("zlb.fdxx"),"id");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; zlbdc.setProjection(projection);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //zlbdc.createCriteria("zl");//加上这句是内联接(inner join)zl为集合<br>投影查询，得到一是object[]</p>
<p><br>&nbsp;&nbsp;DetachedCriteria&nbsp; zlbdc=DetachedCriteria.forClass(ZlZlxm.class, "zlb")<br>&nbsp;&nbsp;//zlbdc.createCriteria("zl"); //此处为对象<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .createAlias("zlb.zl", "t") //别名<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .setProjection(Property.forName("t.id").count())<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .add(Property.forName("t.id").eq(new&nbsp; Long(1))); //这里统计的是个数内联接(inner join)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //zladc.setFetchMode("zla.zlZlxm", org.hibernate.FetchMode.JOIN);//无作用(集合lazy)？？？，如果not lazy将会是全部查出</p>
<img src ="http://www.blogjava.net/WshmAndLily/aggbug/135376.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/WshmAndLily/" target="_blank">semovy</a> 2007-08-08 23:16 <a href="http://www.blogjava.net/WshmAndLily/articles/135376.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Criteria Query</title><link>http://www.blogjava.net/WshmAndLily/articles/135372.html</link><dc:creator>semovy</dc:creator><author>semovy</author><pubDate>Wed, 08 Aug 2007 15:00:00 GMT</pubDate><guid>http://www.blogjava.net/WshmAndLily/articles/135372.html</guid><wfw:comment>http://www.blogjava.net/WshmAndLily/comments/135372.html</wfw:comment><comments>http://www.blogjava.net/WshmAndLily/articles/135372.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/WshmAndLily/comments/commentRss/135372.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/WshmAndLily/services/trackbacks/135372.html</trackback:ping><description><![CDATA[<p align=left><strong><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">Criteria Query </span></strong></p>
<p>
<p align=left><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">Criteria Query</span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">通过面向对象化的设计，将数据查询条件封装为一个对象。简单来<span> </span></span></p>
<p>
<p align=left><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">讲，</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">Criteria Query</span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">可以看作是传统</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">SQL</span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">的对象化表示，如：<span> </span></span></p>
<p>
<p align=left><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">Criteria criteria = session.createCriteria(User.</span><strong><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">class</span></strong><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">); </span></p>
<p>
<p align=left><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">criteria.add(Expression.eq(</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">"name"</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">,</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">"Erica"</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">)); </span></p>
<p>
<p align=left><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">criteria.add(Expression.eq(</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">"sex"</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">,</span><strong><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">new </span></strong><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">Integer(1))); </span></p>
<p>
<p align=left><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">这里的</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">criteria </span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">实例实际上是</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">SQL </span><span>&#8220;</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">Select * from t_user where </span></p>
<p>
<p align=left><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">name=</span><span>&#8217;</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">Erica</span><span>&#8217; </span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">and sex=<chmetcnv w:st="on" tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="1" unitname="&#8221;" />1<span times="" new="" roman?;="" mso-bidi-font-family:="" couriernew?=""><span>&#8221;</span></span></chmetcnv /></span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">的封装（我们可以打开</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">Hibernate </span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">的</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">show_sql </span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">选项，<span> </span></span></p>
<p>
<p align=left><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">以观察</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">Hibernate</span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">在运行期生成的</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">SQL</span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">语句）。<span> </span></span></p>
<p>
<p align=left><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">Hibernate </span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">在运行期会根据</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">Criteria </span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">中指定的查询条件（也就是上面代码中通过<span> </span></span></p>
<p>
<p align=left><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">criteria.add</span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">方法添加的查询表达式）生成相应的</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">SQL</span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">语句。<span> </span></span></p>
<p>
<p align=left><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">这种方式的特点是比较符合</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">Java </span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">程序员的编码习惯，并且具备清晰的可读性。正因<span> </span></span></p>
<p>
<p align=left><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">为此，不少</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">ORM</span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">实现中都提供了类似的实现机制（如</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">Apache OJB</span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">）。<span> </span></span></p>
<p>
<p align=left><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">对于</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">Hibernate</span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">的初学者，特别是对</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">SQL</span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">了解有限的程序员而言，</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">Criteria Query </span></p>
<p>
<p align=left><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">无疑是上手的极佳途径，相对</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">HQL</span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">，</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">Criteria Query</span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">提供了更易于理解的查询手段，借<span> </span></span></p>
<p>
<p align=left><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">助</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">IDE</span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">的</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">Coding Assist</span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">机制，</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">Criteria</span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">的使用几乎不用太多的学习。<span> </span></span></p>
<p>
<p align=left><strong><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">Criteria </span></strong><strong><span>查询表达式<span> </span></span></strong></p>
<p>
<p align=left><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">Criteria </span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">本身只是一个查询容器，具体的查询条件需要通过</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">Criteria.add </span></p>
<p>
<p align=left><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">方法添加到</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">Criteria</span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">实例中。<span> </span></span></p>
<p>
<p align=left><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">如前例所示，</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">Expression </span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">对象具体描述了查询条件。针对</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">SQL </span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">语法，<span> </span></span></p>
<p>
<p align=left><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">Expression</span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">提供了对应的查询限定机制，包括：<span> </span></span></p>
<p>
<p align=left><strong><span 宋体,bold??="">方法 描述<span> </span></span></strong></p>
<p>
<p align=left><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">Expression.eq </span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">对应</span><span mso-font-kerning:="" mso-bidi-font-family:="" 宋体,bold?;="" 0pt;="" verdana?="">SQL</span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">&#8220;</span><span mso-font-kerning:="" mso-bidi-font-family:="" 宋体,bold?;="" 0pt;="" verdana?="">field = value</span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">&#8221;表达式。<span> </span></span></p>
<p>
<p align=left><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">如</span><span mso-font-kerning:="" mso-bidi-font-family:="" 宋体,bold?;="" 0pt;="" verdana?="">Expression.eq(</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">"name"</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">,</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">"Erica"</span><span mso-font-kerning:="" mso-bidi-font-family:="" 宋体,bold?;="" 0pt;="" verdana?="">) </span></p>
<p>
<p align=left><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">Expression.allEq </span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">参数为一个</span><span mso-font-kerning:="" mso-bidi-font-family:="" 宋体,bold?;="" 0pt;="" verdana?="">Map</span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">对象，其中包含了多个属性－值对<span> </span></span></p>
<p>
<p align=left><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">应关系。相当于多个</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">Expression.eq</span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">关系的叠加。<span> </span></span></p>
<p>
<p align=left><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">Expression.gt </span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">对应</span><span mso-font-kerning:="" mso-bidi-font-family:="" 宋体,bold?;="" 0pt;="" verdana?="">SQL</span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">中的 </span><span mso-font-kerning:="" mso-bidi-font-family:="" 宋体,bold?;="" 0pt;="" verdana?="">&#8220;field &gt; value &#8221; </span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">表达式<span> </span></span></p>
<p>
<p align=left><span mso-font-kerning:="" 0pt?="" 宋体,bold?;="">Hibernate Developer&#8217;s Guide Version 1.0 </span></p>
<p>
<p align=left><span mso-font-kerning:="" 0pt?="" 宋体,bold?;="">September 2, 2004 </span><span mso-font-kerning:="" 0pt?="" 宋体,bold?;="">So many open source projects. Why not <strong>Open </strong>your <strong>Doc</strong>uments? </span></p>
<p>
<p align=left><span mso-font-kerning:="" mso-bidi-font-family:="" 宋体,bold?;="" 0pt;="" verdana?="">Expression.ge </span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">对应</span><span mso-font-kerning:="" mso-bidi-font-family:="" 宋体,bold?;="" 0pt;="" verdana?="">SQL</span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">中的 </span><span mso-font-kerning:="" mso-bidi-font-family:="" 宋体,bold?;="" 0pt;="" verdana?="">&#8220;field &gt;= value&#8221; </span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">表达式<span> </span></span></p>
<p>
<p align=left><span mso-font-kerning:="" mso-bidi-font-family:="" 宋体,bold?;="" 0pt;="" verdana?="">Expression.lt </span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">对应</span><span mso-font-kerning:="" mso-bidi-font-family:="" 宋体,bold?;="" 0pt;="" verdana?="">SQL</span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">中的 </span><span mso-font-kerning:="" mso-bidi-font-family:="" 宋体,bold?;="" 0pt;="" verdana?="">&#8220;field &lt; value&#8221; </span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">表达式<span> </span></span></p>
<p>
<p align=left><span mso-font-kerning:="" mso-bidi-font-family:="" 宋体,bold?;="" 0pt;="" verdana?="">Expression.le </span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">对应</span><span mso-font-kerning:="" mso-bidi-font-family:="" 宋体,bold?;="" 0pt;="" verdana?="">SQL</span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">中的 </span><span mso-font-kerning:="" mso-bidi-font-family:="" 宋体,bold?;="" 0pt;="" verdana?="">&#8220;field &lt;= value&#8221; </span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">表达式<span> </span></span></p>
<p>
<p align=left><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">Expression.between </span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">对应</span><span mso-font-kerning:="" mso-bidi-font-family:="" 宋体,bold?;="" 0pt;="" verdana?="">SQL</span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">中的 </span><span mso-font-kerning:="" mso-bidi-font-family:="" 宋体,bold?;="" 0pt;="" verdana?="">&#8220;between&#8221; </span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">表达式<span> </span></span></p>
<p>
<p align=left><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">如下面的表达式表示年龄（</span><span mso-font-kerning:="" mso-bidi-font-family:="" 宋体,bold?;="" 0pt;="" verdana?="">age</span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">）位于</span><span mso-font-kerning:="" mso-bidi-font-family:="" 宋体,bold?;="" 0pt;="" verdana?="">13</span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">到</span><span mso-font-kerning:="" mso-bidi-font-family:="" 宋体,bold?;="" 0pt;="" verdana?="">50</span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">区<span> </span></span></p>
<p>
<p align=left><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">间内。<span> </span></span></p>
<p>
<p align=left><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">Expression.between(</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">"age"</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">,</span><strong><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">new </span></strong></p>
<p>
<p align=left><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">Integer(13),</span><strong><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">new </span></strong><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">Integer(50)); </span></p>
<p>
<p align=left><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">表达式<span> </span></span></p>
<p>
<p align=left><span mso-font-kerning:="" mso-bidi-font-family:="" 宋体,bold?;="" 0pt;="" verdana?="">Expression.in </span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">对应</span><span mso-font-kerning:="" mso-bidi-font-family:="" 宋体,bold?;="" 0pt;="" verdana?="">SQL</span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">中的 </span><span mso-font-kerning:="" mso-bidi-font-family:="" 宋体,bold?;="" 0pt;="" verdana?="">&#8221;field in &#8230;&#8221; </span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">表达式<span> </span></span></p>
<p>
<p align=left><span mso-font-kerning:="" mso-bidi-font-family:="" 宋体,bold?;="" 0pt;="" verdana?="">Expression.eqProperty </span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">用于比较两个属性之间的值，对应</span><span mso-font-kerning:="" mso-bidi-font-family:="" 宋体,bold?;="" 0pt;="" verdana?="">SQL</span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">中的&#8220;</span><span mso-font-kerning:="" mso-bidi-font-family:="" 宋体,bold?;="" 0pt;="" verdana?="">field </span></p>
<p>
<p align=left><span mso-font-kerning:="" mso-bidi-font-family:="" 宋体,bold?;="" 0pt;="" verdana?="">= field</span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">&#8221;。<span> </span></span></p>
<p>
<p align=left><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">如：<span> </span></span></p>
<p>
<p align=left><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">Expression.eqProperty( </span></p>
<p>
<p align=left><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">"TUser.groupID"</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">, </span></p>
<p>
<p align=left><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">"TGroup.id" </span></p>
<p>
<p align=left><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">); </span></p>
<p>
<p align=left><span mso-font-kerning:="" mso-bidi-font-family:="" 宋体,bold?;="" 0pt;="" verdana?="">Expression.gtProperty </span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">用于比较两个属性之间的值，对应</span><span mso-font-kerning:="" mso-bidi-font-family:="" 宋体,bold?;="" 0pt;="" verdana?="">SQL</span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">中的&#8220;</span><span mso-font-kerning:="" mso-bidi-font-family:="" 宋体,bold?;="" 0pt;="" verdana?="">field </span></p>
<p>
<p align=left><span mso-font-kerning:="" mso-bidi-font-family:="" 宋体,bold?;="" 0pt;="" verdana?="">&gt; field</span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">&#8221;。<span> </span></span></p>
<p>
<p align=left><span mso-font-kerning:="" mso-bidi-font-family:="" 宋体,bold?;="" 0pt;="" verdana?="">Expression.geProperty </span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">用于比较两个属性之间的值，对应</span><span mso-font-kerning:="" mso-bidi-font-family:="" 宋体,bold?;="" 0pt;="" verdana?="">SQL</span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">中的&#8220;</span><span mso-font-kerning:="" mso-bidi-font-family:="" 宋体,bold?;="" 0pt;="" verdana?="">field </span></p>
<p>
<p align=left><span mso-font-kerning:="" mso-bidi-font-family:="" 宋体,bold?;="" 0pt;="" verdana?="">&gt;= field</span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">&#8221;。<span> </span></span></p>
<p>
<p align=left><span mso-font-kerning:="" mso-bidi-font-family:="" 宋体,bold?;="" 0pt;="" verdana?="">Expression.ltProperty </span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">用于比较两个属性之间的值，对应</span><span mso-font-kerning:="" mso-bidi-font-family:="" 宋体,bold?;="" 0pt;="" verdana?="">SQL</span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">中的&#8220;</span><span mso-font-kerning:="" mso-bidi-font-family:="" 宋体,bold?;="" 0pt;="" verdana?="">field </span></p>
<p>
<p align=left><span mso-font-kerning:="" mso-bidi-font-family:="" 宋体,bold?;="" 0pt;="" verdana?="">&lt; field</span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">&#8221;。<span> </span></span></p>
<p>
<p align=left><span mso-font-kerning:="" mso-bidi-font-family:="" 宋体,bold?;="" 0pt;="" verdana?="">Expression.leProperty </span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">用于比较两个属性之间的值，对应</span><span mso-font-kerning:="" mso-bidi-font-family:="" 宋体,bold?;="" 0pt;="" verdana?="">SQL</span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">中的&#8220;</span><span mso-font-kerning:="" mso-bidi-font-family:="" 宋体,bold?;="" 0pt;="" verdana?="">field </span></p>
<p>
<p align=left><span mso-font-kerning:="" mso-bidi-font-family:="" 宋体,bold?;="" 0pt;="" verdana?="">&lt;= field</span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">&#8221;。<span> </span></span></p>
<p>
<p align=left><span mso-font-kerning:="" mso-bidi-font-family:="" 宋体,bold?;="" 0pt;="" verdana?="">Expression.and and</span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">关系组合。<span> </span></span></p>
<p>
<p align=left><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">如：<span> </span></span></p>
<p>
<p align=left><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">Expression.and( </span></p>
<p>
<p align=left><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">Expression.eq(</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">"name"</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">,</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">"Erica"</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">), </span></p>
<p>
<p align=left><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">Expression.eq( </span></p>
<p>
<p align=left><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">"sex"</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">, </span></p>
<p>
<p align=left><strong><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">new </span></strong><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">Integer(1) </span></p>
<p>
<p align=left><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">) </span></p>
<p>
<p align=left><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">); </span></p>
<p>
<p align=left><span mso-font-kerning:="" mso-bidi-font-family:="" 宋体,bold?;="" 0pt;="" verdana?="">Expression.or or</span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">关系组合。<span> </span></span></p>
<p>
<p align=left><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">如：<span> </span></span></p>
<p>
<p align=left><span mso-font-kerning:="" 0pt?="" 宋体,bold?;="">Hibernate Developer&#8217;s Guide Version 1.0 </span></p>
<p>
<p align=left><span mso-font-kerning:="" 0pt?="" 宋体,bold?;="">September 2, 2004 </span><span mso-font-kerning:="" 0pt?="" 宋体,bold?;="">So many open source projects. Why not <strong>Open </strong>your <strong>Doc</strong>uments? </span></p>
<p>
<p align=left><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">Expression.or( </span></p>
<p>
<p align=left><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">Expression.eq(</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">"name"</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">,</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">"Erica"</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">), </span></p>
<p>
<p align=left><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">Expression.eq(</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">"name"</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">,</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">"Emma"</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">) </span></p>
<p>
<p align=left><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">); </span></p>
<p>
<p align=left><span mso-font-kerning:="" mso-bidi-font-family:="" 宋体,bold?;="" 0pt;="" verdana?="">Expression.sql </span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">作为补充，本方法提供了原生</span><span mso-font-kerning:="" mso-bidi-font-family:="" 宋体,bold?;="" 0pt;="" verdana?="">SQL</span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">语法的支持。我<span> </span></span></p>
<p>
<p align=left><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">们可以通过这个方法直接通过</span><span mso-font-kerning:="" mso-bidi-font-family:="" 宋体,bold?;="" 0pt;="" verdana?="">SQL</span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">语句限定查询<span> </span></span></p>
<p>
<p align=left><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">条件。<span> </span></span></p>
<p>
<p align=left><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">下面的代码返回所有名称以&#8220;</span><span mso-font-kerning:="" mso-bidi-font-family:="" 宋体,bold?;="" 0pt;="" verdana?="">Erica</span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">&#8221;起始的记录：<span> </span></span></p>
<p>
<p align=left><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">Expression.sql( </span></p>
<p>
<p align=left><span>&#8220;</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">lower({alias}.name) like lower(?)</span><span>&#8221;</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">, </span></p>
<p>
<p align=left><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">"Erica%"</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">, </span></p>
<p>
<p align=left><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">Hibernate.STRING </span></p>
<p>
<p align=left><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">); </span></p>
<p>
<p align=left><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">其中的&#8220;</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">{alias}</span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">&#8221;将由</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">Hibernate</span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">在运行期使<span> </span></span></p>
<p>
<p align=left><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">用当前关联的</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">POJO</span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">别名替换。<span> </span></span></p>
<p>
<p align=left><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">注意</span><span mso-font-kerning:="" mso-bidi-font-family:="" 宋体,bold?;="" 0pt;="" verdana?="">Expression </span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">各方法中的属性名参数（如</span><span mso-font-kerning:="" mso-bidi-font-family:="" 宋体,bold?;="" 0pt;="" verdana?="">Express.eq</span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">中的第一个参数），这里<span> </span></span></p>
<p>
<p align=left><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">所谓属性名是</span><span mso-font-kerning:="" mso-bidi-font-family:="" 宋体,bold?;="" 0pt;="" verdana?="">POJO</span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">中对应实际库表字段的属性名（大小写敏感），而非库表中的实<span> </span></span></p>
<p>
<p align=left><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">际字段名称。<span> </span></span></p>
<p>
<p align=left><strong><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">Criteria </span></strong><strong><span 宋体,bold??="">高级特性<span> </span></span></strong></p>
<p>
<p align=left><strong><span 宋体,bold??="">限定返回的记录范围<span> </span></span></strong></p>
<p>
<p align=left><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">通过</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">criteria. setFirstResult/setMaxResults </span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">方法可以限制一次查询返回<span> </span></span></p>
<p>
<p align=left><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">的记录范围</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">: </span></p>
<p>
<p align=left><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">Criteria criteria = session.createCriteria(TUser.</span><strong><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">class</span></strong><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">); </span></p>
<p>
<p align=left><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">//</span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">限定查询返回检索结果中，从第一百条结果开始的</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">20</span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">条记录<span> </span></span></p>
<p>
<p align=left><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">criteria.setFirstResult(100); </span></p>
<p>
<p align=left><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">criteria.setMaxResults(20); </span></p>
<p>
<p align=left><strong><span 宋体,bold??="">对查询结果进行排序<span> </span></span></strong></p>
<p>
<p align=left><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">//</span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">查询所有</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">groupId=2</span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">的记录<span> </span></span></p>
<p>
<p align=left><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">//</span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">并分别按照姓名</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">(</span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">顺序</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">)</span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">和</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">groupId</span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">（逆序）排序<span> </span></span></p>
<p>
<p align=left><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">Criteria criteria = session.createCriteria(TUser.</span><strong><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">class</span></strong><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">); </span></p>
<p>
<p align=left><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">criteria.add(Expression.eq(</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">"groupId"</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">,</span><strong><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">new </span></strong><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">Integer(2))); </span></p>
<p>
<p align=left><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">criteria.addOrder(Order.asc(</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">"name"</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">)); </span></p>
<p>
<p align=left><span mso-font-kerning:="" 0pt?="" 宋体,bold?;="">Hibernate Developer&#8217;s Guide Version 1.0 </span></p>
<p>
<p align=left><span mso-font-kerning:="" 0pt?="" 宋体,bold?;="">September 2, 2004 </span><span mso-font-kerning:="" 0pt?="" 宋体,bold?;="">So many open source projects. Why not <strong>Open </strong>your <strong>Doc</strong>uments? </span></p>
<p>
<p align=left><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">criteria.addOrder(Order.desc(</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">"groupId"</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">)); </span></p>
<p>
<p align=left><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">Criteria</span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">作为一种对象化的查询封装模式，不过由于</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">Hibernate</span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">在实现过程中将精力<span> </span></span></p>
<p>
<p align=left><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">更加集中在</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">HQL</span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">查询语言上，因此</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">Criteria</span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">的功能实现还没做到尽善尽美（这点上，</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">OJB </span></p>
<p>
<p align=left><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">的</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">Criteria </span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">实现倒是值得借鉴），因此，在实际开发中，建议还是采用</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">Hibernate </span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">官<span> </span></span></p>
<p>
<p align=left><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">方推荐的查询封装模式：</span><span courier="" new?;="" mso-fareast-font-family:="" ?宋体,bold?;="" mso-font-kerning:="" 0pt?="">HQL</span><span times="" new="" roman?;="" mso-bidi-font-family:="" 宋体?="">。</span></p>
<img src ="http://www.blogjava.net/WshmAndLily/aggbug/135372.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/WshmAndLily/" target="_blank">semovy</a> 2007-08-08 23:00 <a href="http://www.blogjava.net/WshmAndLily/articles/135372.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>criteria与detachedcriteria </title><link>http://www.blogjava.net/WshmAndLily/articles/135363.html</link><dc:creator>semovy</dc:creator><author>semovy</author><pubDate>Wed, 08 Aug 2007 14:28:00 GMT</pubDate><guid>http://www.blogjava.net/WshmAndLily/articles/135363.html</guid><wfw:comment>http://www.blogjava.net/WshmAndLily/comments/135363.html</wfw:comment><comments>http://www.blogjava.net/WshmAndLily/articles/135363.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/WshmAndLily/comments/commentRss/135363.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/WshmAndLily/services/trackbacks/135363.html</trackback:ping><description><![CDATA[<p>最近在项目中使用 spring 和 hibernate <a id=vad_0 onmouseover="if(typeof(showTitle)!='undefined'){this.title='';window.clearTimeout(hideTO);showTitle(event, this, 0,'');}" title="" onclick="" onmouseout="if(typeof(showTitle)!='undefined'){mouseIsOverLayer = false; mouseOverWhileLoad = false; hideTO = window.setTimeout('checkIfMouseOverLayer()',500);}" href="http://action.vogate.com/click/click.php?ads_id=3614&amp;site_id=6235007045037850&amp;click=1&amp;url=http%3A//www.renai.cn/tj/&amp;v=0&amp;k=%u8FDB%u884C&amp;s=http%3A//www.readygo.com.cn/javaadv/070127/020335I1Nx.htm&amp;rn=645747" target=_blank>进行</a>开发，有感于 criteria 比较好用，在查询方法设计上可以<a id=vad_1 onmouseover="if(typeof(showTitle)!='undefined'){this.title='';window.clearTimeout(hideTO);showTitle(event, this, 1,'');}" title="" onclick="" onmouseout="if(typeof(showTitle)!='undefined'){mouseIsOverLayer = false; mouseOverWhileLoad = false; hideTO = window.setTimeout('checkIfMouseOverLayer()',500);}" href="http://action.vogate.com/click/click.php?ads_id=1279&amp;site_id=6235007045037850&amp;click=1&amp;url=http%3A//www.boc.cn/cn/common/third_city_card.jsp%3Fcategory%3D1165196149100&amp;v=0&amp;k=%u7075%u6D3B&amp;s=http%3A//www.readygo.com.cn/javaadv/070127/020335I1Nx.htm&amp;rn=309744" target=_blank>灵活</a>的根据 criteria 的特点来<a id=vad_6 onmouseover="if(typeof(showTitle)!='undefined'){this.title='';window.clearTimeout(hideTO);showTitle(event, this, 6,'');}" title="" onclick="" onmouseout="if(typeof(showTitle)!='undefined'){mouseIsOverLayer = false; mouseOverWhileLoad = false; hideTO = window.setTimeout('checkIfMouseOverLayer()',500);}" href="http://action.vogate.com/click/click.php?ads_id=3473&amp;site_id=6235007045037850&amp;click=1&amp;url=http%3A//allyesshafa.allyes.com/main/adfclick%3Fdb%3Dallyesshafa%26bid%3D6018%2C3003%2C125%26cid%3D1978%2C142%2C1%26sid%3D6330%26show%3Dignore%26url%3Dhttp%3A//ad.benq.com.cn/products/harddisk/200706/%20&amp;v=0&amp;k=%u65B9%u4FBF&amp;s=http%3A//www.readygo.com.cn/javaadv/070127/020335I1Nx.htm&amp;rn=943767" target=_blank>方便</a>地进行查询条件的组装。所以现在对 hibernate 的 criteria 深入研究一下。《 hibernate reference 》及网上其它一些资料对 criteria 已经做了很多介绍。本文主要是从 criteria 的结构入手来进行分析。
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 如图 1 。 hibernate 设计了 criteriaspecification 作为 criteria 的顶级接口，其下面提供了 criteria 和 detachedcriteria 。 </p>
<p>criteria 和 detachedcriteria 的主要区别在于创建的形式不一样， criteria 是<a id=vad_8 onmouseover="if(typeof(showTitle)!='undefined'){this.title='';window.clearTimeout(hideTO);showTitle(event, this, 8,'');}" title="光于华夏2 @Vogate.com" onclick="" onmouseout="if(typeof(showTitle)!='undefined'){mouseIsOverLayer = false; mouseOverWhileLoad = false; hideTO = window.setTimeout('checkIfMouseOverLayer()',500);}" href="http://action.vogate.com/click/click.php?ads_id=3505&amp;site_id=6235007045037850&amp;click=1&amp;url=http%3A//news.gyyx.cn/counter.ashx%3Fposition_id%3D28%26class_id%3D2%26page_id%3D2%26source_id%3D5%26game_id%3D1&amp;v=0&amp;k=%u5728%u7EBF&amp;s=http%3A//www.readygo.com.cn/javaadv/070127/020335I1Nx.htm&amp;rn=246811" target=_blank>在线</a>的，所以它是由 hibernate session 进行创建的；而 detachedcriteria 是离线的，创建时无需 session ， detachedcriteria 提供了 4 个静态方法 forclass(class) 或 forentityname(name) 进行 detachedcriteria 实例的创建。 spring 的框架提供了 </p>
<p>gethibernatetemplate().findbycriteria(detachedcriteria) 方法可以很方便地根据 </p>
<p>detachedcriteria 来返回查询结果。 </p>
<p>如图 1 ， criteria 和 detachedcriteria 均可使用 criterion 和 projection 设置查询条件。可以设置 fetchmode( 联合查询抓取的模式 ) ，设置排序方式。对于 criteria 还可以设置 flushmodel （冲刷 session 的方式）和 lockmode （数据库锁模式）。 </p>
<p>下面就对 criterion 和 projection 进行详细说明。 </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </p>
<p align=center>图 1 </p>
<p>&nbsp; </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; criterion 是 criteria 的查询条件。 </p>
<p>criteria 提供了 add(criterion criterion) 方法来添加查询条件。图 2 是 criterion 的结构图。 criterion 接口的主要<a id=vad_9 onmouseover="if(typeof(showTitle)!='undefined'){this.title='';window.clearTimeout(hideTO);showTitle(event, this, 9,'');}" title="" onclick="" onmouseout="if(typeof(showTitle)!='undefined'){mouseIsOverLayer = false; mouseOverWhileLoad = false; hideTO = window.setTimeout('checkIfMouseOverLayer()',500);}" href="http://action.vogate.com/click/click.php?ads_id=2950&amp;site_id=6235007045037850&amp;click=1&amp;url=http%3A//www.5460.net&amp;v=0&amp;k=%u5B9E%u73B0&amp;s=http%3A//www.readygo.com.cn/javaadv/070127/020335I1Nx.htm&amp;rn=797638" target=_blank>实现</a>包括： example 、 junction 和 simpleexpression 。而 junction 的实际使用是它的两个子类 conjunction 和 disjunction ，分别是使用 and 和 or 操作符进行来联结查询条件集合。 </p>
<p>criterion 的实例可以通过 restrictions 工具类来创建， restrictions 提供了大量的静态方法，如 eq （等于）、 ge （大于等于）、 between 等来方法的创建 criterion 查询条件 </p>
<p>（ simpleexpression 实例）。除此之外， restrictions 还提供了方法来创建 conjunction 和 disjunction 实例，通过往该实例的 add(criteria) 方法来增加查询条件形成一个查询条件集合。 </p>
<p>至于 example 的创建有所不同， example 本身提供了一个静态方法 create(object entity) ，即根据一个对象（实际使用中一般是映射到数据库的对象）来创建。然后可以设置一些过滤条件： </p>
<p>example exampleuser =example.create(u) </p>
<p>.ignorecase() // 忽略大小写 </p>
<p>.enablelike(matchmode.anywhere); </p>
<p>// 对 string 类型的属性，无论在那里值在那里都匹配。相当于 %value% </p>
<p>&#160;</p>
<p align=center><br>图 2 </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </p>
<p>project 主要是让 criteria 能够进行报表查询，并可以实现分组。 project 主要有 simpleprojection 、 projectionlist 和 property 三个实现。其中 simpleprojection 和 projectionlist 的实例化是由内建的 projections 来完成，如提供的 avg 、 count 、 max 、 min 、 sum 可以让开发者很容易对某个字段进行统计查询。 </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; property 是对某个字段进行查询条件的设置，如通过 </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; porperty.forname(&#8220;color&#8221;).in(new string[]{&#8220;black&#8221;,&#8221;red&#8221;,&#8221;write&#8221;}); 则可以创建一个 project 实例。通过 criteria 的 add(project) 方法加入到查询条件中去。 </p>
<p>&#160;</p>
<p align=center><br>图 3 </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 使用 criteria 进行查询，主要要<a id=vad_4 onmouseover="if(typeof(showTitle)!='undefined'){this.title='';window.clearTimeout(hideTO);showTitle(event, this, 4,'');}" title="" onclick="" onmouseout="if(typeof(showTitle)!='undefined'){mouseIsOverLayer = false; mouseOverWhileLoad = false; hideTO = window.setTimeout('checkIfMouseOverLayer()',500);}" href="http://action.vogate.com/click/click.php?ads_id=1275&amp;site_id=6235007045037850&amp;click=1&amp;url=http%3A//www.sony.com.cn/electronics/bravia2006/redirect/redirect_sina.asp&amp;v=0&amp;k=%u6E05%u6670&amp;s=http%3A//www.readygo.com.cn/javaadv/070127/020335I1Nx.htm&amp;rn=84140" target=_blank>清晰</a>的是 hibernate 提供了那些类和方法来满足开发中查询条件的创建和组装，其结构层次如何。这样使用起来便可得心应手。 </p>
<img src ="http://www.blogjava.net/WshmAndLily/aggbug/135363.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/WshmAndLily/" target="_blank">semovy</a> 2007-08-08 22:28 <a href="http://www.blogjava.net/WshmAndLily/articles/135363.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>DetachedCriteria</title><link>http://www.blogjava.net/WshmAndLily/articles/135273.html</link><dc:creator>semovy</dc:creator><author>semovy</author><pubDate>Wed, 08 Aug 2007 08:28:00 GMT</pubDate><guid>http://www.blogjava.net/WshmAndLily/articles/135273.html</guid><wfw:comment>http://www.blogjava.net/WshmAndLily/comments/135273.html</wfw:comment><comments>http://www.blogjava.net/WshmAndLily/articles/135273.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/WshmAndLily/comments/commentRss/135273.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/WshmAndLily/services/trackbacks/135273.html</trackback:ping><description><![CDATA[<div id=conbox>
<div id=conleft>
<div id=conneirong><span id=ad3></span>
<div class=guanggao><span id=contentAdv></span></div>
<font style="DISPLAY: none; VISIBILITY: hidden"><a href="http://www1.99118.com/total.asp?id=6687" target=_blank></a></font>　　Hibernate3支持DetachedCriteria，这是一个非常有意义的特性！我们知道，在常规的Web编程中，有大量的动态条件查询，即用户在网页上面自由选择某些条件，程序根据用户的选择条件，动态生成SQL语句，进行查询。 <br><br>　　针对这种需求，对于分层应用程序来说，Web层需要传递一个查询的条件列表给业务层对象，业务层对象获得这个条件列表之后，然后依次取出条件，构造查询语句。这里的一个难点是条件列表用什么来构造？传统上使用Map，但是这种方式缺陷很大，Map可以传递的信息非常有限，只能传递name和value，无法传递究竟要做怎样的条件运算，究竟是大于，小于，like，还是其它的什么，业务层对象必须确切掌握每条entry的隐含条件。因此一旦隐含条件改变，业务层对象的查询构造算法必须相应修改，但是这种查询条件的改变是隐式约定的，而不是程序代码约束的，因此非常容易出错。 <br><br>　　DetachedCriteria可以解决这个问题，即在web层，程序员使用DetachedCriteria来构造查询条件，然后将这个DetachedCriteria作为方法调用参数传递给业务层对象。而业务层对象获得DetachedCriteria之后，可以在session范围内直接构造Criteria，进行查询。就此，查询语句的构造完全被搬离到web层实现，而业务层则只负责完成持久化和查询的封装即可，与查询条件构造完全解耦，非常完美！这恐怕也是以前很多企图在web层代码中构造HQL语句的人想实现的梦想吧！ <br><br>　　示例代码片段如下： <br><br>　　web层程序构造查询条件： <br><br>　　java代码: <br><br>
<table borderColor=#ffcc66 width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Department.class); <br>detachedCriteria.add(Restrictions.eq("name", "department")).createAlias("employees", "e").add(Restrictions.gt(("e.age"), new Integer(20)));</td>
        </tr>
    </tbody>
</table>
<br>　　Department和Employee是一对多关联，查询条件为： <br><br>　　名称是&#8220;department&#8221;开发部门； <br>　　部门里面的雇员年龄大于20岁； <br><br>　　业务层对象使用该条件执行查询： <br><br>　　java代码: <br><br>
<table borderColor=#ffcc66 width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>detachedCriteria.getExecutableCriteria(session).list();</td>
        </tr>
    </tbody>
</table>
<br>　　最大的意义在于，业务层代码是固定不变的，所有查询条件的构造都在web层完成，业务层只负责在session内执行之。这样代码就可放之四海而皆准，都无须修改了。<br><br>　　然而Spring和Hibernate3的DetachedCriteria有不兼容的问题，因此在Spring环境下面使用Hibernate3需要注意： <br><br>　　Spring的HibernateTemplate提供了Hibernate的完美封装，即通过匿名类实现回调，来保证Session的自动资源管理和事务的管理。其中核心方法是： <br><br>　　java代码: <br><br>
<table borderColor=#ffcc66 width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>HibernateTemplate.execute(new HibernateCallback() { <br>　public Object doInHibernate(Session session) throws HibernateException { <br>　　.... <br>　} <br>}</td>
        </tr>
    </tbody>
</table>
<br>　　回调方法提供了session作为参数，有了session，就可以自由的使用Hibernate API编程了。使用了spring的之后，代码修改如下： <br><strong><br></strong>　　web层代码： <br><br>　　java代码: <br><br>
<table borderColor=#ffcc66 width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Department.class); <br>detachedCriteria.createAlias("employees", "e").add(Restrictions.eq("name", "department")).add(Restrictions.gt(("e.age"), new Integer(20))); <br>departmentManager.findByCriteria(detachedCriteria);</td>
        </tr>
    </tbody>
</table>
<br>　　构造detachedCriteria，作为参数传递给departmentManager <br><br>　　业务层代码使用spring，DepartmentManager的findByCriteria如下： <br><br>　　java代码: <br><br>
<table borderColor=#ffcc66 width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>public List findByCriteria(final DetachedCriteria detachedCriteria) { <br>　return (List) getHibernateTemplate().execute(new HibernateCallback() { <br>　　public Object doInHibernate(Session session) throws HibernateException { <br>　　　Criteria criteria = detachedCriteria.getExecutableCriteria(session); <br>　　　return criteria.list(); <br>　　} <br>　}); <br>}</td>
        </tr>
    </tbody>
</table>
<br>　　实际上也就是： <br><br>　　java代码: <br><br>
<table borderColor=#ffcc66 width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>Criteria criteria = detachedCriteria.getExecutableCriteria(session); <br>return criteria.list(); </td>
        </tr>
    </tbody>
</table>
<br>　　而已 <br><br>　　但是该程序代码执行，会抛出强制类型转换异常！ <br><br>　　我跟踪了一下spring和Hibernate源代码，原因如下： <br><br>　　spring的HibernateTemplate的execute方法提供的回调接口具有Session作为参数，但是实际上，默认情况下，HibernateTemplate传递给回调接口的session并不是org.hibernate.impl.SessionImpl类，而是SessionImpl类的一个Proxy类。之所以替换成为一个Proxy类，HibernateTemplate的注释说明，Proxy提供了一些额外的功能，包括自动设置Cachable，Transaction的超时时间，Session资源的更积极的关闭等等。 <br><br>　　java代码: <br><br>
<table borderColor=#ffcc66 width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>private boolean exposeNativeSession = false; <br>... </td>
        </tr>
    </tbody>
</table>
<br>　　execute方法内部： <br><br>
<table borderColor=#ffcc66 width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>Session sessionToExpose = (exposeNativeSession ? session : createSessionProxy(session));</td>
        </tr>
    </tbody>
</table>
<br>　　但是遗憾的是，Hibernate的DetachedCriteria的setExecutableCriteria方法却要求将session参数强制转为SessionImpl，但是spring传过来的却是一个Proxy类，因此就报错了。 <br><br>　　java代码: <br><br>
<table borderColor=#ffcc66 width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>public Criteria getExecutableCriteria(Session session) { <br>　impl.setSession( (SessionImpl) session ); // 要求SessionImpl，Spring传递的是Proxy <br>　return impl; <br>}</td>
        </tr>
    </tbody>
</table>
<br>　　解决方法，禁止Spring的HibernateTemplate传递Proxy类，强制要求它传递真实的SessionImpl类，即给exexute方法增加一个参数，提供参数为true，如下： <br><br>　　java代码: <br><br>
<table borderColor=#ffcc66 width="90%" align=center bgColor=#e3e3e3 border=1>
    <tbody>
        <tr>
            <td>public List findByCriteria(final DetachedCriteria detachedCriteria) { <br>　return (List) getHibernateTemplate().execute(new HibernateCallback() { <br>　　public Object doInHibernate(Session session) throws HibernateException { <br>　　　Criteria criteria = detachedCriteria.getExecutableCriteria(session); <br>　　　return criteria.list(); <br>　　} <br>　}, true); <br>}</td>
        </tr>
    </tbody>
</table>
</div>
</div>
</div>
<img src ="http://www.blogjava.net/WshmAndLily/aggbug/135273.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/WshmAndLily/" target="_blank">semovy</a> 2007-08-08 16:28 <a href="http://www.blogjava.net/WshmAndLily/articles/135273.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>MyEclipse4.1+hibernate3.05+mySql5.0开发J2EE入门</title><link>http://www.blogjava.net/WshmAndLily/articles/80216.html</link><dc:creator>semovy</dc:creator><author>semovy</author><pubDate>Thu, 09 Nov 2006 09:49:00 GMT</pubDate><guid>http://www.blogjava.net/WshmAndLily/articles/80216.html</guid><wfw:comment>http://www.blogjava.net/WshmAndLily/comments/80216.html</wfw:comment><comments>http://www.blogjava.net/WshmAndLily/articles/80216.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/WshmAndLily/comments/commentRss/80216.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/WshmAndLily/services/trackbacks/80216.html</trackback:ping><description><![CDATA[
		<p>一、在MySql5.0中建数据库Test与Employee表<br />create database Test;<br />use Test;<br />create table employee<br />(<br />      id int(11) primary key not null ,<br />      name varcahr(50) not null<br />);<br />二、<br />1、在MyEclipse4.1中新建Web-Project 名为myWeb.<br />2、选择MyEclipse选项的Add Hibernate Capabilities,以使web应用具有hibernate性能，<br />在配置对话框的最下面的选项应选择Copy checked Library Jars to project floder and add to build-path.<br />这样项目就添加了HibernateSessionFactory的类，与及hibernate的core jar包和在classes下的hibernate.cfg.xml。<br />(1)hibernate 核心jar包应该包含:<br />hibernate3.jar<br />ehcache-1.1.jar <br />,antlr-2.7.5H3.jar<br />asm.jar<br />jta.jar<br />commons-logging-1.0.4.jar<br />asm-attrs.jar<br /><br />(2).HibernateSessionFactory系统自动类产生的，不可继承的，其方法是静态的，直接使用，不用实例化。<br /><br />package com.semovy.framework.base;</p>
		<p>import org.hibernate.HibernateException;<br />import org.hibernate.Session;<br />import org.hibernate.cfg.Configuration;</p>
		<p>/**<br /> * Configures and provides access to Hibernate sessions, tied to the<br /> * current thread of execution.  Follows the Thread Local Session<br /> * pattern, see <a href="mailto:{@link">{@link</a><a href="http://hibernate.org/42.html">http://hibernate.org/42.html</a>}.<br /> */<br />public class HibernateSessionFactory{</p>
		<p>    /** <br />     * Location of hibernate.cfg.xml file.<br />     * NOTICE: Location should be on the classpath as Hibernate uses<br />     * #resourceAsStream style lookup for its configuration file. That<br />     * is place the config file in a Java package - the default location<br />     * is the default Java package.&lt;br&gt;&lt;br&gt;<br />     * Examples: &lt;br&gt;<br />     * &lt;code&gt;CONFIG_FILE_LOCATION = "/hibernate.conf.xml". <br />     * CONFIG_FILE_LOCATION = "/com/foo/bar/myhiberstuff.conf.xml".&lt;/code&gt; <br />     */<br />    private static String CONFIG_FILE_LOCATION = "/hibernate.cfg.xml";</p>
		<p>    /** Holds a single instance of Session */<br /> private static final ThreadLocal threadLocal = new ThreadLocal();</p>
		<p>    /** The single instance of hibernate configuration */<br />    private static final Configuration cfg = new Configuration();</p>
		<p>    /** The single instance of hibernate SessionFactory */<br />    private static org.hibernate.SessionFactory sessionFactory;</p>
		<p>    /**<br />     * Returns the ThreadLocal Session instance.  Lazy initialize<br />     * the &lt;code&gt;SessionFactory&lt;/code&gt; if needed.<br />     *<br />     *  @return Session<br />     *  @throws HibernateException<br />     */<br />    public static Session currentSession() throws HibernateException {<br />        Session session = (Session) threadLocal.get();</p>
		<p>  if (session == null || !session.isOpen()) {<br />   if (sessionFactory == null) {<br />    try {<br />     cfg.configure(CONFIG_FILE_LOCATION);<br />     sessionFactory = cfg.buildSessionFactory();<br />    } catch (Exception e) {<br />     System.err<br />       .println("%%%% Error Creating SessionFactory %%%%");<br />     e.printStackTrace();<br />    }<br />   }<br />   session = (sessionFactory != null) ? sessionFactory.openSession()<br />     : null;<br />   threadLocal.set(session);<br />  }</p>
		<p>        return session;<br />    }</p>
		<p>    /**<br />     *  Close the single hibernate session instance.<br />     *<br />     *  @throws HibernateException<br />     */<br />    public static void closeSession() throws HibernateException {<br />        Session session = (Session) threadLocal.get();<br />        threadLocal.set(null);</p>
		<p>        if (session != null) {<br />            session.close();<br />        }<br />    }</p>
		<p>    /**<br />     * Default constructor.<br />     */<br />    private HibernateSession() {<br />    }</p>
		<p>}<br />(3).自动在classes下产生hibernate.cfg.xml配置文件<br />&lt;?xml version='1.0' encoding='UTF-8'?&gt;<br />&lt;!DOCTYPE hibernate-configuration PUBLIC<br />          "-//Hibernate/Hibernate Configuration DTD 3.0//EN"<br />          "<a href="http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd</a>"&gt;</p>
		<p>&lt;!-- Generated by MyEclipse Hibernate Tools.                   --&gt;<br />&lt;hibernate-configuration&gt;</p>
		<p> &lt;session-factory&gt;<br />  &lt;property name="connection.username"&gt;root&lt;/property&gt;<br />  &lt;property name="connection.url"&gt;jdbc:mysql://localhost:3306/test?useUnicode=true;characterEncoding=gbk&lt;/property&gt;<br />  &lt;property name="dialect"&gt;org.hibernate.dialect.MySQLDialect&lt;/property&gt;<br />  &lt;property name="myeclipse.connection.profile"&gt;MySqlDB&lt;/property&gt;<br />  &lt;property name="connection.password"&gt;1234&lt;/property&gt;<br />  &lt;property name="connection.driver_class"&gt;com.mysql.jdbc.Driver&lt;/property&gt;<br />  &lt;mapping resource="com/semovy/business/pojo/Employee.hbm.xml" /&gt;&lt;!--对应对象映射文件资源--&gt;.</p>
		<p> &lt;/session-factory&gt;</p>
		<p>&lt;/hibernate-configuration&gt;<br />三、打开MyEclipse的DB Browser选择Employee右击creating hibernate mapping,设置持久类路径好之后。<br />便自动产生Employee持久类，与同一目录下的Employee.hbm.xml两个文件<br /><br />1).<br />package com.semovy.business.pojo;</p>
		<p> </p>
		<p>/**<br /> * Employee generated by MyEclipse - Hibernate Tools<br /> */</p>
		<p>public class Employee  implements java.io.Serializable {</p>
		<p>
				<br />    // Fields    </p>
		<p>     /**<br />  * <br />  */<br /> private static final long serialVersionUID = 1L;<br /> private Integer id;<br />     private String name;</p>
		<p>
				<br />    // Constructors</p>
		<p>    /** default constructor */<br />    public Employee() {<br />    }</p>
		<p> /** minimal constructor */<br />    public Employee(Integer id) {<br />        this.id = id;<br />    }<br />    <br />    /** full constructor */<br />    public Employee(Integer id, String name) {<br />        this.id = id;<br />        this.name = name;<br />    }<br />    // Property accessors</p>
		<p>    public Integer getId() {<br />        return this.id;<br />    }<br />    <br />    public void setId(Integer id) {<br />        this.id = id;<br />    }</p>
		<p>    public String getName() {<br />        return this.name;<br />    }<br />    <br />    public void setName(String name) {<br />        this.name = name;<br />    }<br />}<br /><br />2).Employee.hbm.xml文件<br /><br />&lt;?xml version="1.0"?&gt;<br />&lt;!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"<br />"<a href="http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd</a>"&gt;<br />&lt;!-- <br />    Mapping file autogenerated by MyEclipse - Hibernate Tools<br />--&gt;<br />&lt;hibernate-mapping&gt;<br />    &lt;class name="com.semovy.business.pojo.Employee" table="employee" &gt;&lt;!---一定弃掉catalog属性，我是卡在这里好久，运行有异常--&gt;<br />        &lt;id name="id" type="integer"&gt;<br />            &lt;column name="id" /&gt;<br />            &lt;generator class="identity" /&gt;<br />        &lt;/id&gt;<br />        &lt;property name="name" type="string"&gt;<br />            &lt;column name="name" length="50" /&gt;<br />        &lt;/property&gt;<br />    &lt;/class&gt;<br />&lt;/hibernate-mapping&gt;<br /><br />四，建立Employee持久化类的业务逻辑：<br />package com.semovy.business.service;</p>
		<p>import java.util.ArrayList;<br />import java.util.List;</p>
		<p>import org.hibernate.Session;<br />import org.hibernate.Transaction;</p>
		<p>import com.semovy.framework.base.HibernateSession;<br />/**<br /> * this class supply all type of busniss service method for Employees<br /> * @author Semovy<br /> * @since 2006-11-08<br /> * @version 1.0<br /> */<br />public class EmployeeService {<br /> Session session = null;<br /> public EmployeeService(){}<br /> public List findAllEmployees()<br /> {<br />  List employees = new ArrayList();<br />  try<br />  {<br />   session = HibernateSession.currentSession();<br />   Transaction tx = session.beginTransaction();<br />   employees = session.createQuery("from Employee").list();<br />   tx.commit();<br />   return employees;<br />  }<br />  catch(Exception ex)<br />  {<br />   ex.printStackTrace();<br />   return null;<br />  }<br />  finally<br />  {<br />   HibernateSession.closeSession();<br />  }<br /> }<br />}<br />五，建立jsp页面listEmployees.jsp来调用测试hibernate.<br /><br />&lt;%@ page language="java" import="java.util.*,<br />com.semovy.business.pojo.Employee,com.semovy.business.service.EmployeeService" <br />pageEncoding="UTF-8"%&gt;<br />&lt;%<br />String path = request.getContextPath();<br />String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";<br />%&gt;</p>
		<p>&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"&gt;<br />&lt;html&gt;<br />  &lt;head&gt;<br />    &lt;base href="&lt;%=basePath%&gt;"&gt;<br />    <br />    &lt;title&gt;My JSP 'listEmployees.jsp' starting page&lt;/title&gt;<br />    <br />    &lt;meta http-equiv="pragma" content="no-cache"&gt;<br />    &lt;meta http-equiv="cache-control" content="no-cache"&gt;<br />    &lt;meta http-equiv="expires" content="0"&gt;<br />    &lt;meta http-equiv="keywords" content="keyword1,keyword2,keyword3"&gt;<br />    &lt;meta http-equiv="description" content="This is my page"&gt;<br />    <br />    &lt;!--<br />    &lt;link rel="stylesheet" type="text/css" href="styles.css"&gt;<br />    --&gt;<br />  &lt;/head&gt;<br />  <br />  &lt;body&gt;<br />    This is my JSP page.&lt;br&gt;<br />    &lt;%<br />  <br />    EmployeeService es = new EmployeeService();<br />    List l = es.findAllEmployees();<br />    if(l != null)<br />    {<br />     Iterator it = l.iterator();<br />     while(it.hasNext())<br />     {<br />      Employee em = (Employee)it.next();<br />      out.print("ID: " + em.getId() + "Name: " + em.getName()+"&lt;br&gt;");<br />      <br />     } <br />    }<br />    %&gt; <br />  &lt;/body&gt;<br />&lt;/html&gt;<br />六、发布应用</p>
<img src ="http://www.blogjava.net/WshmAndLily/aggbug/80216.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/WshmAndLily/" target="_blank">semovy</a> 2006-11-09 17:49 <a href="http://www.blogjava.net/WshmAndLily/articles/80216.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>