﻿<?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-欢迎来到小米的博客-随笔分类-Hibernate</title><link>http://www.blogjava.net/georgehill/category/1286.html</link><description>希望能和您交流Java编程的知识和见解</description><language>zh-cn</language><lastBuildDate>Tue, 27 Feb 2007 08:46:28 GMT</lastBuildDate><pubDate>Tue, 27 Feb 2007 08:46:28 GMT</pubDate><ttl>60</ttl><item><title>《深入浅出Hibernate》读书笔记(9)——Session管理</title><link>http://www.blogjava.net/georgehill/archive/2005/07/29/8759.html</link><dc:creator>小米</dc:creator><author>小米</author><pubDate>Fri, 29 Jul 2005 11:43:00 GMT</pubDate><guid>http://www.blogjava.net/georgehill/archive/2005/07/29/8759.html</guid><wfw:comment>http://www.blogjava.net/georgehill/comments/8759.html</wfw:comment><comments>http://www.blogjava.net/georgehill/archive/2005/07/29/8759.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/georgehill/comments/commentRss/8759.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/georgehill/services/trackbacks/8759.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;这一节是非常实用的一节，我在阅读此书的时候，一直在迷惑，究竟应该怎样管理Session呢？因为Session的管理是如此重要，类似于以前写程序对JDBC Connection的管理。看完此节后，终于找到了方法。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;在各种Session管理方案中，ThreadLocal模式得到了大量使用。ThreadLocal是Java中一种较为特殊的线程绑定机制。通过ThreadLocal存取的数据，总是与当前线程相关，也就是说，JVM为每个运行的线程，绑定了私有的本定实例存取空间，从而为多线程环境经常出现的并发访问问题提供了一种隔离机制。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;下面是Hibernate官方提供的一个ThreadLocal工具：<BR><BR>
<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: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
<DIV><SPAN style="COLOR: #000000"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top>import&nbsp;net.sf.hibernate.</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">;<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top>import&nbsp;net.sf.hibernate.cfg.</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">;<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top>import&nbsp;org.apache.log4j.Logger;<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top><BR><IMG id=Codehighlighter1_122_292_Open_Image onclick="this.style.display='none'; Codehighlighter1_122_292_Open_Text.style.display='none'; Codehighlighter1_122_292_Closed_Image.style.display='inline'; Codehighlighter1_122_292_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=Codehighlighter1_122_292_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_122_292_Closed_Text.style.display='none'; Codehighlighter1_122_292_Open_Image.style.display='inline'; Codehighlighter1_122_292_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align=top></SPAN><SPAN id=Codehighlighter1_122_292_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=Codehighlighter1_122_292_Open_Text><SPAN style="COLOR: #008000">/*</SPAN><SPAN style="COLOR: #008000">*<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;*&nbsp;&lt;p&gt;Title:&nbsp;&lt;/p&gt;<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;*<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;*&nbsp;&lt;p&gt;Description:&nbsp;Session的管理类&lt;/p&gt;<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;*<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;*&nbsp;&lt;p&gt;Copyright:&nbsp;Copyright&nbsp;(c)&nbsp;2005&lt;/p&gt;<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;*<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;*&nbsp;&lt;p&gt;Company:&nbsp;&lt;/p&gt;<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;*<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;*&nbsp;@author&nbsp;George&nbsp;Hill<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;*&nbsp;@version&nbsp;1.0<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>&nbsp;</SPAN><SPAN style="COLOR: #008000">*/</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top><BR><IMG id=Codehighlighter1_322_1435_Open_Image onclick="this.style.display='none'; Codehighlighter1_322_1435_Open_Text.style.display='none'; Codehighlighter1_322_1435_Closed_Image.style.display='inline'; Codehighlighter1_322_1435_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=Codehighlighter1_322_1435_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_322_1435_Closed_Text.style.display='none'; Codehighlighter1_322_1435_Open_Image.style.display='inline'; Codehighlighter1_322_1435_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;HibernateUtil&nbsp;</SPAN><SPAN id=Codehighlighter1_322_1435_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"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_322_1435_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">private</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">static</SPAN><SPAN style="COLOR: #000000">&nbsp;final&nbsp;Logger&nbsp;log&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;Logger.getLogger(HibernateUtil.</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">);<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">private</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">static</SPAN><SPAN style="COLOR: #000000">&nbsp;final&nbsp;SessionFactory&nbsp;sessionFactory;<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top><BR><IMG id=Codehighlighter1_458_486_Open_Image onclick="this.style.display='none'; Codehighlighter1_458_486_Open_Text.style.display='none'; Codehighlighter1_458_486_Closed_Image.style.display='inline'; Codehighlighter1_458_486_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_458_486_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_458_486_Closed_Text.style.display='none'; Codehighlighter1_458_486_Open_Image.style.display='inline'; Codehighlighter1_458_486_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;</SPAN><SPAN id=Codehighlighter1_458_486_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=Codehighlighter1_458_486_Open_Text><SPAN style="COLOR: #008000">/*</SPAN><SPAN style="COLOR: #008000">*<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;*&nbsp;初始化Hibernate配置<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">*/</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG id=Codehighlighter1_497_772_Open_Image onclick="this.style.display='none'; Codehighlighter1_497_772_Open_Text.style.display='none'; Codehighlighter1_497_772_Closed_Image.style.display='inline'; Codehighlighter1_497_772_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_497_772_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_497_772_Closed_Text.style.display='none'; Codehighlighter1_497_772_Open_Image.style.display='inline'; Codehighlighter1_497_772_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">static</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN id=Codehighlighter1_497_772_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"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_497_772_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG id=Codehighlighter1_507_626_Open_Image onclick="this.style.display='none'; Codehighlighter1_507_626_Open_Text.style.display='none'; Codehighlighter1_507_626_Closed_Image.style.display='inline'; Codehighlighter1_507_626_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_507_626_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_507_626_Closed_Text.style.display='none'; Codehighlighter1_507_626_Open_Image.style.display='inline'; Codehighlighter1_507_626_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">try</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN id=Codehighlighter1_507_626_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"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_507_626_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;Create&nbsp;the&nbsp;SessionFactory</SPAN><SPAN style="COLOR: #008000"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top></SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sessionFactory&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;Configuration().configure().buildSessionFactory();<BR><IMG id=Codehighlighter1_649_768_Open_Image onclick="this.style.display='none'; Codehighlighter1_649_768_Open_Text.style.display='none'; Codehighlighter1_649_768_Closed_Image.style.display='inline'; Codehighlighter1_649_768_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_649_768_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_649_768_Closed_Text.style.display='none'; Codehighlighter1_649_768_Open_Image.style.display='inline'; Codehighlighter1_649_768_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN></SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">catch</SPAN><SPAN style="COLOR: #000000">&nbsp;(Throwable&nbsp;ex)&nbsp;</SPAN><SPAN id=Codehighlighter1_649_768_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"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_649_768_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;log.error(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">Initial&nbsp;SessionFactory&nbsp;creation&nbsp;failed.</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,&nbsp;ex);<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">throw</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;ExceptionInInitializerError(ex);<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">static</SPAN><SPAN style="COLOR: #000000">&nbsp;final&nbsp;ThreadLocal&nbsp;session&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;ThreadLocal();<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top><BR><IMG id=Codehighlighter1_841_926_Open_Image onclick="this.style.display='none'; Codehighlighter1_841_926_Open_Text.style.display='none'; Codehighlighter1_841_926_Closed_Image.style.display='inline'; Codehighlighter1_841_926_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_841_926_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_841_926_Closed_Text.style.display='none'; Codehighlighter1_841_926_Open_Image.style.display='inline'; Codehighlighter1_841_926_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;</SPAN><SPAN id=Codehighlighter1_841_926_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=Codehighlighter1_841_926_Open_Text><SPAN style="COLOR: #008000">/*</SPAN><SPAN style="COLOR: #008000">*<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;*&nbsp;根据当前线程获取相应的Session<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;*&nbsp;@return&nbsp;Session<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;*&nbsp;@throws&nbsp;HibernateException<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">*/</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG id=Codehighlighter1_995_1198_Open_Image onclick="this.style.display='none'; Codehighlighter1_995_1198_Open_Text.style.display='none'; Codehighlighter1_995_1198_Closed_Image.style.display='inline'; Codehighlighter1_995_1198_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_995_1198_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_995_1198_Closed_Text.style.display='none'; Codehighlighter1_995_1198_Open_Image.style.display='inline'; Codehighlighter1_995_1198_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">static</SPAN><SPAN style="COLOR: #000000">&nbsp;Session&nbsp;currentSession()&nbsp;throws&nbsp;HibernateException&nbsp;</SPAN><SPAN id=Codehighlighter1_995_1198_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"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_995_1198_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;Session&nbsp;s&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;(Session)&nbsp;session.</SPAN><SPAN style="COLOR: #0000ff">get</SPAN><SPAN style="COLOR: #000000">();<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;Open&nbsp;a&nbsp;new&nbsp;Session,&nbsp;if&nbsp;this&nbsp;Thread&nbsp;has&nbsp;none&nbsp;yet</SPAN><SPAN style="COLOR: #008000"><BR><IMG id=Codehighlighter1_1112_1180_Open_Image onclick="this.style.display='none'; Codehighlighter1_1112_1180_Open_Text.style.display='none'; Codehighlighter1_1112_1180_Closed_Image.style.display='inline'; Codehighlighter1_1112_1180_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_1112_1180_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_1112_1180_Closed_Text.style.display='none'; Codehighlighter1_1112_1180_Open_Image.style.display='inline'; Codehighlighter1_1112_1180_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align=top></SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">&nbsp;(s&nbsp;</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">null</SPAN><SPAN style="COLOR: #000000">)&nbsp;</SPAN><SPAN id=Codehighlighter1_1112_1180_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"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_1112_1180_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;sessionFactory.openSession();<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;session.</SPAN><SPAN style="COLOR: #0000ff">set</SPAN><SPAN style="COLOR: #000000">(s);<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;s;<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top><BR><IMG id=Codehighlighter1_1203_1264_Open_Image onclick="this.style.display='none'; Codehighlighter1_1203_1264_Open_Text.style.display='none'; Codehighlighter1_1203_1264_Closed_Image.style.display='inline'; Codehighlighter1_1203_1264_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_1203_1264_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_1203_1264_Closed_Text.style.display='none'; Codehighlighter1_1203_1264_Open_Image.style.display='inline'; Codehighlighter1_1203_1264_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;</SPAN><SPAN id=Codehighlighter1_1203_1264_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=Codehighlighter1_1203_1264_Open_Text><SPAN style="COLOR: #008000">/*</SPAN><SPAN style="COLOR: #008000">*<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;*&nbsp;返回Session给相应的线程<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;*&nbsp;@throws&nbsp;HibernateException<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">*/</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG id=Codehighlighter1_1328_1432_Open_Image onclick="this.style.display='none'; Codehighlighter1_1328_1432_Open_Text.style.display='none'; Codehighlighter1_1328_1432_Closed_Image.style.display='inline'; Codehighlighter1_1328_1432_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_1328_1432_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_1328_1432_Closed_Text.style.display='none'; Codehighlighter1_1328_1432_Open_Image.style.display='inline'; Codehighlighter1_1328_1432_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">static</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;closeSession()&nbsp;throws&nbsp;HibernateException&nbsp;</SPAN><SPAN id=Codehighlighter1_1328_1432_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"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_1328_1432_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;Session&nbsp;s&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;(Session)&nbsp;session.</SPAN><SPAN style="COLOR: #0000ff">get</SPAN><SPAN style="COLOR: #000000">();<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;session.</SPAN><SPAN style="COLOR: #0000ff">set</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">null</SPAN><SPAN style="COLOR: #000000">);<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">&nbsp;(s&nbsp;</SPAN><SPAN style="COLOR: #000000">!=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">null</SPAN><SPAN style="COLOR: #000000">)<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s.close();<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top></SPAN></DIV></DIV><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;针对WEB程序，还可以利用Servlet2.3的Filter机制，轻松实现线程生命周期内的Session管理。下面是一个通过Filter进行Session管理的典型案例：<BR><BR>
<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: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
<DIV><IMG id=Codehighlighter1_49_666_Open_Image onclick="this.style.display='none'; Codehighlighter1_49_666_Open_Text.style.display='none'; Codehighlighter1_49_666_Closed_Image.style.display='inline'; Codehighlighter1_49_666_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=Codehighlighter1_49_666_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_49_666_Closed_Text.style.display='none'; Codehighlighter1_49_666_Open_Image.style.display='inline'; Codehighlighter1_49_666_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align=top><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;PersistenceFilter&nbsp;implements&nbsp;Filter&nbsp;</SPAN><SPAN id=Codehighlighter1_49_666_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"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_49_666_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">protected</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">static</SPAN><SPAN style="COLOR: #000000">&nbsp;ThreadLocal&nbsp;hibernateHolder&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;ThreadLocal();<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top><BR><IMG id=Codehighlighter1_249_655_Open_Image onclick="this.style.display='none'; Codehighlighter1_249_655_Open_Text.style.display='none'; Codehighlighter1_249_655_Closed_Image.style.display='inline'; Codehighlighter1_249_655_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_249_655_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_249_655_Closed_Text.style.display='none'; Codehighlighter1_249_655_Open_Image.style.display='inline'; Codehighlighter1_249_655_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;doFilter(ServletRequest&nbsp;request,&nbsp;ServletResponse&nbsp;response,&nbsp;FilterChain&nbsp;chain)&nbsp;throws&nbsp;IOException,&nbsp;ServletException&nbsp;</SPAN><SPAN id=Codehighlighter1_249_655_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"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_249_655_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;hibernateHolder.</SPAN><SPAN style="COLOR: #0000ff">set</SPAN><SPAN style="COLOR: #000000">(getSession());<BR><IMG id=Codehighlighter1_298_371_Open_Image onclick="this.style.display='none'; Codehighlighter1_298_371_Open_Text.style.display='none'; Codehighlighter1_298_371_Closed_Image.style.display='inline'; Codehighlighter1_298_371_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_298_371_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_298_371_Closed_Text.style.display='none'; Codehighlighter1_298_371_Open_Image.style.display='inline'; Codehighlighter1_298_371_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">try</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN id=Codehighlighter1_298_371_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"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_298_371_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<IMG src="http://www.blogjava.net/images/dot.gif"><IMG src="http://www.blogjava.net/images/dot.gif"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;chain.doFilter(request,&nbsp;response);<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<IMG src="http://www.blogjava.net/images/dot.gif"><IMG src="http://www.blogjava.net/images/dot.gif"><BR><IMG id=Codehighlighter1_381_651_Open_Image onclick="this.style.display='none'; Codehighlighter1_381_651_Open_Text.style.display='none'; Codehighlighter1_381_651_Closed_Image.style.display='inline'; Codehighlighter1_381_651_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_381_651_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_381_651_Closed_Text.style.display='none'; Codehighlighter1_381_651_Open_Image.style.display='inline'; Codehighlighter1_381_651_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN></SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">finally</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN id=Codehighlighter1_381_651_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"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_381_651_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Session&nbsp;session&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;(Session)&nbsp;hibernateHolder.</SPAN><SPAN style="COLOR: #0000ff">get</SPAN><SPAN style="COLOR: #000000">();<BR><IMG id=Codehighlighter1_467_645_Open_Image onclick="this.style.display='none'; Codehighlighter1_467_645_Open_Text.style.display='none'; Codehighlighter1_467_645_Closed_Image.style.display='inline'; Codehighlighter1_467_645_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_467_645_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_467_645_Closed_Text.style.display='none'; Codehighlighter1_467_645_Open_Image.style.display='inline'; Codehighlighter1_467_645_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">&nbsp;(session&nbsp;</SPAN><SPAN style="COLOR: #000000">!=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">null</SPAN><SPAN style="COLOR: #000000">)&nbsp;</SPAN><SPAN id=Codehighlighter1_467_645_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"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_467_645_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hibernateHolder.</SPAN><SPAN style="COLOR: #0000ff">set</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">null</SPAN><SPAN style="COLOR: #000000">);<BR><IMG id=Codehighlighter1_516_553_Open_Image onclick="this.style.display='none'; Codehighlighter1_516_553_Open_Text.style.display='none'; Codehighlighter1_516_553_Closed_Image.style.display='inline'; Codehighlighter1_516_553_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_516_553_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_516_553_Closed_Text.style.display='none'; Codehighlighter1_516_553_Open_Image.style.display='inline'; Codehighlighter1_516_553_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">try</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN id=Codehighlighter1_516_553_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"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_516_553_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;session.close();<BR><IMG id=Codehighlighter1_585_637_Open_Image onclick="this.style.display='none'; Codehighlighter1_585_637_Open_Text.style.display='none'; Codehighlighter1_585_637_Closed_Image.style.display='inline'; Codehighlighter1_585_637_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_585_637_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_585_637_Closed_Text.style.display='none'; Codehighlighter1_585_637_Open_Image.style.display='inline'; Codehighlighter1_585_637_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN></SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">catch</SPAN><SPAN style="COLOR: #000000">&nbsp;(HibernateException&nbsp;ex)&nbsp;</SPAN><SPAN id=Codehighlighter1_585_637_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"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_585_637_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">throw</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;ServletException(ex);<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;<IMG src="http://www.blogjava.net/images/dot.gif"><IMG src="http://www.blogjava.net/images/dot.gif"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</SPAN></SPAN></DIV></DIV><img src ="http://www.blogjava.net/georgehill/aggbug/8759.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/georgehill/" target="_blank">小米</a> 2005-07-29 19:43 <a href="http://www.blogjava.net/georgehill/archive/2005/07/29/8759.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《深入浅出Hibernate》读书笔记(8)——Hibernate分页</title><link>http://www.blogjava.net/georgehill/archive/2005/07/26/8502.html</link><dc:creator>小米</dc:creator><author>小米</author><pubDate>Tue, 26 Jul 2005 10:12:00 GMT</pubDate><guid>http://www.blogjava.net/georgehill/archive/2005/07/26/8502.html</guid><wfw:comment>http://www.blogjava.net/georgehill/comments/8502.html</wfw:comment><comments>http://www.blogjava.net/georgehill/archive/2005/07/26/8502.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.blogjava.net/georgehill/comments/commentRss/8502.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/georgehill/services/trackbacks/8502.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;数据分页显示，是很多B/S系统会遇到的问题。现在大多数主流数据库都提供了数据部分读取机制，而对于某些没有提供相应机制的数据而言，Hibernate也通过其它途径实现了分页，如通过Scrollable ResultSet，如果JDBC不支持Scrollable ResultSet，Hibernate也会自动通过ResultSet的next方法进行记录定位。Hibernate的Criteria、Query等接口提供了一致的方法设定分页范围。下面是书中的例子：<BR><BR>
<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: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
<DIV><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top><SPAN style="COLOR: #000000">Criteria&nbsp;criteria&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;session.createCriteria(TUser.</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">);<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top>Criteria.add(Expression.eq(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">age</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">20</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">));<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">从检索结果中获取第100条记录开始的20条记录</SPAN><SPAN style="COLOR: #008000"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #000000">criteria.setFirstResult(</SPAN><SPAN style="COLOR: #000000">100</SPAN><SPAN style="COLOR: #000000">);<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top>criteria.setFetchSize(</SPAN><SPAN style="COLOR: #000000">20</SPAN><SPAN style="COLOR: #000000">);</SPAN></DIV></DIV><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;不过，我在测试的时候总是不能够正常工作，把setFetchSize方法换成setMaxResults方法才行。换成最新的mysql-connector-java-3.1.10-bin-g.jar驱动也是一样。<img src ="http://www.blogjava.net/georgehill/aggbug/8502.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/georgehill/" target="_blank">小米</a> 2005-07-26 18:12 <a href="http://www.blogjava.net/georgehill/archive/2005/07/26/8502.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《深入浅出Hibernate》读书笔记(7)——回调与拦截机制</title><link>http://www.blogjava.net/georgehill/archive/2005/07/21/8145.html</link><dc:creator>小米</dc:creator><author>小米</author><pubDate>Thu, 21 Jul 2005 10:35:00 GMT</pubDate><guid>http://www.blogjava.net/georgehill/archive/2005/07/21/8145.html</guid><wfw:comment>http://www.blogjava.net/georgehill/comments/8145.html</wfw:comment><comments>http://www.blogjava.net/georgehill/archive/2005/07/21/8145.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/georgehill/comments/commentRss/8145.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/georgehill/services/trackbacks/8145.html</trackback:ping><description><![CDATA[<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Hibernate通过Lifecycle、Validatable接口制定了实体对象CRUD过程中的回调方式。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Lifecycle接口中的onSave、onUpdate、onDelete方法，如果返回true则意味着需要中止执行相应的操作过程。如果代码运行期间抛出了CallbackException，对应的操作也会被中止。注意，不要试图在这些方法中调用Session进行持久化操作，这些方法中Session无法正常使用。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Validatable.validate方法将在实体被持久化之前得到调用以对数据进行验证。此方法在实体对象的生命周期内可能被数次调用，因此，此方法仅用于数据本身的逻辑校验，而不要试图在此实现业务逻辑的验证。<BR>
<HR>
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Hibernate还引入了Interceptor，为持久化事件的捕获和处理提供了一个非侵略性的实现。Interceptor接口定义了Hibernate中的通用拦截机制。Session创建时即可指定加载相应的Interceptor，之后，此Session的持久化操作动作都将首先经由此拦截器捕获处理。简单的加载范例如下：</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: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
<DIV><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top><SPAN style="COLOR: #000000">SessionFactory&nbsp;factory&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;config.buildSessionFactory();<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top>Interceptor&nbsp;it&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;MyInterceptor();<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top>session&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;sessionFactory.openSession(it);</SPAN></DIV></DIV><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;需要注意的是，与Lifecycle相同，Interceptor的方法中不可通过Session实例进行持久化操作。<img src ="http://www.blogjava.net/georgehill/aggbug/8145.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/georgehill/" target="_blank">小米</a> 2005-07-21 18:35 <a href="http://www.blogjava.net/georgehill/archive/2005/07/21/8145.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《深入浅出Hibernate》读书笔记(6)——集合类型和结果集排序</title><link>http://www.blogjava.net/georgehill/archive/2005/07/20/8033.html</link><dc:creator>小米</dc:creator><author>小米</author><pubDate>Wed, 20 Jul 2005 02:56:00 GMT</pubDate><guid>http://www.blogjava.net/georgehill/archive/2005/07/20/8033.html</guid><wfw:comment>http://www.blogjava.net/georgehill/comments/8033.html</wfw:comment><comments>http://www.blogjava.net/georgehill/archive/2005/07/20/8033.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/georgehill/comments/commentRss/8033.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/georgehill/services/trackbacks/8033.html</trackback:ping><description><![CDATA[<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;最近真是忙，事情都挤到一块去了。<IMG height=20 src="http://www.blogjava.net/Emoticons/QQ/19.gif" width=20 border=0>&nbsp;终于有时间又看了几页书。<IMG height=20 src="http://www.blogjava.net/Emoticons/QQ/15.gif" width=20 border=0><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;言归正传，Hibernate中的Collection类型分为有序集和无序集两类。这里所谓的有序和无序，是针对Hibernate数据持久过程中，是否保持数据集合中的记录排列顺序加以区分的。无序集有Set，Bag，Map几种，有序集有List一种。有序集的数据在持久化过程中，会将集合中元素排列的先后顺序同时固化到数据库中，读取时也会返回一个具备同样排列顺序的数据集合。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Hibernate中的Collection类型是用的自己的实现，所以在程序中，不能够把接口强制转化成相应的JDK Collection的实现。<BR>
<HR>
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;结果集的排序有两种方式：<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1. Sort<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Collection中的数据排序。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2. order-by<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;对数据库执行Select SQL时，由order by子句实现的数据排序方式。<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;需要注意的是，order-by特性在实现中借助了JDK 1.4中的新增集合类LinkedHashSet以及LinkedHashMap。因此，order-by特性只支持在1.4版本以上的JDK中运行。</P><img src ="http://www.blogjava.net/georgehill/aggbug/8033.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/georgehill/" target="_blank">小米</a> 2005-07-20 10:56 <a href="http://www.blogjava.net/georgehill/archive/2005/07/20/8033.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《深入浅出Hibernate》读书笔记(5)——持久层操作</title><link>http://www.blogjava.net/georgehill/archive/2005/07/12/7556.html</link><dc:creator>小米</dc:creator><author>小米</author><pubDate>Tue, 12 Jul 2005 10:49:00 GMT</pubDate><guid>http://www.blogjava.net/georgehill/archive/2005/07/12/7556.html</guid><wfw:comment>http://www.blogjava.net/georgehill/comments/7556.html</wfw:comment><comments>http://www.blogjava.net/georgehill/archive/2005/07/12/7556.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.blogjava.net/georgehill/comments/commentRss/7556.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/georgehill/services/trackbacks/7556.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Session.get/load的区别：<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1.如果未能发现符合条件的记录，get方法返回null，而load方法会抛出一个ObejctNotFoundException。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2.Load方法可返回实体的代理类类型，而get方法永远直接返回实体类。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3.Load方法可以充分利用内部缓存和二级缓存中现有数据，而get方法则仅仅在内部缓存中进行数据查找，如没有发现对应数据，将越过二级缓存，直接调用SQL完成数据读取。
<P></P>
<P>
<HR>
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Session.find/iterate的区别：<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;find方法将执行Select SQL从数据库中获得所有符合条件的记录并构造相应的实体对象，实体对象构建完毕之后，就将其纳入缓存。它对缓存只写不读，因此无法利用缓存。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iterate方法首先执行一条Select SQL以获得所有符合查询条件的数据id，随即，iterate方法首先在本地缓存中根据id查找对应的实体对象是否存在，如果缓存中已经存在对应的数据，则直接以此数据对象作为查询结果，如果没有找到，再执行相应的Select语句获得对应的库表记录（iterate方法如果执行了数据库读取操作并构建了完整的数据对象，也会将其查询结果纳入缓存）。
<P></P>
<P>
<HR>
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Query Cache产生作用的情况：<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1.完全相同的Select SQL重复执行。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2.在两次查询之间，此Select SQL对应的库表没有发生过改变。
<P></P>
<P>
<HR>
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Session.save方法的执行步骤：<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1.在Session内部缓存中寻找待保存对象。内部缓存命中，则认为此数据已经保存（执行过insert操作），实体对象已经处于Persistent状态，直接返回。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2.如果实体类实现了lifecycle接口，则调用待保存对象的onSave方法。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3.如果实体类实现了validatable接口，则调用其validate()方法。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;4.调用对应拦截器的Interceptor.onSave方法（如果有的话）。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;5.构造Insert SQL，并加以执行。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;6.记录插入成功，user.id属性被设定为insert操作返回的新记录id值。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;7.将user对象放入内部缓存。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;8.最后，如果存在级联关系，对级联关系进行递归处理。
<P></P>
<P>
<HR>
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Session.update方法的执行步骤：<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1.根据待更新实体对象的Key，在当前session的内部缓存中进行查找，如果发现，则认为当前实体对象已经处于Persistent状态，返回。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2.初始化实体对象的状态信息（作为之后脏数据检查的依据），并将其纳入内部缓存。注意这里Session.update方法本身并没有发送Update SQL完成数据更新操作，Update SQL将在之后的Session.flush方法中执行（Transaction.commit在真正提交数据库事务之前会调用Session.flush）。
<P></P>
<P>
<HR>

<P></P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Session.saveOrUpdate方法的执行步骤：<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1.首先在Session内部缓存中进行查找，如果发现则直接返回。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2.执行实体类对应的Interceptor.isUnsaved方法（如果有的话），判断对象是否为未保存状态。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3.根据unsaved-value判断对象是否处于未保存状态。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;4.如果对象未保存（Transient状态），则调用save方法保存对象。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;5.如果对象为已保存（Detached状态），调用update方法将对象与Session重新关联。</P><img src ="http://www.blogjava.net/georgehill/aggbug/7556.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/georgehill/" target="_blank">小米</a> 2005-07-12 18:49 <a href="http://www.blogjava.net/georgehill/archive/2005/07/12/7556.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《深入浅出Hibernate》读书笔记(4)——事务管理</title><link>http://www.blogjava.net/georgehill/archive/2005/07/08/7374.html</link><dc:creator>小米</dc:creator><author>小米</author><pubDate>Fri, 08 Jul 2005 08:19:00 GMT</pubDate><guid>http://www.blogjava.net/georgehill/archive/2005/07/08/7374.html</guid><wfw:comment>http://www.blogjava.net/georgehill/comments/7374.html</wfw:comment><comments>http://www.blogjava.net/georgehill/archive/2005/07/08/7374.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.blogjava.net/georgehill/comments/commentRss/7374.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/georgehill/services/trackbacks/7374.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;事务的4个基本特性（ACID）：<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1. Atomic（原子性）：事务中包含的操作被看作一个逻辑单元，这个逻辑单元中的操作要么全部成功，要么全部失败。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2. Consistency（一致性）：只有合法的数据可以被写入数据库，否则事务应该将其回滚到最初状态。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3. Isolation（隔离性）：事务允许多个用户对同一个数据的并发访问，而不破坏数据的正确性和完整性。同时，并行事务的修改必须与其他并行事务的修改相互独立。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;4. Durability（持久性）：事务结束后，事务处理的结果必须能够得到固化。 
<HR>
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;数据库操作过程中可能出现的3种不确定情况：<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1. 脏读取（Dirty Reads）：一个事务读取了另一个并行事务未提交的数据。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2. 不可重复读取（Non-repeatable Reads）：一个事务再次读取之前的数据时，得到的数据不一致，被另一个已提交的事务修改。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3. 虚读（Phantom Reads）：一个事务重新执行一个查询，返回的记录中包含了因为其他最近提交的事务而产生的新记录。<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;标准SQL规范中，为了避免上面3种情况的出现，定义了4个事务隔离等级：<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1. Read Uncommitted：最低等级的事务隔离，仅仅保证了读取过程中不会读取到非法数据。上诉3种不确定情况均有可能发生。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2. Read Committed：大多数主流数据库的默认事务等级，保证了一个事务不会读到另一个并行事务已修改但未提交的数据，避免了“脏读取”。该级别适用于大多数系统。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3. Repeatable Read：保证了一个事务不会修改已经由另一个事务读取但未提交（回滚）的数据。避免了“脏读取”和“不可重复读取”的情况，但是带来了更多的性能损失。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;4. Serializable：最高等级的事务隔离，上面3种不确定情况都将被规避。这个级别将模拟事务的串行执行。 
<HR>
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Hibernate将事务管理委托给底层的JDBC或者JTA，默认是基于JDBC Transaction的。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Hibernate支持“悲观锁（Pessimistic Locking）”和“乐观锁（Optimistic Locking）”。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;悲观锁对数据被外界修改持保守态度，因此，在整个数据处理过程中，将数据处于锁定状态。悲观锁的实现，往往依靠数据库提供的锁机制。Hibernate通过使用数据库的for update子句实现了悲观锁机制。Hibernate的加锁模式有：<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1. LockMode.NONE：无锁机制<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2. LockMode.WRITE：Hibernate在Insert和Update记录的时候会自动获取<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3. LockMode.READ：Hibernate在读取记录的时候会自动获取<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;4. LockMode.UPGRADE：利用数据库的for update子句加锁<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;5. LockMode.UPGRADE_NOWAIT：Oracle的特定实现，利用Oracle的for update nowait子句实现加锁<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;乐观锁大多是基于数据版本（Version）记录机制实现。Hibernate在其数据访问引擎中内置了乐观锁实现，可以通过class描述符的optimistic-lock属性结合version描述符指定。optimistic-lock属性有如下可选取值：<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1. none：无乐观锁<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2. version：通过版本机制实现乐观锁<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3. dirty：通过检查发生变动过的属性实现乐观锁<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;4. all：通过检查所有属性实现乐观锁<img src ="http://www.blogjava.net/georgehill/aggbug/7374.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/georgehill/" target="_blank">小米</a> 2005-07-08 16:19 <a href="http://www.blogjava.net/georgehill/archive/2005/07/08/7374.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《深入浅出Hibernate》读书笔记(3)——数据缓存</title><link>http://www.blogjava.net/georgehill/archive/2005/06/22/6557.html</link><dc:creator>小米</dc:creator><author>小米</author><pubDate>Wed, 22 Jun 2005 10:15:00 GMT</pubDate><guid>http://www.blogjava.net/georgehill/archive/2005/06/22/6557.html</guid><wfw:comment>http://www.blogjava.net/georgehill/comments/6557.html</wfw:comment><comments>http://www.blogjava.net/georgehill/archive/2005/06/22/6557.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.blogjava.net/georgehill/comments/commentRss/6557.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/georgehill/services/trackbacks/6557.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;一般而言，ORM的数据缓存应包含如下几个层次：<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1. 事务级缓存（Transcation Layer Cache）<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2. 应用级/进程级缓存（Application/Process Layer Cache）<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3. 分布式缓存（Cluster Layer Cache）<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Hibernate数据缓存（Cache）分为两个层次，以Hibernate语义加以区分，可分为：<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1. 内部缓存（Session Level，也称为一级缓存）<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2. 二级缓存（SessionFactory Level，也称为二级缓存）<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Hibernate中，缓存将在以下情况中发挥作用：<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1. 通过id[主键]加载数据时<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2. 延迟加载<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;内部缓存正常情况下由Hibernate自动维护，如果需要手动干预，可以通过以下方法完成：<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1. Session.evict<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;将某个特定对象从内部缓存清除。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2. Session.clear<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;清空内部缓存。<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;在Hibernate中，二级缓存涵盖了应用级缓存和分布式缓存领域。如果数据满足以下条件，则可将其纳入缓存管理。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1. 数据不会被第三方应用修改；<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2. 数据大小(Data Size)在可接收的范围之内；<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3. 数据更新频率较低；<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;4. 同一数据可能会被系统频繁引用；<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;5. 非关键数据(关键数据，如金融帐户数据)。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Hibernate本身并未提供二级缓存的产品化实现，而是为众多的第三方缓存组件提供了接入接口，较常用的第三方组件有：<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1. JCS<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2. EHCache<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3. OSCache<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;4. JBossCache<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;5. SwarmCache<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Hibernate中启用二级缓存，需要在hibernate.cfg.xml配置hibernate.cache.provider_class参数，之后，需要在映射文件中指定各个映射实体(以及collection)的缓存同步策略。Hibernate提供了一下4种内置的缓存同步策略：<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1. read-only<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;只读。对于不会发生改变的数据，可使用只读型缓存。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2. nonstrict-read-write<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;如果程序对并发访问下的数据同步要求不是非常严格，且数据更新操作频率较低，可以采用本选项，获得较好的性能。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3. read-write<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;严格可读写缓存。基于时间戳判定机制，实现了“read committed”事务隔离等级。可用于对数据同步要求严格的情况，但不支持分布式缓存。这也是实际应用中使用最多的同步策略。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;4. transactional<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;事务型缓存，必须运行在JTA事务环境中。<img src ="http://www.blogjava.net/georgehill/aggbug/6557.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/georgehill/" target="_blank">小米</a> 2005-06-22 18:15 <a href="http://www.blogjava.net/georgehill/archive/2005/06/22/6557.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《深入浅出Hibernate》读书笔记(2)——实体对象识别</title><link>http://www.blogjava.net/georgehill/archive/2005/06/22/6546.html</link><dc:creator>小米</dc:creator><author>小米</author><pubDate>Wed, 22 Jun 2005 08:32:00 GMT</pubDate><guid>http://www.blogjava.net/georgehill/archive/2005/06/22/6546.html</guid><wfw:comment>http://www.blogjava.net/georgehill/comments/6546.html</wfw:comment><comments>http://www.blogjava.net/georgehill/archive/2005/06/22/6546.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.blogjava.net/georgehill/comments/commentRss/6546.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/georgehill/services/trackbacks/6546.html</trackback:ping><description><![CDATA[<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;在Java语言中，对象之间的比较可以通过引用比较(==)和内容比较(equals)两种方式进行，而在Hibernate的实体对象的比较是通过主键值来比较，如果要实现自己的识别逻辑，则需要重写equals方法和hashCode方法。<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;检查数据对象改变检查的一般策略有下面两种：<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1. 数据对象监控<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;数据对象监控的实现方式，通过拦截器对数据对象的设值方法进行拦截。一旦数据对象的设置方法被调用，则将其标志为“待更新”状态，之后在数据库操作时将其更新到对应的库表。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2. 数据版本对比<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;在持久层框架中维持数据对象的最近读取版本，当数据提交时将提交数据与此版本进行比对，如果发生变化则将其同步到数据库对应的库表。<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Hibernate采取的是第二种检查策略。它采用一个内部数据结构"EntityEntry"保存对应实体类的状态信息。<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;对于级联对象的更新，Hibernate将根据unsaved-value进行判定。首先Hibernate会取出目标对象的id。之后，将此值与unsaved-value进行比对，如果相等，则认为目标对象尚未保存，否则，认为对象已经保存，无需再进行保存操作。</P><img src ="http://www.blogjava.net/georgehill/aggbug/6546.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/georgehill/" target="_blank">小米</a> 2005-06-22 16:32 <a href="http://www.blogjava.net/georgehill/archive/2005/06/22/6546.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《深入浅出Hibernate》读书笔记(1)——实体对象生命周期</title><link>http://www.blogjava.net/georgehill/archive/2005/06/16/6224.html</link><dc:creator>小米</dc:creator><author>小米</author><pubDate>Thu, 16 Jun 2005 10:31:00 GMT</pubDate><guid>http://www.blogjava.net/georgehill/archive/2005/06/16/6224.html</guid><wfw:comment>http://www.blogjava.net/georgehill/comments/6224.html</wfw:comment><comments>http://www.blogjava.net/georgehill/archive/2005/06/16/6224.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.blogjava.net/georgehill/comments/commentRss/6224.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/georgehill/services/trackbacks/6224.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;最近正在研读《深入浅出Hibernate》一书，前面写的随笔有些也是读该书的笔记，只是未做归类，从这篇开始，我将把相关的内容都整理成一个系列的读书笔记。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;今天这篇是有关实体对象的生命周期。我刚开始接触Hibernate的时候，只是简单的把它当做一个API工具，直到后来看到有关VO和PO的内容时，才意识到Hibernate不仅仅是一个O/R Mapping的API工具，它还是一个容器。它可以帮你管理实体对象的生命周期。<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;实体对象的生命周期有三种状态：<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1.Transient（自由状态）<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;此时的实体对象和数据库中的记录无关联，只是一个普通的JavaBean。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2.Persistent（持久状态）<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;此时的实体对象和数据库中的记录有关联，其变更将由Hibernate固化到数据库中。该实体对象处于由Hibernate框架所管理的状态。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3.Detached（游离状态）<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;处于Persistent状态的对象，其对应的Session实例关闭之后，那么，此对象就处于"Detached"状态。Detached状态和Transient状态的区别在于Detached状态的对象可以再次与某个Session实例相关联而成为Persistent对象。<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;从实体对象是否被纳入Hibernate实体管理容器的角度，Transient和Detached状态的实体对象可以统称为VO（Value Object），而被管理的实体对象称为PO（Persistent Object）。两者的区别：<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1.VO是相对独立的实体对象，处于非管理状态。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2.PO是Hibernate纳入其实体管理容器（Entity Map）的对象，它代表了与数据库中某条记录对应的Hibernate实体，PO的变化在事务提交时将反映到实际数据库中。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3.如果一个PO与其对应的Session实例分离，那么此时，它又会变成一个VO。<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;下图是我画的实体对象生命周期的状态转换图：<BR><BR><IMG height=323 alt=vopolife.JPG src="http://www.blogjava.net/images/blogjava_net/georgehill/temp/vopolife.JPG" width=553 border=0><img src ="http://www.blogjava.net/georgehill/aggbug/6224.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/georgehill/" target="_blank">小米</a> 2005-06-16 18:31 <a href="http://www.blogjava.net/georgehill/archive/2005/06/16/6224.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>用HQL获取部分的实体对象属性</title><link>http://www.blogjava.net/georgehill/archive/2005/06/15/6167.html</link><dc:creator>小米</dc:creator><author>小米</author><pubDate>Wed, 15 Jun 2005 08:33:00 GMT</pubDate><guid>http://www.blogjava.net/georgehill/archive/2005/06/15/6167.html</guid><wfw:comment>http://www.blogjava.net/georgehill/comments/6167.html</wfw:comment><comments>http://www.blogjava.net/georgehill/archive/2005/06/15/6167.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/georgehill/comments/commentRss/6167.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/georgehill/services/trackbacks/6167.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;在使用HQL查询中，有时并不需要获取完整的一个实体对象，例如一个实体对象User有三个属性：account, password和email，如果我们只需要获取account和email属性，那么有两种方法可以选择。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1. 用普通的"select user.account, user.email from User as user"，程序片断如下：<BR><BR>
<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: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
<DIV><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;List&nbsp;list&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;session.createQuery(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">select&nbsp;user.account,&nbsp;user.email&nbsp;from&nbsp;User&nbsp;as&nbsp;user</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">).list();<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;Iterator&nbsp;it&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;list.iterator();<BR><IMG id=Codehighlighter1_157_264_Open_Image onclick="this.style.display='none'; Codehighlighter1_157_264_Open_Text.style.display='none'; Codehighlighter1_157_264_Closed_Image.style.display='inline'; Codehighlighter1_157_264_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=Codehighlighter1_157_264_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_157_264_Closed_Text.style.display='none'; Codehighlighter1_157_264_Open_Image.style.display='inline'; Codehighlighter1_157_264_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">while</SPAN><SPAN style="COLOR: #000000">&nbsp;(it.hasNext())&nbsp;</SPAN><SPAN id=Codehighlighter1_157_264_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"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_157_264_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Object[]&nbsp;values&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;(Object[])&nbsp;it.next();<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.</SPAN><SPAN style="COLOR: #0000ff">out</SPAN><SPAN style="COLOR: #000000">.println(values[</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">]&nbsp;</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">&nbsp;values[</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">]);<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN></SPAN></DIV></DIV><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;这时调用Query类的list方法返回的将是一个每个元素都是一个Object数组的List。如果只获取一个属性，那么返回的List中的每个元素都是String实例。<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2.在HQL中用new操作符生成实体对象，例如："select new User(user.account, user.email) from User as user"，程序片断如下：<BR><BR>
<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: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
<DIV><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;List&nbsp;list&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;session.createQuery(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">select&nbsp;new&nbsp;User(user.account,&nbsp;user.email)&nbsp;from&nbsp;User&nbsp;as&nbsp;user</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">).list();<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;Iterator&nbsp;it&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;list.iterator();<BR><IMG id=Codehighlighter1_167_278_Open_Image onclick="this.style.display='none'; Codehighlighter1_167_278_Open_Text.style.display='none'; Codehighlighter1_167_278_Closed_Image.style.display='inline'; Codehighlighter1_167_278_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=Codehighlighter1_167_278_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_167_278_Closed_Text.style.display='none'; Codehighlighter1_167_278_Open_Image.style.display='inline'; Codehighlighter1_167_278_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">while</SPAN><SPAN style="COLOR: #000000">&nbsp;(it.hasNext())&nbsp;</SPAN><SPAN id=Codehighlighter1_167_278_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"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_167_278_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;User&nbsp;user&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;(User)&nbsp;it.next();<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.</SPAN><SPAN style="COLOR: #0000ff">out</SPAN><SPAN style="COLOR: #000000">.println(user.getAccount()&nbsp;</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">&nbsp;user.getEmail());<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN></SPAN></DIV></DIV><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;这时list方法返回的List中的每一个元素都是User实体对象。这里有三点需要注意的：<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a.在HQL语句中需要使用as操作符指定User的别名，并且需要在构造函数的属性前面加上别名；<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; b.HQL语句中的构造函数在User类中必须要有相应的构造函数；<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;c.生成的实体对象是VO对象，如果对这些对象调用Session的saveOrUpdate方法将导致插入新的记录，而不是更新记录。<img src ="http://www.blogjava.net/georgehill/aggbug/6167.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/georgehill/" target="_blank">小米</a> 2005-06-15 16:33 <a href="http://www.blogjava.net/georgehill/archive/2005/06/15/6167.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Criteria的示例查询</title><link>http://www.blogjava.net/georgehill/archive/2005/06/03/5533.html</link><dc:creator>小米</dc:creator><author>小米</author><pubDate>Fri, 03 Jun 2005 09:27:00 GMT</pubDate><guid>http://www.blogjava.net/georgehill/archive/2005/06/03/5533.html</guid><wfw:comment>http://www.blogjava.net/georgehill/comments/5533.html</wfw:comment><comments>http://www.blogjava.net/georgehill/archive/2005/06/03/5533.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/georgehill/comments/commentRss/5533.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/georgehill/services/trackbacks/5533.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Criteria Query是很好的一种面向对象的查询实现，它提供了一种示例查询的方式。该方式根据已有的对象，查找数据库中属性匹配的其他对象。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;下面是一个场景片断，模糊查找数据库中用户帐号为'test'，邮件地址为<A href="mailto:'georgehill@21cn.com'">'georgehill@21cn.com'</A>的实例，忽略大小写。<BR><BR>
<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: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
<DIV><IMG id=Codehighlighter1_58_481_Open_Image onclick="this.style.display='none'; Codehighlighter1_58_481_Open_Text.style.display='none'; Codehighlighter1_58_481_Closed_Image.style.display='inline'; Codehighlighter1_58_481_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=Codehighlighter1_58_481_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_58_481_Closed_Text.style.display='none'; Codehighlighter1_58_481_Open_Image.style.display='inline'; Codehighlighter1_58_481_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align=top><SPAN style="COLOR: #000000">&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;testCriteriaExampleQuery()&nbsp;throws&nbsp;Exception&nbsp;</SPAN><SPAN id=Codehighlighter1_58_481_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"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_58_481_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;User&nbsp;user&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;User();<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;user.setAccount(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">test</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;user.setEmail(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">georgehill@21cn.com</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;Criteria&nbsp;criteria&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;session.createCriteria(User.</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">).add(Example.create(user).enableLike(MatchMode.ANYWHERE).ignoreCase());<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;List&nbsp;list&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;criteria.list();<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;<BR><IMG id=Codehighlighter1_354_477_Open_Image onclick="this.style.display='none'; Codehighlighter1_354_477_Open_Text.style.display='none'; Codehighlighter1_354_477_Closed_Image.style.display='inline'; Codehighlighter1_354_477_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_354_477_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_354_477_Closed_Text.style.display='none'; Codehighlighter1_354_477_Open_Image.style.display='inline'; Codehighlighter1_354_477_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">&nbsp;(list&nbsp;</SPAN><SPAN style="COLOR: #000000">!=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">null</SPAN><SPAN style="COLOR: #000000">)&nbsp;</SPAN><SPAN id=Codehighlighter1_354_477_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"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_354_477_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG id=Codehighlighter1_400_471_Open_Image onclick="this.style.display='none'; Codehighlighter1_400_471_Open_Text.style.display='none'; Codehighlighter1_400_471_Closed_Image.style.display='inline'; Codehighlighter1_400_471_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_400_471_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_400_471_Closed_Text.style.display='none'; Codehighlighter1_400_471_Open_Image.style.display='inline'; Codehighlighter1_400_471_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">for</SPAN><SPAN style="COLOR: #000000">&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;i&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">;&nbsp;i&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;list.size();&nbsp;i</SPAN><SPAN style="COLOR: #000000">++</SPAN><SPAN style="COLOR: #000000">)&nbsp;</SPAN><SPAN id=Codehighlighter1_400_471_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"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_400_471_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.</SPAN><SPAN style="COLOR: #0000ff">out</SPAN><SPAN style="COLOR: #000000">.println(((User)&nbsp;list.</SPAN><SPAN style="COLOR: #0000ff">get</SPAN><SPAN style="COLOR: #000000">(i)).getAccount());<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>&nbsp;&nbsp;}</SPAN></SPAN></DIV></DIV><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;示例查询需要生成Example实例，可以通过Example的静态方法create生成。Example类有下面的几个方法指定查询的方式： 
<H3>excludeZeroes</H3><PRE>public <A title="class in net.sf.hibernate.expression" href="file:///D:/lib/hibernate-2.1/doc/api/net/sf/hibernate/expression/Example.html">Example</A> <B>excludeZeroes</B>()</PRE>
<DL>
<DD>Exclude zero-valued properties 
<P></P>
<DD>
<DL></DL></DD></DL>
<HR>

<H3>excludeNone</H3><PRE>public <A title="class in net.sf.hibernate.expression" href="file:///D:/lib/hibernate-2.1/doc/api/net/sf/hibernate/expression/Example.html">Example</A> <B>excludeNone</B>()</PRE>
<DL>
<DD>Don't exclude null or zero-valued properties 
<P></P>
<DD>
<DL></DL></DD></DL>
<HR>

<H3>enableLike</H3><PRE>public <A title="class in net.sf.hibernate.expression" href="file:///D:/lib/hibernate-2.1/doc/api/net/sf/hibernate/expression/Example.html">Example</A> <B>enableLike</B>(<A title="class in net.sf.hibernate.expression" href="file:///D:/lib/hibernate-2.1/doc/api/net/sf/hibernate/expression/MatchMode.html">MatchMode</A>&nbsp;matchMode)</PRE>
<DL>
<DD>Use the "like" operator for all string-valued properties 
<P></P>
<DD>
<DL></DL></DD></DL>
<HR>

<H3>enableLike</H3><PRE>public <A title="class in net.sf.hibernate.expression" href="file:///D:/lib/hibernate-2.1/doc/api/net/sf/hibernate/expression/Example.html">Example</A> <B>enableLike</B>()</PRE>
<DL>
<DD>Use the "like" operator for all string-valued properties 
<P></P>
<DD>
<DL></DL></DD></DL>
<HR>

<H3>ignoreCase</H3><PRE>public <A title="class in net.sf.hibernate.expression" href="file:///D:/lib/hibernate-2.1/doc/api/net/sf/hibernate/expression/Example.html">Example</A> <B>ignoreCase</B>()</PRE>
<DL>
<DD>Ignore case for all string-valued properties 
<P></P>
<DD>
<DL></DL></DD></DL>
<HR>

<H3>excludeProperty</H3><PRE>public <A title="class in net.sf.hibernate.expression" href="file:///D:/lib/hibernate-2.1/doc/api/net/sf/hibernate/expression/Example.html">Example</A> <B>excludeProperty</B>(<A title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/String.html">String</A>&nbsp;name)</PRE>
<DL>
<DD>Exclude a particular named property 
<P></P>
<DD>
<DL></DL></DD></DL>
<HR>
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;当用enableLike()方法时，可以通过MatchMode指定匹配的方式。MatchMode提供了四种匹配的方式：<BR><BR>
<TABLE cellSpacing=0 cellPadding=3 width="100%" summary="" border=1>
<TBODY>
<TR class=TableHeadingColor bgColor=#ccccff>
<TD colSpan=2><FONT size=+2><B>Field Summary</B></FONT></TD></TR>
<TR class=TableRowColor bgColor=white>
<TD vAlign=top align=right width="1%"><FONT size=-1><CODE>static&nbsp;<A title="class in net.sf.hibernate.expression" href="file:///D:/lib/hibernate-2.1/doc/api/net/sf/hibernate/expression/MatchMode.html">MatchMode</A></CODE></FONT></TD>
<TD><CODE><B><A href="file:///D:/lib/hibernate-2.1/doc/api/net/sf/hibernate/expression/MatchMode.html#ANYWHERE">ANYWHERE</A></B></CODE> <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Match the pattern anywhere in the string</TD></TR>
<TR class=TableRowColor bgColor=white>
<TD vAlign=top align=right width="1%"><FONT size=-1><CODE>static&nbsp;<A title="class in net.sf.hibernate.expression" href="file:///D:/lib/hibernate-2.1/doc/api/net/sf/hibernate/expression/MatchMode.html">MatchMode</A></CODE></FONT></TD>
<TD><CODE><B><A href="file:///D:/lib/hibernate-2.1/doc/api/net/sf/hibernate/expression/MatchMode.html#END">END</A></B></CODE> <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Match the end of the string to the pattern</TD></TR>
<TR class=TableRowColor bgColor=white>
<TD vAlign=top align=right width="1%"><FONT size=-1><CODE>static&nbsp;<A title="class in net.sf.hibernate.expression" href="file:///D:/lib/hibernate-2.1/doc/api/net/sf/hibernate/expression/MatchMode.html">MatchMode</A></CODE></FONT></TD>
<TD><CODE><B><A href="file:///D:/lib/hibernate-2.1/doc/api/net/sf/hibernate/expression/MatchMode.html#EXACT">EXACT</A></B></CODE> <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Match the entire string to the pattern</TD></TR>
<TR class=TableRowColor bgColor=white>
<TD vAlign=top align=right width="1%"><FONT size=-1><CODE>static&nbsp;<A title="class in net.sf.hibernate.expression" href="file:///D:/lib/hibernate-2.1/doc/api/net/sf/hibernate/expression/MatchMode.html">MatchMode</A></CODE></FONT></TD>
<TD><CODE><B><A href="file:///D:/lib/hibernate-2.1/doc/api/net/sf/hibernate/expression/MatchMode.html#START">START</A></B></CODE> <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Match the start of the string to the pattern</TD></TR></TBODY></TABLE><img src ="http://www.blogjava.net/georgehill/aggbug/5533.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/georgehill/" target="_blank">小米</a> 2005-06-03 17:27 <a href="http://www.blogjava.net/georgehill/archive/2005/06/03/5533.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>如何用XDoclet生成hbm.xml文件</title><link>http://www.blogjava.net/georgehill/archive/2005/05/17/4402.html</link><dc:creator>小米</dc:creator><author>小米</author><pubDate>Tue, 17 May 2005 02:20:00 GMT</pubDate><guid>http://www.blogjava.net/georgehill/archive/2005/05/17/4402.html</guid><wfw:comment>http://www.blogjava.net/georgehill/comments/4402.html</wfw:comment><comments>http://www.blogjava.net/georgehill/archive/2005/05/17/4402.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/georgehill/comments/commentRss/4402.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/georgehill/services/trackbacks/4402.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;在数据库建立后，可以用Middlegen生成每个表对应的hbm.xml文件，并用hibernate-extensions生成对应的Java类。在后期开发时，如果要修改表，修改完后再走一遍这样的流程，那就显得有些繁琐。用XDoclet可以直接根据修改后的Java类生成对应的hbm.xml文件，这样可以减少维护的工作量。下面是我的...&nbsp;&nbsp;<a href='http://www.blogjava.net/georgehill/archive/2005/05/17/4402.html'>阅读全文</a><img src ="http://www.blogjava.net/georgehill/aggbug/4402.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/georgehill/" target="_blank">小米</a> 2005-05-17 10:20 <a href="http://www.blogjava.net/georgehill/archive/2005/05/17/4402.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Hibernate的一对多关联实例</title><link>http://www.blogjava.net/georgehill/archive/2005/05/15/4296.html</link><dc:creator>小米</dc:creator><author>小米</author><pubDate>Sat, 14 May 2005 17:55:00 GMT</pubDate><guid>http://www.blogjava.net/georgehill/archive/2005/05/15/4296.html</guid><wfw:comment>http://www.blogjava.net/georgehill/comments/4296.html</wfw:comment><comments>http://www.blogjava.net/georgehill/archive/2005/05/15/4296.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/georgehill/comments/commentRss/4296.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/georgehill/services/trackbacks/4296.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Hibernate2.1.8中有关一对多的文档，可以查看官方网站上的文档：http://www.hibernate.org/hib_docs/reference/zh-cn/html/，由于篇幅太长，这里就不再引用。&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;我的例子是一个全国省和市的数据表，省为一...&nbsp;&nbsp;<a href='http://www.blogjava.net/georgehill/archive/2005/05/15/4296.html'>阅读全文</a><img src ="http://www.blogjava.net/georgehill/aggbug/4296.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/georgehill/" target="_blank">小米</a> 2005-05-15 01:55 <a href="http://www.blogjava.net/georgehill/archive/2005/05/15/4296.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Hibernate的一对一关联实例</title><link>http://www.blogjava.net/georgehill/archive/2005/05/14/4290.html</link><dc:creator>小米</dc:creator><author>小米</author><pubDate>Sat, 14 May 2005 07:02:00 GMT</pubDate><guid>http://www.blogjava.net/georgehill/archive/2005/05/14/4290.html</guid><wfw:comment>http://www.blogjava.net/georgehill/comments/4290.html</wfw:comment><comments>http://www.blogjava.net/georgehill/archive/2005/05/14/4290.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/georgehill/comments/commentRss/4290.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/georgehill/services/trackbacks/4290.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Hibernate中的表的关联有一对一，一对多和多对多三种关联方式，在这篇笔记和接下来的笔记中，我将用我自己的实际例子来说明如何具体实施。&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;我使用的Hibernate版本是2.1.8，在Hibernate的网站2.1.6版本的中文文档中有关一对一的关联有下面...&nbsp;&nbsp;<a href='http://www.blogjava.net/georgehill/archive/2005/05/14/4290.html'>阅读全文</a><img src ="http://www.blogjava.net/georgehill/aggbug/4290.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/georgehill/" target="_blank">小米</a> 2005-05-14 15:02 <a href="http://www.blogjava.net/georgehill/archive/2005/05/14/4290.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>我的Hibernate启蒙文档</title><link>http://www.blogjava.net/georgehill/archive/2005/05/12/4236.html</link><dc:creator>小米</dc:creator><author>小米</author><pubDate>Thu, 12 May 2005 09:45:00 GMT</pubDate><guid>http://www.blogjava.net/georgehill/archive/2005/05/12/4236.html</guid><wfw:comment>http://www.blogjava.net/georgehill/comments/4236.html</wfw:comment><comments>http://www.blogjava.net/georgehill/archive/2005/05/12/4236.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/georgehill/comments/commentRss/4236.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/georgehill/services/trackbacks/4236.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;我是由夏昕的文档开始学习Hibernate的，很不错的一篇文档，在这里共享给大家。下载地址：<A href="http://www.xiaxin.net/Hibernate_DEV_GUIDE.rar">http://www.xiaxin.net/Hibernate_DEV_GUIDE.rar</A><img src ="http://www.blogjava.net/georgehill/aggbug/4236.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/georgehill/" target="_blank">小米</a> 2005-05-12 17:45 <a href="http://www.blogjava.net/georgehill/archive/2005/05/12/4236.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>