﻿<?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/ocean07000814/category/15455.html</link><description>共同探讨STRUTS#HIBERNATE#SPRING#EJB等技术</description><language>zh-cn</language><lastBuildDate>Thu, 01 Mar 2007 15:37:31 GMT</lastBuildDate><pubDate>Thu, 01 Mar 2007 15:37:31 GMT</pubDate><ttl>60</ttl><item><title>hibernate的inverse和 many－to－many 关系浅谈</title><link>http://www.blogjava.net/ocean07000814/articles/86128.html</link><dc:creator>非洲小白脸</dc:creator><author>非洲小白脸</author><pubDate>Thu, 07 Dec 2006 09:05:00 GMT</pubDate><guid>http://www.blogjava.net/ocean07000814/articles/86128.html</guid><wfw:comment>http://www.blogjava.net/ocean07000814/comments/86128.html</wfw:comment><comments>http://www.blogjava.net/ocean07000814/articles/86128.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ocean07000814/comments/commentRss/86128.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ocean07000814/services/trackbacks/86128.html</trackback:ping><description><![CDATA[
		<div class="postText">
				<p>                               <font size="4"> hibernate的inverse和 many－to－many 关系浅谈<br /></font><br />Inverse是hibernate双向关系中的基本概念，当然对于多数实体，我们并不需要双向关联，更多的可能会选择单向关联，况且我们大多数人一般采用一对多关系，而一对多双向关联的另一端：多对一的inverse属性是不存在，其实它默认就是inverse=false.从而防止了在一对多端胡乱设置inverse也不至于出错。但是inverse设置不当确实会带来很大的性能影响，这点是我们必须关注的。</p>
				<p>这篇文章已经详细分析了inverse设置不当带来的影响：</p>
				<p>
						<a href="http://www.hibernate.org/155.html">
								<font color="#4a664d">http://www.hibernate.org/155.html</font>
						</a>
				</p>
				<p>看了这篇文章，还是很有必要再写下一些总结的：</p>
				<p>1）inverse中提及的side其实是指一个类或者表的概念，双向关联其实是指双方都可以取得对方的应用。</p>
				<p>2）维护关系这个名词还是稍显模糊或者晦涩。我们一般说A类或者A表（这里的表的是指多对多的连接表）有责任维护关系，其实这里的意思是说，我在应用在更新，创建，删除（读就不用说了，双向引用正是为了方便读而出现）A类或者A表时，此时创建的SQL语句必须有责任保证关系的正确修改。</p>
				<p>3）inverse=false的side（side其实是指inverse＝false所位于的class元素）端有责任维护关系，而inverse＝true端无须维护这些关系。</p>
				<p>4）我们说inverse设立不当会导致性能低下，其实是说inverse设立不当，会产生多余重复的SQL语句甚至致使JDBC exception的throw。这是我们在建立实体类关系时必须需要关注的地方。一般来说，inverse＝true是推荐使用，双向关联中双方都设置inverse＝false的话，必会导致双方都重复更新同一个关系。但是如果双方都设立inverse＝true的话，双方都不维护关系的更新，这也是不行的，好在一对多中的一端:many-to-one默认是inverse＝false，避免了这种错误的产生。但是对多对就没有这个默认设置了，所以很多人经常在多对多的两端都使用inverse＝true，结果导致连接表的数据根本没有记录，就是因为他们双分都没有责任维护关系。所以说，双向关联中最好的设置是一端为inverse＝true，一端为inverse＝false。一般inverse＝false会放在多的一端，那么有人提问了，many－to－many两边都是多的，inverse到底放在哪儿？其实hibernate建立多对多关系也是将他们分离成两个一对多关系，中间连接一个连接表。所以通用存在一对多的关系，也可以这样说：一对多是多对多的基本组成部分。</p>
				<p>看下面的多对多的定义大家更会清楚”多对多“与“一对多”的关系：其中我们注意&lt;many-to-many /&gt;标签的特点就知道，它是定义了一个多对多关系，而不是&lt;one-to-many/&gt;。</p>
				<p>&lt;?xml version="1.0"?&gt;<br />&lt;!DOCTYPE hibernate-mapping PUBLIC <br /> "-//Hibernate/Hibernate Mapping DTD 2.0//EN"<br /> "<a href="http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd"><font color="#4a664d">http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd</font></a>"&gt;<br />&lt;hibernate-mapping  package="org.hibernate.auction"&gt;<br /> &lt;class name="TestA" table="TestA" <br /> dynamic-update="true" dynamic-insert="true" &gt; </p>
				<p>  &lt;id name="id" column="id" type="int" unsaved-value="any" &gt; <br />   &lt;generator class="assigned"&gt; <br />   &lt;/generator&gt; <br />  &lt;/id&gt; </p>
				<p>  &lt;property name="name" type="java.lang.String" <br />   update="true" insert="true" column="name" /&gt; </p>
				<p>  &lt;set name="testBs" table="TestA_TestB" inverse="false" cascade="all"&gt; <br />   &lt;key column="testA"/&gt; <br />   &lt;many-to-many column="testB" class="TestB" /&gt; <br />  &lt;/set&gt; </p>
				<p>
						<br /> &lt;/class&gt; <br /> &lt;class name="TestB" table="TestB" <br /> dynamic-update="true" dynamic-insert="true" &gt; </p>
				<p>  &lt;id name="id" column="id" type="int" unsaved-value="any" &gt; <br />   &lt;generator class="assigned"&gt; <br />   &lt;/generator&gt; <br />  &lt;/id&gt; </p>
				<p>  &lt;property name="name" type="java.lang.String" update="true" <br />  insert="true" column="name" /&gt; </p>
				<p>  &lt;set name="testAs" table="TestA_TestB" inverse="true" cascade="all"&gt; <br />   &lt;key column="testB"/&gt; <br />   &lt;many-to-many column="testA" class="TestA" /&gt; <br />  &lt;/set&gt; </p>
				<p>
						<br /> &lt;/class&gt; <br />&lt;/hibernate-mapping&gt;</p>
				<p>在对多对中，因为一端维护关系另一端不维护关系的原因，我们必须注意避免在应用中用不维护关系的类建立关系，因为这样建立的关系是不会在数据库中存储的。基于上面的映射文件代码给出一个例子：</p>
				<p>package org.hibernate.auction;<br />import java.util.*;</p>
				<p>/**<br /> * @author Administrator<br /> *<br /> * To change the template for this generated type comment go to<br /> * Window&amp;gt;Preferences&amp;gt;Java&amp;gt;Code Generation&amp;gt;Code and Comments<br /> */<br />public class TestA {<br /> int id;<br /> String name;<br /> Set testBs=new HashSet();<br /> public TestA(){<br />  <br /> }<br /> public TestA(int id){<br />  setId(id);<br /> }<br /> public int getId(){<br />  return id;<br /> }<br /> public void setId(int id){<br />  this.id=id;<br /> }<br /> public String getName(){<br />  return name;<br /> }<br /> public void setName(String name){<br />  this.name=name;<br /> }<br /> public Set getTestBs(){<br />  return testBs;<br /> }<br /> public void setTestBs(Set s){<br />  testBs=s;<br /> }<br /> public void addTestB(TestB tb){<br />  testBs.add(tb);<br /> }</p>
				<p> public static void main(String[] args) {<br /> }<br />}<br /></p>
				<p>public class TestB {</p>
				<p>
						<br /> int id;<br /> String name;<br /> Set testAs=new HashSet();<br /> public TestB(){<br />  <br /> }<br /> public TestB(int id){<br />  setId(id);<br /> }<br /> public int getId(){<br />  return id;<br /> }<br /> public void setId(int id){<br />  this.id=id;<br /> }<br /> public String getName(){<br />  return name;<br /> }<br /> public void setName(String name){<br />  this.name=name;<br /> }<br /> public Set getTestAs(){<br />  return testAs;<br /> }<br /> public void setTestAs(Set s){<br />  testAs=s;<br /> }<br /> public void addTestA(TestA ta){<br />  testAs.add(ta);<br /> }<br /> public static void main(String[] args) {<br /> }<br />}</p>
				<p>测试代码：</p>
				<p>public void doTest() throws Exception{<br />  TestA a1=new TestA(1);<br />  TestA a2=new TestA(2);<br />  TestA a3=new TestA(3);<br />  TestB b1=new TestB(1);<br />  TestB b2=new TestB(2);<br />  TestB b3=new TestB(3);<br />  a1.addTestB(b1);<br />  a1.addTestB(b2);<br />  a1.addTestB(b3);<br />  b1.addTestA(a1);<br />  b2.addTestA(a2);<br />  <br />  Session s = factory.openSession();<br />  <br />  s = factory.openSession();<br />  <br />  <br />  Session session = factory.openSession(); <br />  session.save(a1); <br />  session.flush(); <br />  session.close(); </p>
				<p> }</p>
				<p>测试后连接表的数据为：</p>
				<p>testa              testb</p>
				<p>1                  1</p>
				<p>1                  2</p>
				<p>1                  3</p>
				<p>根据inverse规则，对这些代码：b2.addTestA(a1);  b2.addTestA(a2); 建立的关系，数据库并没有存储下来，因为TestB没有责任维护这些关系，所以产生的sql语句自然不会有针对Testa_testB表的操作了。假设应用中真的需要这些方法，那么我们可以修改TestB的方法，让他们注意在维护端类中执行相应的操作以使得关系能够在数据库中保存下来，更改TestB如下：</p>
				<p>/*<br /> * Created on 2004-7-25<br /> *<br /> * To change the template for this generated file go to<br /> * Window&amp;gt;Preferences&amp;gt;Java&amp;gt;Code Generation&amp;gt;Code and Comments<br /> */<br />package org.hibernate.auction;<br />import java.util.*;</p>
				<p>/**<br /> * @author Administrator<br /> *<br /> * To change the template for this generated type comment go to<br /> * Window&amp;gt;Preferences&amp;gt;Java&amp;gt;Code Generation&amp;gt;Code and Comments<br /> */<br />public class TestB {</p>
				<p>
						<br /> int id;<br /> String name;<br /> Set testAs=new HashSet();<br /> public TestB(){<br />  <br /> }<br /> public TestB(int id){<br />  setId(id);<br /> }<br /> public int getId(){<br />  return id;<br /> }<br /> public void setId(int id){<br />  this.id=id;<br /> }<br /> public String getName(){<br />  return name;<br /> }<br /> public void setName(String name){<br />  this.name=name;<br /> }<br /> public Set getTestAs(){<br />  return testAs;<br /> }<br /> public void setTestAs(Set s){<br />  testAs=s;<br /> }<br /> public void addTestA(TestA ta){<br />  testAs.add(ta);<br />  <font color="#ff0066">ta.addTestB(this);<br /></font> }<br /> public static void main(String[] args) {<br /> }<br />}<br />那么测试执行后连接表的数据为：</p>
				<p>testa          testb</p>
				<p>1               2</p>
				<p>1               3</p>
				<p>1                1</p>
				<p>2                 2</p>
				<p>测试通过。<br /></p>
		</div>
<img src ="http://www.blogjava.net/ocean07000814/aggbug/86128.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ocean07000814/" target="_blank">非洲小白脸</a> 2006-12-07 17:05 <a href="http://www.blogjava.net/ocean07000814/articles/86128.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Hibernate QBC的查询方式的总结</title><link>http://www.blogjava.net/ocean07000814/articles/72601.html</link><dc:creator>非洲小白脸</dc:creator><author>非洲小白脸</author><pubDate>Thu, 28 Sep 2006 07:52:00 GMT</pubDate><guid>http://www.blogjava.net/ocean07000814/articles/72601.html</guid><wfw:comment>http://www.blogjava.net/ocean07000814/comments/72601.html</wfw:comment><comments>http://www.blogjava.net/ocean07000814/articles/72601.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ocean07000814/comments/commentRss/72601.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ocean07000814/services/trackbacks/72601.html</trackback:ping><description><![CDATA[
		<h1 class="block_title">
				<a id="viewpost1_TitleUrl" href="/yesjoy/articles/65782.html">Hibernate QBC的查询方式的总结</a>
		</h1>
		<div class="post">
				<div class="postcontent">
						<p> </p>
						<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
								<span style="COLOR: #008080"> 1</span>
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
								<span style="COLOR: #000000">        Criteria criteria </span>
								<span style="COLOR: #808080">=</span>
								<span style="COLOR: #000000"> this.getSession().createCriteria(EquipmentPO.class);<br /></span>
								<span style="COLOR: #008080"> 2</span>
								<span style="COLOR: #000000">
										<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        criteria.</span>
								<span style="COLOR: #0000ff">add</span>
								<span style="COLOR: #000000">(Restrictions.allEq(new Map(Restrictions.eq("equipID",new String("</span>
								<span style="FONT-WEIGHT: bold; COLOR: #800000">11020449</span>
								<span style="COLOR: #000000">")),Restrictions.eq("equipID",new String("</span>
								<span style="FONT-WEIGHT: bold; COLOR: #800000">11020449</span>
								<span style="COLOR: #000000">"))));        <br /></span>
								<span style="COLOR: #008080"> 3</span>
								<span style="COLOR: #000000">
										<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span>
								<span style="COLOR: #808080">//</span>
								<span style="COLOR: #000000">注意：between查询条件可解释为查询EquipmentPO对象中的equipID属性值在new String("</span>
								<span style="FONT-WEIGHT: bold; COLOR: #800000">11020449</span>
								<span style="COLOR: #000000">")和new String("</span>
								<span style="FONT-WEIGHT: bold; COLOR: #800000">11030137</span>
								<span style="COLOR: #000000">")之间的所有记录值（包含两个端点）<br /></span>
								<span style="COLOR: #008080"> 4</span>
								<span style="COLOR: #000000">
										<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        criteria.</span>
								<span style="COLOR: #0000ff">add</span>
								<span style="COLOR: #000000">(Restrictions.</span>
								<span style="COLOR: #808080">between</span>
								<span style="COLOR: #000000">("equipID",new String("</span>
								<span style="FONT-WEIGHT: bold; COLOR: #800000">11020449</span>
								<span style="COLOR: #000000">"),new String("</span>
								<span style="FONT-WEIGHT: bold; COLOR: #800000">11030137</span>
								<span style="COLOR: #000000">")));<br /></span>
								<span style="COLOR: #008080"> 5</span>
								<span style="COLOR: #000000">
										<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span>
								<span style="COLOR: #808080">//</span>
								<span style="COLOR: #000000">查询结果列表记录按照equipID的属性值来升序排序<br /></span>
								<span style="COLOR: #008080"> 6</span>
								<span style="COLOR: #000000">
										<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        criteria.addOrder(</span>
								<span style="COLOR: #0000ff">Order</span>
								<span style="COLOR: #000000">.</span>
								<span style="COLOR: #0000ff">asc</span>
								<span style="COLOR: #000000">("equipID"));</span>
								<span style="COLOR: #808080">//</span>
								<span style="COLOR: #000000">降序方式为：</span>
								<span style="COLOR: #0000ff">Order</span>
								<span style="COLOR: #000000">.</span>
								<span style="COLOR: #0000ff">desc</span>
								<span style="COLOR: #000000">("equipID")        <br /></span>
								<span style="COLOR: #008080"> 7</span>
								<span style="COLOR: #000000">
										<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span>
								<span style="COLOR: #808080">//</span>
								<span style="COLOR: #000000">通过EquipmentPO对象的主键id来查询<br /></span>
								<span style="COLOR: #008080"> 8</span>
								<span style="COLOR: #000000">
										<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        criteria.</span>
								<span style="COLOR: #0000ff">add</span>
								<span style="COLOR: #000000">(Restrictions.idEq("402882ac0d3f7ca8010d3f7ef869000b"));        <br /></span>
								<span style="COLOR: #008080"> 9</span>
								<span style="COLOR: #000000">
										<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        Restrictions.</span>
								<span style="COLOR: #808080">like</span>
								<span style="COLOR: #000000">(fieldName, "</span>
								<span style="COLOR: #808080">%</span>
								<span style="COLOR: #000000">" </span>
								<span style="COLOR: #808080">+</span>
								<span style="COLOR: #000000"> para</span>
								<span style="COLOR: #808080">+</span>
								<span style="COLOR: #000000"> "</span>
								<span style="COLOR: #808080">%</span>
								<span style="COLOR: #000000">")<br /></span>
								<span style="COLOR: #008080">10</span>
								<span style="COLOR: #000000">
										<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span>
								<span style="COLOR: #808080">//</span>
								<span style="COLOR: #000000">使用ilike方式进行模糊查询<br /></span>
								<span style="COLOR: #008080">11</span>
								<span style="COLOR: #000000">
										<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        criteria.</span>
								<span style="COLOR: #0000ff">add</span>
								<span style="COLOR: #000000">(Restrictions.ilike("equipID",new String("</span>
								<span style="COLOR: #808080">%</span>
								<span style="FONT-WEIGHT: bold; COLOR: #800000">11020</span>
								<span style="COLOR: #808080">%</span>
								<span style="COLOR: #000000">")));<br /></span>
								<span style="COLOR: #008080">12</span>
								<span style="COLOR: #000000">
										<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span>
								<span style="COLOR: #808080">//</span>
								<span style="COLOR: #000000">ilike的i即ignore之意,所以这里查询出englishName值为"Optima XL 100K Ultracentrifuge"（忽略大小写）的记录<br /></span>
								<span style="COLOR: #008080">13</span>
								<span style="COLOR: #000000">
										<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        criteria.</span>
								<span style="COLOR: #0000ff">add</span>
								<span style="COLOR: #000000">(Restrictions.ilike("englishName",new String("Optima XL 100K Ultracentrifuge"),MatchMode.ANYWHERE));</span>
								<span style="COLOR: #808080">//</span>
								<span style="COLOR: #000000">这里        <br /></span>
								<span style="COLOR: #008080">14</span>
								<span style="COLOR: #000000">
										<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span>
								<span style="COLOR: #808080">//</span>
								<span style="COLOR: #000000">使用in方式有两种形式，即数组或者Collection的方式，可参考如下两个实例<br /></span>
								<span style="COLOR: #008080">15</span>
								<span style="COLOR: #000000">
										<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span>
								<span style="COLOR: #808080">//</span>
								<span style="COLOR: #000000">criteria.</span>
								<span style="COLOR: #0000ff">add</span>
								<span style="COLOR: #000000">(Restrictions.</span>
								<span style="COLOR: #808080">in</span>
								<span style="COLOR: #000000">("equipID",new String</span>
								<span style="COLOR: #ff0000">[]</span>
								<span style="COLOR: #000000">{"</span>
								<span style="FONT-WEIGHT: bold; COLOR: #800000">11020449</span>
								<span style="COLOR: #000000">","</span>
								<span style="FONT-WEIGHT: bold; COLOR: #800000">11020450</span>
								<span style="COLOR: #000000">"}));</span>
								<span style="COLOR: #808080">//</span>
								<span style="COLOR: #000000">数组参数<br /></span>
								<span style="COLOR: #008080">16</span>
								<span style="COLOR: #000000">
										<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        Collection col </span>
								<span style="COLOR: #808080">=</span>
								<span style="COLOR: #000000"> new ArrayList();<br /></span>
								<span style="COLOR: #008080">17</span>
								<span style="COLOR: #000000">
										<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        col.</span>
								<span style="COLOR: #0000ff">add</span>
								<span style="COLOR: #000000">(new String("</span>
								<span style="FONT-WEIGHT: bold; COLOR: #800000">11020449</span>
								<span style="COLOR: #000000">"));<br /></span>
								<span style="COLOR: #008080">18</span>
								<span style="COLOR: #000000">
										<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        col.</span>
								<span style="COLOR: #0000ff">add</span>
								<span style="COLOR: #000000">(new String("</span>
								<span style="FONT-WEIGHT: bold; COLOR: #800000">11020450</span>
								<span style="COLOR: #000000">"));<br /></span>
								<span style="COLOR: #008080">19</span>
								<span style="COLOR: #000000">
										<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        col.</span>
								<span style="COLOR: #0000ff">add</span>
								<span style="COLOR: #000000">(new String("</span>
								<span style="FONT-WEIGHT: bold; COLOR: #800000">11020874</span>
								<span style="COLOR: #000000">"));<br /></span>
								<span style="COLOR: #008080">20</span>
								<span style="COLOR: #000000">
										<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        criteria.</span>
								<span style="COLOR: #0000ff">add</span>
								<span style="COLOR: #000000">(Restrictions.</span>
								<span style="COLOR: #808080">in</span>
								<span style="COLOR: #000000">("equipID",col));</span>
								<span style="COLOR: #808080">//</span>
								<span style="COLOR: #000000">Collection参数        <br /></span>
								<span style="COLOR: #008080">21</span>
								<span style="COLOR: #000000">
										<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span>
								<span style="COLOR: #808080">//</span>
								<span style="COLOR: #000000">使用isEmpty</span>
								<span style="COLOR: #808080">/</span>
								<span style="COLOR: #000000">isNotEmpty方式用来判断EquipmentPO对象中的Collection类型的属性是否为空的所有记录<br /></span>
								<span style="COLOR: #008080">22</span>
								<span style="COLOR: #000000">
										<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span>
								<span style="COLOR: #808080">//</span>
								<span style="COLOR: #000000">EquipmentPO对象中定义属性private </span>
								<span style="COLOR: #0000ff">Set</span>
								<span style="COLOR: #000000"> equipFunctionDevelopPOs </span>
								<span style="COLOR: #808080">=</span>
								<span style="COLOR: #000000"> new HashSet(); </span>
								<span style="COLOR: #808080">//</span>
								<span style="COLOR: #000000"> 设备功能开发对象<br /></span>
								<span style="COLOR: #008080">23</span>
								<span style="COLOR: #000000">
										<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        criteria.</span>
								<span style="COLOR: #0000ff">add</span>
								<span style="COLOR: #000000">(Restrictions.isEmpty("equipFunctionDevelopPOs"));<br /></span>
								<span style="COLOR: #008080">24</span>
								<span style="COLOR: #000000">
										<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        criteria.</span>
								<span style="COLOR: #0000ff">add</span>
								<span style="COLOR: #000000">(Restrictions.isNotEmpty("equipFunctionDevelopPOs"));<br /></span>
								<span style="COLOR: #008080">25</span>
								<span style="COLOR: #000000">
										<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span>
								<span style="COLOR: #808080">//</span>
								<span style="COLOR: #000000">使用isNull方式查询出所有schoolID属性没有值的记录。说明：Restrictions.isNull判断属性是否为空，为空返回true，反之返回false<br /></span>
								<span style="COLOR: #008080">26</span>
								<span style="COLOR: #000000">
										<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        criteria.</span>
								<span style="COLOR: #0000ff">add</span>
								<span style="COLOR: #000000">(Restrictions.</span>
								<span style="COLOR: #ff00ff">isNull</span>
								<span style="COLOR: #000000">("schoolID"));<br /></span>
								<span style="COLOR: #008080">27</span>
								<span style="COLOR: #000000">
										<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        criteria.</span>
								<span style="COLOR: #0000ff">add</span>
								<span style="COLOR: #000000">(Restrictions.isNotNull("schoolID"));        <br /></span>
								<span style="COLOR: #008080">28</span>
								<span style="COLOR: #000000">
										<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span>
								<span style="COLOR: #808080">//</span>
								<span style="COLOR: #000000">与Restrictions.eq正好相反，表示不存在(</span>
								<span style="COLOR: #808080">not</span>
								<span style="COLOR: #000000"> </span>
								<span style="COLOR: #808080">in</span>
								<span style="COLOR: #000000">)<br /></span>
								<span style="COLOR: #008080">29</span>
								<span style="COLOR: #000000">
										<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        criteria.</span>
								<span style="COLOR: #0000ff">add</span>
								<span style="COLOR: #000000">(Restrictions.</span>
								<span style="COLOR: #808080">not</span>
								<span style="COLOR: #000000">(Restrictions.eq("equipID",new String("</span>
								<span style="FONT-WEIGHT: bold; COLOR: #800000">11020449</span>
								<span style="COLOR: #000000">"))));<br /></span>
								<span style="COLOR: #008080">30</span>
								<span style="COLOR: #000000">
										<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span>
								<span style="COLOR: #808080">//</span>
								<span style="COLOR: #000000">使用Restrictions.sizeEq方式用来查询EquipmentPO对象中的Collection类型的属性equipFunctionDevelopPOs的size为1的所有记录<br /></span>
								<span style="COLOR: #008080">31</span>
								<span style="COLOR: #000000">
										<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        criteria.</span>
								<span style="COLOR: #0000ff">add</span>
								<span style="COLOR: #000000">(Restrictions.sizeEq("equipFunctionDevelopPOs",</span>
								<span style="FONT-WEIGHT: bold; COLOR: #800000">1</span>
								<span style="COLOR: #000000">));        <br /></span>
								<span style="COLOR: #008080">32</span>
								<span style="COLOR: #000000">
										<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span>
								<span style="COLOR: #808080">//</span>
								<span style="COLOR: #000000">使用sql限定的查询。注意{alias}.chnname这里是指实际表中的字段名而非属性名（不区分大小写）<br /></span>
								<span style="COLOR: #008080">33</span>
								<span style="COLOR: #000000">
										<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        criteria.</span>
								<span style="COLOR: #0000ff">add</span>
								<span style="COLOR: #000000">(Restrictions.sqlRestriction("{alias}.chnname </span>
								<span style="COLOR: #808080">like</span>
								<span style="COLOR: #000000"> (?)","</span>
								<span style="COLOR: #808080">%</span>
								<span style="COLOR: #000000">电</span>
								<span style="COLOR: #808080">%</span>
								<span style="COLOR: #000000">",Hibernate.STRING));<br /></span>
								<span style="COLOR: #008080">34</span>
								<span style="COLOR: #000000">
										<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        criteria.</span>
								<span style="COLOR: #0000ff">add</span>
								<span style="COLOR: #000000">(Restrictions.sqlRestriction("{alias}.ENGNAME </span>
								<span style="COLOR: #808080">like</span>
								<span style="COLOR: #000000"> (?)","</span>
								<span style="COLOR: #808080">%</span>
								<span style="COLOR: #000000">ptima</span>
								<span style="COLOR: #808080">%</span>
								<span style="COLOR: #000000">",Hibernate.STRING));<br /></span>
								<span style="COLOR: #008080">35</span>
								<span style="COLOR: #000000">
										<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span>
								<span style="COLOR: #808080">//</span>
								<span style="COLOR: #000000">如果有多个查询条件，比如between子句的查询则如下：        <br /></span>
								<span style="COLOR: #008080">36</span>
								<span style="COLOR: #000000">
										<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        BigDecimal</span>
								<span style="COLOR: #ff0000">[]</span>
								<span style="COLOR: #000000"> unitPrice </span>
								<span style="COLOR: #808080">=</span>
								<span style="COLOR: #000000"> {new BigDecimal(</span>
								<span style="FONT-WEIGHT: bold; COLOR: #800000">402514</span>
								<span style="COLOR: #000000">),new BigDecimal(</span>
								<span style="FONT-WEIGHT: bold; COLOR: #800000">614891</span>
								<span style="COLOR: #000000">)};<br /></span>
								<span style="COLOR: #008080">37</span>
								<span style="COLOR: #000000">
										<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        Type</span>
								<span style="COLOR: #ff0000">[]</span>
								<span style="COLOR: #000000"> types </span>
								<span style="COLOR: #808080">=</span>
								<span style="COLOR: #000000"> {Hibernate.BIG_DECIMAL,Hibernate.BIG_DECIMAL};<br /></span>
								<span style="COLOR: #008080">38</span>
								<span style="COLOR: #000000">
										<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        criteria.</span>
								<span style="COLOR: #0000ff">add</span>
								<span style="COLOR: #000000">(Restrictions.sqlRestriction("{alias}.unit_price </span>
								<span style="COLOR: #808080">between</span>
								<span style="COLOR: #000000"> (?) </span>
								<span style="COLOR: #808080">and</span>
								<span style="COLOR: #000000"> (?)",unitPrice,types));<br /></span>
								<span style="COLOR: #008080">39</span>
								<span style="COLOR: #000000">
										<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        List list </span>
								<span style="COLOR: #808080">=</span>
								<span style="COLOR: #000000"> criteria.list();<br /></span>
								<span style="COLOR: #008080">40</span>
								<span style="COLOR: #000000">
										<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        System.out.println("size</span>
								<span style="COLOR: #808080">===&gt;</span>
								<span style="COLOR: #000000">" </span>
								<span style="COLOR: #808080">+</span>
								<span style="COLOR: #000000"> list.size());<br /></span>
								<span style="COLOR: #008080">41</span>
								<span style="COLOR: #000000">
										<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span>
								<span style="COLOR: #0000ff">return</span>
								<span style="COLOR: #000000"> list;</span>
						</div>
				</div>
		</div>
<img src ="http://www.blogjava.net/ocean07000814/aggbug/72601.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ocean07000814/" target="_blank">非洲小白脸</a> 2006-09-28 15:52 <a href="http://www.blogjava.net/ocean07000814/articles/72601.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于Hibernate3的NativeSQL查询是如此简单 </title><link>http://www.blogjava.net/ocean07000814/articles/72585.html</link><dc:creator>非洲小白脸</dc:creator><author>非洲小白脸</author><pubDate>Thu, 28 Sep 2006 07:14:00 GMT</pubDate><guid>http://www.blogjava.net/ocean07000814/articles/72585.html</guid><wfw:comment>http://www.blogjava.net/ocean07000814/comments/72585.html</wfw:comment><comments>http://www.blogjava.net/ocean07000814/articles/72585.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ocean07000814/comments/commentRss/72585.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ocean07000814/services/trackbacks/72585.html</trackback:ping><description><![CDATA[
		<div class="postTitle">
				<a href="http://blog.csdn.net/newfox/archive/2006/05/26/756010.aspx">
						<img height="13" src="http://blog.csdn.net/images/authorship.gif" width="15" border="0" /> 关于Hibernate3的NativeSQL查询是如此简单 </a>
		</div>
		<div class="postText">现在的系统中虽然使用了。Hibernate但是没有使用Hibernate的关联关系来进行数据库操作。所有的管理操作都是单独实现的。所以也不能用Criteria.add()这种方式去查询关联的一方。所以只能用Native SQL去查询结果返回对象了。按照Hibernate3的reference里面说的<br /><div class="sect1" lang="zh-cn"><div class="titlepage"><div><div><h2 class="title" style="CLEAR: both"><font color="#006400">16.1. 使用<tt class="literal">SQLQuery</tt></font></h2></div></div></div><p><font color="#006400">对原生SQL查询执行的控制是通过<tt class="literal">SQLQuery</tt>接口进行的，通过执行<tt class="literal">Session.createSQLQuery()</tt>获取这个接口。最简单的情况下，我们可以采用以下形式：</font></p><pre class="programlisting"><font color="#006400">List cats = sess.createSQLQuery("select * from cats")<br />    .addEntity(Cat.class)<br />    .list();</font></pre><p><font color="#006400">这个查询指定了:</font></p><div class="itemizedlist"><ul type="disc"><li><p><font color="#006400">SQL查询字符串</font></p></li><li><p><font color="#006400">查询返回的实体</font></p></li></ul></div><p><font color="#006400">这里，结果集字段名被假设为与映射文件中指明的字段名相同。对于连接了多个表的查询，这就可能造成问题，因为可能在多个表中出现同样名字的字段。下面的方法就可以避免字段名重复的问题:</font></p><pre class="programlisting"><font color="#006400">List cats = sess.createSQLQuery("select {cat.*} from cats cat")<br />    .addEntity("cat", Cat.class)<br />    .list();</font></pre><p><font color="#006400">这个查询指定了: </font></p><div class="itemizedlist"><ul type="disc"><li><p><font color="#006400">SQL查询语句，它带一个占位符，可以让Hibernate使用字段的别名. </font></p></li><li><p><font color="#006400">查询返回的实体，和它的SQL表的别名. </font></p></li></ul></div><p><font color="#006400"><tt class="literal">addEntity()</tt>方法将SQL表的别名和实体类联系起来，并且确定查询结果集的形态。 </font></p><p><font color="#006400"><tt class="literal">addJoin()</tt>方法可以被用于载入其他的实体和集合的关联. </font></p><pre class="programlisting"><font color="#006400">List cats = sess.createSQLQuery(<br />        "select {cat.*}, {kitten.*} from cats cat, cats kitten where kitten.mother = cat.id"<br />    )<br />    .addEntity("cat", Cat.class)<br />    .addJoin("kitten", "cat.kittens")<br />    .list();</font></pre><p><font color="#006400">原生的SQL查询可能返回一个简单的标量值或者一个标量和实体的结合体。 </font></p><pre class="programlisting"><font color="#006400">Double max = (Double) sess.createSQLQuery("select max(cat.weight) as maxWeight from cats cat")<br />        .addScalar("maxWeight", Hibernate.DOUBLE);<br />        .uniqueResult();</font></pre><p><font color="#006400">除此之外，你还可以在你的hbm文件中描述结果集映射信息，在查询中使用。</font></p><pre class="programlisting"><font color="#006400">List cats = sess.createSQLQuery(<br />        "select {cat.*}, {kitten.*} from cats cat, cats kitten where kitten.mother = cat.id"<br />    )<br />    .setResultSetMapping("catAndKitten")<br />    .list();<br /></font></pre></div><br />后来我使用了命名SQL查询方式。<br /><div class="titlepage"><div><div><h2 class="title" style="CLEAR: both"><font color="#006400">16.3. 命名SQL查询</font></h2></div></div></div><p><font color="#006400">可以在映射文档中定义查询的名字,然后就可以象调用一个命名的HQL查询一样直接调用命名SQL查询.在这种情况下,我们<span class="emphasis"><em>不</em></span> 需要调用<tt class="literal">addEntity()</tt>方法. </font></p><pre class="programlisting"><font color="#006400">&lt;sql-query name="persons"&gt;<br />    &lt;return alias="person" class="eg.Person"/&gt;<br />    SELECT person.NAME AS {person.name},<br />           person.AGE AS {person.age},<br />           person.SEX AS {person.sex}<br />    FROM PERSON person<br />    WHERE person.NAME LIKE :namePattern<br />&lt;/sql-query&gt;</font></pre><pre class="programlisting"><font color="#006400">List people = sess.getNamedQuery("persons")<br />    .setString("namePattern", namePattern)<br />    .setMaxResults(50)<br />    .list();</font><br /><br />我觉得这种发式比较好。这样写出来的sql可以很整齐。我们的数据库使用的是oracle，不过按照这上面的写法发现sql语句有错误。<br />后来拿到控制台执行也抱错。因为原来都用sqlserver，而sqlserver都是可以的。后来发现是表不能有别名改成这样就好了。<br /><div style="BORDER-RIGHT: rgb(204,204,204) 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: rgb(204,204,204) 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: rgb(204,204,204) 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: rgb(204,204,204) 1px solid; BACKGROUND-COLOR: rgb(238,238,238)"><span style="COLOR: rgb(0,0,0)">            </span><span style="COLOR: rgb(0,0,255)">SELECT</span><span style="COLOR: rgb(0,0,0)"> T_PAY.sys_id </span><span style="COLOR: rgb(0,0,255)">as</span><span style="COLOR: rgb(0,0,0)"> {pay.sysId},<br />                   T_PAY.sys_flag </span><span style="COLOR: rgb(0,0,255)">as</span><span style="COLOR: rgb(0,0,0)"> {pay.sysFlag},<br />                   T_PAY.sys_domain </span><span style="COLOR: rgb(0,0,255)">as</span><span style="COLOR: rgb(0,0,0)"> {pay.sysDomain},<br />                   T_PAY.sys_owner </span><span style="COLOR: rgb(0,0,255)">as</span><span style="COLOR: rgb(0,0,0)"> {pay.sysOwner},<br />                   T_PAY.sys_create_date </span><span style="COLOR: rgb(0,0,255)">as</span><span style="COLOR: rgb(0,0,0)"> {pay.sysCreateDate},<br />                   T_PAY.sys_update_date </span><span style="COLOR: rgb(0,0,255)">as</span><span style="COLOR: rgb(0,0,0)"> {pay.sysUpdateDate},<br />                   T_PAY.pay_id </span><span style="COLOR: rgb(0,0,255)">as</span><span style="COLOR: rgb(0,0,0)"> {pay.payId},<br />                   T_PAY.pay_name </span><span style="COLOR: rgb(0,0,255)">as</span><span style="COLOR: rgb(0,0,0)"> {pay.payName},<br />                   T_PAY.pay_type_id </span><span style="COLOR: rgb(0,0,255)">as</span><span style="COLOR: rgb(0,0,0)"> {pay.payTypeId},<br />                   T_PAY.pay_date </span><span style="COLOR: rgb(0,0,255)">as</span><span style="COLOR: rgb(0,0,0)"> {pay.payDate},<br />                   T_PAY.money_type_id </span><span style="COLOR: rgb(0,0,255)">as</span><span style="COLOR: rgb(0,0,0)"> {pay.moneyTypeId},<br />                   T_PAY.amount </span><span style="COLOR: rgb(0,0,255)">as</span><span style="COLOR: rgb(0,0,0)"> {pay.amount},<br />                   T_PAY.payer_id </span><span style="COLOR: rgb(0,0,255)">as</span><span style="COLOR: rgb(0,0,0)"> {pay.payerId},<br />                   T_PAY.payer_name </span><span style="COLOR: rgb(0,0,255)">as</span><span style="COLOR: rgb(0,0,0)"> {pay.payerName},<br />                   T_PAY.accept_id </span><span style="COLOR: rgb(0,0,255)">as</span><span style="COLOR: rgb(0,0,0)"> {pay.acceptId},<br />                   T_PAY.accept_name </span><span style="COLOR: rgb(0,0,255)">as</span><span style="COLOR: rgb(0,0,0)"> {pay.acceptName},<br />                   T_PAY.pay_state_id </span><span style="COLOR: rgb(0,0,255)">as</span><span style="COLOR: rgb(0,0,0)"> {pay.payStateId},<br />                   T_PAY.remark </span><span style="COLOR: rgb(0,0,255)">as</span><span style="COLOR: rgb(0,0,0)"> {pay.remark}<br />            </span><span style="COLOR: rgb(0,0,255)">FROM</span><span style="COLOR: rgb(0,0,0)">   T_PAY<br />            </span><span style="COLOR: rgb(0,0,255)">JOIN</span><span style="COLOR: rgb(0,0,0)">   T_BIZ_PAY<br />            </span><span style="COLOR: rgb(0,0,255)">ON</span><span style="COLOR: rgb(0,0,0)">       T_PAY.pay_id </span><span style="COLOR: rgb(128,128,128)">=</span><span style="COLOR: rgb(0,0,0)"> T_BIZ_PAY.pay_id<br />            </span><span style="COLOR: rgb(0,0,255)">WHERE</span><span style="COLOR: rgb(0,0,0)">  T_BIZ_PAY.biz_id </span><span style="COLOR: rgb(128,128,128)">=</span><span style="COLOR: rgb(0,0,0)"> :bizId</span></div></pre>  <strong>这里要特别的提醒一下大家千万不要把主键忘了。刚开始我就忘了主键，后来调试了半天才找出原因来。<br /></strong><br />这样在sping里面用回调查询一下就ok了。真的很方便.<br /><div style="BORDER-RIGHT: rgb(204,204,204) 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: rgb(204,204,204) 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: rgb(204,204,204) 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: rgb(204,204,204) 1px solid; BACKGROUND-COLOR: rgb(238,238,238)"><span style="COLOR: rgb(0,0,0)">    </span><span style="COLOR: rgb(0,0,255)">public</span><span style="COLOR: rgb(0,0,0)"> List getPaysByBizId(</span><span style="COLOR: rgb(0,0,255)">final</span><span style="COLOR: rgb(0,0,0)"> String bizId) {<br />        </span><span style="COLOR: rgb(0,0,255)">return</span><span style="COLOR: rgb(0,0,0)"> (List)getHibernateTemplate().execute(</span><span style="COLOR: rgb(0,0,255)">new</span><span style="COLOR: rgb(0,0,0)"> HibernateCallback(){<br />            </span><span style="COLOR: rgb(0,0,255)">public</span><span style="COLOR: rgb(0,0,0)"> Object doInHibernate(Session session)</span><span style="COLOR: rgb(0,0,255)">throws</span><span style="COLOR: rgb(0,0,0)"> HibernateException{<br />                Query query </span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)"> session.getNamedQuery(</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">find.pays.by.bizid</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">);<br />                query.setParameter(</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">bizId</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">,bizId);<br />                </span><span style="COLOR: rgb(0,0,255)">return</span><span style="COLOR: rgb(0,0,0)"> query.list();<br />            }<br />        },</span><span style="COLOR: rgb(0,0,255)">true</span><span style="COLOR: rgb(0,0,0)">);<br />    }</span></div></div>
<img src ="http://www.blogjava.net/ocean07000814/aggbug/72585.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ocean07000814/" target="_blank">非洲小白脸</a> 2006-09-28 15:14 <a href="http://www.blogjava.net/ocean07000814/articles/72585.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Hibernate综合查询解决方案(转)</title><link>http://www.blogjava.net/ocean07000814/articles/70713.html</link><dc:creator>非洲小白脸</dc:creator><author>非洲小白脸</author><pubDate>Wed, 20 Sep 2006 02:22:00 GMT</pubDate><guid>http://www.blogjava.net/ocean07000814/articles/70713.html</guid><wfw:comment>http://www.blogjava.net/ocean07000814/comments/70713.html</wfw:comment><comments>http://www.blogjava.net/ocean07000814/articles/70713.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ocean07000814/comments/commentRss/70713.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ocean07000814/services/trackbacks/70713.html</trackback:ping><description><![CDATA[
		<h1 style="FONT-SIZE: 14pt" align="center">Hibernate综合查询解决方案</h1>
		<table cellspacing="3" cellpadding="5" width="90%" align="center" border="0">
				<tbody>
						<tr>
								<td>
								</td>
						</tr>
						<tr>
								<td>
										<h2>
												<font size="3">这两个星期以来，我把原来用struts开发的一个测试工具改用struts+hibernate来实现，首先从心情上来，整个开发过程中始终保持愉快和平和，“原来开发可以这样愉快？”，再一点就是开发效率上高效了许多。<br />      现在sun又加入jdocentral.com开始着手JDO2.0，想想看等它出台以后将是一个怎样激动人心得场面，让我们拭目以待。<br />      <br />      用Hibernate来操纵持久数据非常简单，在这里一些简单的查询我会一笔带过，本文着重说明在综合查询兼有分页的时候我的一些经验，如果网友觉得我的方案还有不足的地方，也请和我讨论，我的email:plateau_t@sina.com.<br />      <br />      第一部分：Hibernate提供的查询接口或其方法（此部分不做深究，请参考hibernate手册）<br />      <br />       1。根据ID查询<br />    要用到Session接口的load方法。<br />    load(Class theClass, Serializable id) <br />    load(Class theClass, Serializable id, LockMode lockMode)<br />    load(Object object, Serializable id)  <br />    <br />       2。HQL语句进行查询<br />       <br />       2。1 利用Query接口，Query由Session里的createQuery()来产生一个查询<br />        1)不带参数的查询（这类比较简单）<br />        Query query=session.createQuery("select user from User as user");<br />        2)带参数的查询<br />        Query query=session.createQuery("select user from User as user where user.name=?");<br />        query.setString(0,name)//假设name为传过来的参数<br />        Query query=session.createQuery("select user from User as user where user.name=:name");<br />        query.setString("name",name)//假设name为传过来的参数 <br />        (多个参数以此类推) <br />        <br />        利用Session接口的find查询<br />        find(String query) <br />        find(String query, Object[] values, Type[] types) <br />        find(String query, Object value, Type type)    均返回list   <br />        如:<br />        List list=session.find("select user from Users as user where user.name=?",name,Hibernate.STRING)<br />        List list=session.find("select user from Users as user where user.name=? and             user.pw=?",new Object[]{name,pw},new Type[]{Hibernate.STRING,Hibernate.STRING})<br />        <br />        {推荐使用Query的方法进行查询}   <br />        <br />      第二部分：hibernate综合查询解决方案 （此部分详细实例说明，如有不足的地方请写信给我）         <br />      <br />       大家从第一部分可以看到，带有参数的查询，必须使用到Query接口,如上边：<br />        Query query=session.createQuery("select users from Users as users where users.name=?");<br />        query.setString(0,name)//假设name为传过来的参数    <br />       但是在系统中如何才能写一个公用的查寻方法呢？咋一看，似乎是不可以的，因为每一次查询的参数不一样，参数的数量不一样（如下代码），那么我们如何提取共性呢？   <br />         Query query=session.createQuery("select users from Users as users where users.name=? and users.pw=?");<br />        query.setString(0,name)//假设name为传过来的参数  <br />        query.setString(1,pw); <br />       <br />      首先说明，我的解决方案是从Seesion接口的find方法找到出口的，如下为Session接口得find()方法之一：<br />        find(String query, Object[] values, Type[] types)  <br />      其中Object[]为存放参数值的数组，Type[]为存放参数类型的数组，他们的顺序是和query里“？” 的顺序是相同的。那么我为什么不用该find方法呢，因为如果有分页的情况，那么该方法将不适用。<br />    <br />      下面详细要说明的解决方案：<br />      首先我想创建三个新的对象：Paras.java（参数对象） ParasList.java（参数集合对象）HQuery.java<br />     （感谢我的同事camel提供注释良好的代码）<br />     1。Paras.java（参数对象）<br />    <br />  package com.ifreeway.homegrown.testing.waf;<br />  <br />  /**<br />   *<br />   * &lt;p&gt;Title:定义一个sql语句的条件参数类 &lt;/p&gt;<br />   * &lt;p&gt;Description: 可以使用有序的参数集合传送给sql/hql语句 &lt;/p&gt;<br />   * &lt;p&gt;Copyright: Copyright (c) 2003&lt;/p&gt;<br />   * &lt;p&gt;Company: ifreeway&lt;/p&gt;<br />   * @author camel<br />   * @version 1.0<br />   */<br />  <br />  public class Paras {<br />   /**<br />    * 参数名称<br />    */<br />   private Object pName;<br />   /**<br />    * 参数类型编码，于java.sql.types中的类型保持一致<br />    */<br />   private int typeNo;<br />  <br />   public Object getPName() {<br />    return pName;<br />   }<br />   public void setPName(Object pName) {<br />    this.pName = pName;<br />   }<br />   public int getTypeNo() {<br />    return typeNo;<br />   }<br />   public void setTypeNo(int typeNo) {<br />    this.typeNo = typeNo;<br />   }<br />  }  <br /> <br /> 2。ParasList.java（参数集合对象） <br />  package com.ifreeway.homegrown.testing.waf;<br />  <br />  import java.util.ArrayList;<br />  <br />  /**<br />   *<br />   * &lt;p&gt;Title: 参数集合类&lt;/p&gt;<br />   * &lt;p&gt;Description: 封装sql/hql的参数到该集合类，便于处理和传递&lt;/p&gt;<br />   * &lt;p&gt;Copyright: Copyright (c) 2003&lt;/p&gt;<br />   * &lt;p&gt;Company: ifreeway&lt;/p&gt;<br />   * @author camel<br />   * @version 1.0<br />   */<br />  <br />  public class ParaList extends ArrayList {<br />  <br />    /**<br />     * 在指定位置添加一个参数对象<br />     * @param index：参数的索引值<br />     * @param p：需要加入的参数对象<br />     */<br />    public  void addParas(int index,Paras p){<br />        super.add(index,p);<br />    }<br />  <br />    /**<br />     * 在集合的最后位置添加一个参数对象<br />     * @param p：需要加入的参数对象<br />     */<br />    public void addParas(Paras p){<br />      super.add(p);<br />    }<br />  <br />    /**<br />     * 取得指定位置的参数对象<br />     * @param index：参数的索引值<br />     * @return：参数对象<br />     */<br />    public Paras getParas(int index){<br />        return (Paras)super.get(index) ;<br />    }<br />    /**<br />     * 取得指定参数的索引<br />     * @param p：参数对象<br />     * @return：参数索引<br />     */<br />    public int indexofParas(Paras p){<br />       return super.indexOf(p) ;<br />    }<br />  <br />    /**<br />     * 从集合中去掉一个指定的参数对象<br />     * @param index：参数索引<br />     */<br />    public void removeParas(int index){<br />      super.remove(index) ;<br />    } <br />  <br />  }  <br /> 3。HQuery.java<br />  package com.ifreeway.homegrown.testing.waf;<br />  <br />  <br />  /**<br />   *<br />   * &lt;p&gt;Title: HQL的语句封装类&lt;/p&gt;<br />   * &lt;p&gt;Description: 该对象封装HQL的查询语句，参数集合，排序参数，分组参数，单页起始地址  &lt;/p&gt;<br />   * &lt;p&gt;Copyright: Copyright (c) 2003&lt;/p&gt;<br />   * &lt;p&gt;Company:ifreeway &lt;/p&gt;<br />   * @author camel<br />   * @version 1.0<br />   */<br />  <br />  public class HQuery {<br />  <br />    /**<br />     * HQL查询语句<br />     */<br />    private String queryString;<br />    /**<br />     * 参数集合对象<br />     */<br />    private ParaList paralist;<br />    /**<br />     * 排序字段<br />     */<br />    private String orderby;<br />    /**<br />     * 分组字段<br />     */<br />    private String groupby;<br />    /**<br />     * 分页起始查询地址<br />     */<br />    private int pageStartNo;<br />  <br />    /**<br />     * 取得一个Hibernate的Query对象<br />     * @return：Query对象<br />     */<br />    public String getQueryString() {<br />      return queryString;<br />    }<br />  <br />    /**<br />     * 设置一个HQL查询字符串<br />     * @param queryString：查询字符串<br />     * <br />     */<br />    public void setQueryString(String queryString) {<br />   <br />     this.queryString =queryString;<br />  <br />    }<br />  <br />    /**<br />     * 取得参数集合对象<br />     * @return：参数集合对象<br />     */<br />    public ParaList getParalist() {<br />      return paralist;<br />    }<br />  <br />    /**<br />     * 设置参数集合对象<br />     * @param paralist：参数集合对象<br />     */<br />    public void setParalist(ParaList paralist) {<br />      this.paralist = paralist;<br />    }<br />  <br />    /**<br />     * 取得排序字段<br />     * @return：排序字段<br />     */<br />    public String getOrderby() {<br />      return orderby;<br />    }<br />  <br />    /**<br />     * 设置排序字段<br />     * @param orderby<br />     */<br />    public void setOrderby(String orderby) {<br />      this.orderby = orderby;<br />    }<br />  <br />    /**<br />     * 取得分组字段<br />     * @return<br />     */<br />    public String getGroupby() {<br />      return groupby;<br />    }<br />  <br />    /**<br />     * 设置分组字段<br />     * @param groupby<br />     */<br />    public void setGroupby(String groupby) {<br />      this.groupby = groupby;<br />    }<br />  <br />    /**<br />     * 取得页起始地址<br />     * @return<br />     */<br />    public int getPageStartNo() {<br />      return pageStartNo;<br />    }<br />  <br />    /**<br />     * 设置页起始地址<br />     * @param pageStartNo<br />     */<br />    public void setPageStartNo(int pageStartNo) {<br />      this.pageStartNo = pageStartNo;<br />    }<br />  } <br />  <br /> 上面三个对象的关系是：<br /> <br /> 用Paras来装载每一个查询参数<br />  Paras paras=new Paras();<br />  paras.setPName(...);<br />  paras.setTypeNo(...);<br /> 然后放在ParasList中<br />  ParasList paraslist=new ParasList();<br />  paraslist.add(paras)<br /> 最后把填充以后的ParasList集合给HQuery  <br />  HQuery hquery=new HQuery();<br />  hquery.setParalist(paraslist);<br />  <br /> 先面我们写一个公用查寻方法，来实现我们的综合查询：<br /> <br /> /**<br />  *<br />  *  综合查询，首先实例化HQuery<br />  * @see com.ifreeway.homegrown.testing.common.waf.DBHandler#find(com.ifreeway.homegrown.testing.common.waf.HQuery)<br />  */<br /> public List find(HQuery _query) throws HibernateException {<br />  List itr = null;<br />  try {<br />   StringBuffer query_str = new StringBuffer(_query.getQueryString());<br />   //是否要排序<br />   if (_query.getOrderby() != null) {<br />    query_str.append(_query.getOrderby());<br />   }<br />   //是否要分组<br />   if (_query.getGroupby() != null) {<br />    query_str.append(_query.getGroupby());<br />   }<br />   Session session = getSession();<br />   Query query = session.createQuery(query_str.toString());<br />   if (_query.getParalist() != null) {<br />    List list = _query.getParalist();<br />    for (int i = 0; i &lt; list.size(); i++) {<br />     Paras param = (Paras) list.get(i);<br />     switch (param.getTypeNo()) {//此处要根据参数类型的增加要增加相应的“case”<br />      case Types.VARCHAR :<br />       query.setString(i, param.getPName().toString());<br />       break;<br />      case Types.INTEGER :<br />       query.setInteger(<br />        i,<br />        ((Integer) param.getPName()).intValue());<br />       break;<br />      case Types.DATE :<br />       query.setDate(i, (java.sql.Date) param.getPName());<br />       break;<br />      case Types.DOUBLE :<br />       query.setDouble(<br />        i,<br />        ((Double) param.getPName()).doubleValue());<br />       break;<br />      case Types.BOOLEAN :<br />       query.setBoolean(<br />        i,<br />        ((Boolean) param.getPName()).booleanValue());<br />       break;<br />      case Types.CHAR :<br />       query.setCharacter(<br />        i,<br />        ((Character) param.getPName()).charValue());<br />       break;<br />      case Types.JAVA_OBJECT :<br />       query.setEntity(i, (BaseModel) param.getPName());<br />       break;<br />     }<br />    }<br />   }<br />   //是否存在分页，当_query.getPageStartNo()==0是不分页<br />   if (_query.getPageStartNo() != 0) {<br />    int pageno = _query.getPageStartNo();<br />    query.setFirstResult((pageno - 1) * Constants.RECORD_PER_PAGE);<br />    query.setMaxResults((pageno) * Constants.RECORD_PER_PAGE);<br />   }<br />   itr = query.list();<br />   closeSession();<br />  } catch (Exception e) {</font>
										</h2>
										<p>
												<strong>  }<br />  return itr;<br /> } <br />    <br />      好了一旦我们做好了上边的工作，查询对我们来说将是很容易的一件事情，而且可以达到公用，是不是省了许多力气？下面我将实例化一个例子来进一步说明：<br />      <br />      例子：<br />      HQuery hquery=HQuery();<br />      hquery.setQueryString("select users from Users as users where users.name=? and users.sex=?");<br />      hquery.setOrderby("order by users.age desc");<br />      <br />      //如果要分页，把当前页curpage传递给hquery<br />      hquery.setPageStartNo(curpage);<br />      <br />      //实例化参数，本例为两个参数<br />      Paras paras1=new Paras();<br />      paras1.setPName(name);<br />      paras1.setTypeNo(Types.VARCHAR);<br />      <br />      Paras paras2=new Paras();<br />      paras2.setPName(sex);<br />      paras2.setTypeNo(Types.INTEGER);<br />      <br />      ParasList paraslist=new ParasList();<br />      paraslist.add(paras1);<br />      paraslist.add(paras2);//注意顺序<br />      <br />      hquery.setParalist(paraslist);<br />      <br />      //好了，做好准备工作，调用查寻方法得到结果<br />      List list=find(hquery);<br />      <br /></strong>     </p>
								</td>
						</tr>
				</tbody>
		</table>
<img src ="http://www.blogjava.net/ocean07000814/aggbug/70713.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ocean07000814/" target="_blank">非洲小白脸</a> 2006-09-20 10:22 <a href="http://www.blogjava.net/ocean07000814/articles/70713.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Hibernate中实现one-to-many</title><link>http://www.blogjava.net/ocean07000814/articles/70702.html</link><dc:creator>非洲小白脸</dc:creator><author>非洲小白脸</author><pubDate>Wed, 20 Sep 2006 02:04:00 GMT</pubDate><guid>http://www.blogjava.net/ocean07000814/articles/70702.html</guid><wfw:comment>http://www.blogjava.net/ocean07000814/comments/70702.html</wfw:comment><comments>http://www.blogjava.net/ocean07000814/articles/70702.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ocean07000814/comments/commentRss/70702.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ocean07000814/services/trackbacks/70702.html</trackback:ping><description><![CDATA[
		<h1 style="FONT-SIZE: 14pt" align="center">Hibernate中实现one-to-many</h1>
		<table cellspacing="3" cellpadding="5" width="90%" align="center" border="0">
				<tbody>
						<tr>
								<td>
								</td>
						</tr>
						<tr>
								<td>
										<p>近两天来在研究Hibernate中的one-to-one和one-to-many的问题，做了很多试验，发现实现表关系时，在hibernate-mapping中generator的class设为uuid.hex，上述的两种关系可以实现，也就是数据库的主键设为varchar（MSSQL2000），但是主键改成int型的标识却弹出“ERROR SessionImpl:2379 - Could not synchronize database state with session”和“net.sf.hibernate.HibernateException: SQL insert, update or delete failed (row not found)”异常，百思不得其解。下面贴出主键设为uuid.hex时的实现代码：<br /><br /><font color="#ff3300">Child.hbm.xml</font><br />&lt;?xml version="1.0"?&gt;<br />&lt;!DOCTYPE hibernate-mapping SYSTEM "<a href="http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" target="_blank" rel="nofollow">http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd</a>" &gt;<br />&lt;hibernate-mapping&gt;<br />    &lt;class name="test.pojo.Child" table="child"&gt;<br />        &lt;id name="cid" column="cid" &gt;<br />            &lt;generator class="uuid.hex"/&gt;<br />        &lt;/id&gt;<br />        &lt;property name="cname" column="cname" /&gt;<br />        &lt;many-to-one name="parent" column="pid" /&gt;<br />    &lt;/class&gt;<br />&lt;/hibernate-mapping&gt;<br /><br /><font color="#ff0000">Child.java</font></p>
										<p>package test.pojo;</p>
										<p>public class Child {<br />    private String cname;<br />    private String pid;<br />    private Parent parent;<br />    private String cid;<br />    public Child() {<br />    }</p>
										<p>    public String getCid() {<br />        return cid;<br />    }</p>
										<p>    public void setCid(String cid) {<br />        this.cid = cid;<br />    }</p>
										<p>    public String getCname() {<br />        return cname;<br />    }</p>
										<p>    public void setCname(String cname) {<br />        this.cname = cname;<br />    }</p>
										<p>    public String getPid() {<br />        return pid;<br />    }</p>
										<p>    public void setPid(String pid) {<br />        this.pid = pid;<br />    }</p>
										<p>    public Parent getParent() {<br />        return parent;<br />    }</p>
										<p>    public void setParent(Parent parent) {<br />        this.parent = parent;<br />    }<br />}<br /><br /><font color="#ff0000">Parent.hbm.xml</font><br />&lt;?xml version="1.0"?&gt;<br />&lt;!DOCTYPE hibernate-mapping SYSTEM "<a href="http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" target="_blank" rel="nofollow">http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd</a>" &gt;<br />&lt;hibernate-mapping&gt;<br />    &lt;class name="test.pojo.Parent" table="parent" &gt;<br />        &lt;id name="pid" column="pid" type="integer"&gt;<br />            &lt;generator class="uuid.hex" /&gt;<br />        &lt;/id&gt;<br />        &lt;property name="pname" column="pname" /&gt;<br />        &lt;set name="child" lazy="true" inverse="true" cascade="all"&gt;<br />            &lt;key column="cid" /&gt;<br />            &lt;one-to-many class="capinfo.negroup.test.pojo.Child"/&gt;<br />        &lt;/set&gt;<br />    &lt;/class&gt;<br />&lt;/hibernate-mapping&gt;<br /><br /><font color="#ff0000"><font color="#000000"><font color="#ff0000">Parent.java</font><br />package test.pojo;</font></font></p>
										<p>
												<font color="#ff0000">
														<font color="#000000">import java.util.HashSet;</font>
												</font>
										</p>
										<p>
												<font color="#ff0000">
														<font color="#000000">public class Parent {<br />    private String pname;<br />    private java.util.Set child = new HashSet();<br />    private String pid;<br />    public Parent() {<br />    }</font>
												</font>
										</p>
										<p>
												<font color="#ff0000">
														<font color="#000000">    public String getPid() {<br />        return pid;<br />    }</font>
												</font>
										</p>
										<p>
												<font color="#ff0000">
														<font color="#000000">    public void setPid(String pid) {<br />        this.pid = pid;<br />    }</font>
												</font>
										</p>
										<p>
												<font color="#ff0000">
														<font color="#000000">    public String getPname() {<br />        return pname;<br />    }</font>
												</font>
										</p>
										<p>
												<font color="#ff0000">
														<font color="#000000">    public void setPname(String pname) {<br />        this.pname = pname;<br />    }</font>
												</font>
										</p>
										<p>
												<font color="#ff0000">
														<font color="#000000">    public java.util.Set getChild() {<br />        return child;<br />    }</font>
												</font>
										</p>
										<p>
												<font color="#ff0000">
														<font color="#000000">    public void setChild(java.util.Set child) {<br />        this.child = child;<br />    }</font>
												</font>
										</p>
										<p>
												<font color="#ff0000">
														<font color="#000000">}<br /><br /><font color="#ff0000">TestHibernate.java</font><br />package test.pojo;</font>
												</font>
										</p>
										<p>
												<font color="#ff0000">
														<font color="#000000">public class TestHibernate {<br />    public TestHibernate() {<br />    }</font>
												</font>
										</p>
										<p>
												<font color="#ff0000">
														<font color="#000000">    public static void main(String[] argv) {<br />        //先建立多的初始数据<br />        Child child = new Child();<br />        child.setCname("kerry");<br />        //再建立一的初始数据<br />        Parent parent = new Parent();<br />        parent.setPname("Kelphen");<br />        //将多的数据放入到一里<br />        parent.getChild().add(child);<br />        //再将一放到多里，这样一与多互相拥有对方<br />        child.setParent(parent);<br />        try {<br />            BaseDAOHibernate.saveObject(parent);<br />        }<br />        catch (DAOException daoe) {<br />            daoe.printStackTrace();<br />        }<br />    }<br />}<br /></font>
												</font>
										</p>
								</td>
						</tr>
				</tbody>
		</table>
<img src ="http://www.blogjava.net/ocean07000814/aggbug/70702.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ocean07000814/" target="_blank">非洲小白脸</a> 2006-09-20 10:04 <a href="http://www.blogjava.net/ocean07000814/articles/70702.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Hibernate下数据批量处理解决方案(转)</title><link>http://www.blogjava.net/ocean07000814/articles/70699.html</link><dc:creator>非洲小白脸</dc:creator><author>非洲小白脸</author><pubDate>Wed, 20 Sep 2006 01:56:00 GMT</pubDate><guid>http://www.blogjava.net/ocean07000814/articles/70699.html</guid><wfw:comment>http://www.blogjava.net/ocean07000814/comments/70699.html</wfw:comment><comments>http://www.blogjava.net/ocean07000814/articles/70699.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ocean07000814/comments/commentRss/70699.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ocean07000814/services/trackbacks/70699.html</trackback:ping><description><![CDATA[
		<h1 style="FONT-SIZE: 14pt" align="center">Hibernate下数据批量处理解决方案</h1>
		<table cellspacing="3" cellpadding="5" width="90%" align="center" border="0">
				<tbody>
						<tr>
								<td>
								</td>
						</tr>
						<tr>
								<td>
										<script type="text/javascript">
												<!--
google_ad_client = "pub-4944583547581781";
google_ad_width = 728;
google_ad_height = 90;
google_ad_format = "728x90_as";
google_ad_channel ="1429059098";
google_color_border = "FFFFFF";
google_color_bg = "FFFFFF";
google_color_link = "0000FF";
google_color_url = "000000";
google_color_text = "000000";
//-->
										</script>
										<script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript">
										</script>
很多人都对Java在批量数据的处理方面是否是其合适的场所持有怀疑的念头，由此延伸，那么就会认为ORM可能也不是特别适合数据的批量处理。 其实，我想如果我们应用得当的话，完全可以消除ORM批量处理性能问题这方面的顾虑。下面以Hibernate为例来做为说明，假如我们真的不得不在Java中使用Hibernate来对数据进行批量处理的话。 向数据库插入100 000条数据，用Hibernate可能像这样：<br /><br /><table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#e6e4dd" border="1"><tbody><tr><td>Session session = sessionFactory.openSession(); <br />Transaction tx = session.beginTransaction(); <br />for ( int i=0; i&lt;100000; i++ ) { <br />Customer customer = new Customer(.....); <br />session.save(customer); } <br />tx.commit();<br />session.close(); </td></tr></tbody></table><br />　　大概在运行到第50 000条的时候，就会出现内存溢出而失败。这是Hibernate把最近插入的Customer都以session-level cache在内存做缓存，我们不要忘记Hiberante并没有限制first-level cache 的缓存大小： <br /><br />　　# 持久对象实例被管理在事务结束时，此时Hibernate与数据库同步任何已经发生变 化的被管理的的对象。<br /><br />　　# Session实现了异步write-behind，它允许Hibernate显式地写操作的批处理。 这里，我给出Hibernate如何实现批量插入的方法： <br />首先，我们设置一个合理的JDBC批处理大小，hibernate.jdbc.batch_size 20。 然后在一定间隔对Session进行flush()和clear()。<br /><br /><table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#e6e4dd" border="1"><tbody><tr><td>Session session = sessionFactory.openSession(); <br />Transaction tx = session.beginTransaction(); <br />for ( int i=0; i&lt;100000; i++ ) {<br />Customer customer = new Customer(.....); <br />session.save(customer); <br />if ( i % 20 == 0 ) {<br />//flush 插入数据和释放内存: <br />session.flush(); session.clear(); } <br />} <br />tx.commit(); <br />session.close();</td></tr></tbody></table><br />　　那么，关于怎样删除和更新数据呢？那好，在Hibernate2.1.6或者更后版本，scroll() 这个方法将是最好的途径：<br /><br /><table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#e6e4dd" border="1"><tbody><tr><td>Session session = sessionFactory.openSession(); <br />Transaction tx = session.beginTransaction(); <br />ScrollableResults customers = session.getNamedQuery("GetCustomers")<br />.scroll(ScrollMode.FORWARD_ONLY); <br />int count=0; <br />while ( customers.next() ) { <br />Customer customer = (Customer) customers.get(0); <br />customer.updateStuff(...); <br />if ( ++count % 20 == 0 ) { <br />//flush 更新数据和释放内存: <br />session.flush(); session.clear(); } }<br />tx.commit(); session.close(); </td></tr></tbody></table><br />　　这种做法并不困难，也不算不优雅。请注意，如果Customer启用了second-level caching ，我们仍然会有一些内存管理的问题。原因就是对于用户的每一次插入和更新，Hibernate在事务处理结束后不得不通告second-level cache 。因此，我们在批处理情况下将要禁用用户使用缓存。<br /><br /></td>
						</tr>
				</tbody>
		</table>
<img src ="http://www.blogjava.net/ocean07000814/aggbug/70699.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ocean07000814/" target="_blank">非洲小白脸</a> 2006-09-20 09:56 <a href="http://www.blogjava.net/ocean07000814/articles/70699.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Hibernate性能测试（load10000条记录的简单测试 仅供参考）(转)</title><link>http://www.blogjava.net/ocean07000814/articles/70696.html</link><dc:creator>非洲小白脸</dc:creator><author>非洲小白脸</author><pubDate>Wed, 20 Sep 2006 01:49:00 GMT</pubDate><guid>http://www.blogjava.net/ocean07000814/articles/70696.html</guid><wfw:comment>http://www.blogjava.net/ocean07000814/comments/70696.html</wfw:comment><comments>http://www.blogjava.net/ocean07000814/articles/70696.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ocean07000814/comments/commentRss/70696.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ocean07000814/services/trackbacks/70696.html</trackback:ping><description><![CDATA[
		<h1 style="FONT-SIZE: 14pt" align="center">Hibernate性能测试（load10000条记录的简单测试 仅供参考）</h1>
		<table cellspacing="3" cellpadding="5" width="90%" align="center" border="0">
				<tbody>
						<tr>
								<td>
								</td>
						</tr>
						<tr>
								<td>
										<p>性能测试：<br />   对一个9036条记录的表进行load测试，表字段有8个，有一个字段是text型，每条记录的该字段约有1300多字节，其余都是简单字段<br />   软硬件：AMD XP1600+, 512M内存（测试时内存有余），winXP SP1, JDK1.4.2_06, Mysql4.1.9,InnoDB,GBK, mm.3.1.6驱动， tomcat5.0.28（启动设置最大内存256M，最小内存64M）,hibernate2.1.8, 打开二级缓存Ehcache（配置二级缓存最多10000个对象）关闭所有hibernate log信息和sql输出<br />   <br />   方法1：先用 List idList = session.find("select o.id from MyClass o");找出idList然后<br />          list.add(session.load(MyClass.class, (Long)idList.get(i)));组成list<br />   方法2：直接用hibernate的session.find(from MyClass )得到list<br />   方法3：直接用hibernate的session.iterator(from MyClass )，然后list = new ArrayList(9100);  while(iter.hasNext()) { list.add(iter.next()); }构造list<br />   <br />   每个方法连续调用5次。（第1次调用是没有二级缓存的结果，第2次以后是有二次缓存的结果）<br />   <br />   结果如下：  <br />       <br />    结束第1次loadAll1()方法, 用时15763ms~14762ms<br />    结束第2次loadAll1()方法, 用时771ms~580ms<br />    结束第3次loadAll1()方法, 用时631ms~611ms<br />    结束第4次loadAll1()方法, 用时641ms~591ms<br />    结束第5次loadAll1()方法, 用时601ms~551ms<br />   <br />    结束第1次loadAll2()方法, 用时2965ms~3025ms<br />    结束第2次loadAll2()方法, 用时2854ms~2950ms  <br />    结束第3次loadAll2()方法, 用时2613ms~<br />    结束第4次loadAll2()方法, 用时2815ms~<br />    结束第5次loadAll2()方法, 用时2653ms~<br />    <br />    结束第1次loadAll3()方法, 用时16664ms~16514ms<br />    结束第2次loadAll3()方法, 用时651ms~661ms<br />    结束第3次loadAll3()方法, 用时621ms~591ms <br />    结束第4次loadAll3()方法, 用时571ms~571ms<br />    结束第5次loadAll3()方法, 用时641ms~631ms     </p>
										<p>
												<br />   <br />   分析： 方法1和方法3在访问数据库的策略是一样的，所以运行时间基本差不多。（方法3稍慢一点可能是iterator遍历再组成list用的时间较多）这两种方法第一次运行都要进行9036+1次数据库访问，所以时间最长。而第二次以后运行只需访问一次数据库，并只取出数据的id不取别的字段，因为此时所有对象都已经存在二级缓存中，剩下的是访问二级缓存组成list，所以速度最快。<br />   <br />          而方法2每次都会访问数据库load所有数据的所有字段，打开cache的log信息，可以看出第2次以后会通过二级缓存得到数据，但是由于load所有字段占用时间占了此方法较大比例的开销，所以，即使访问二级缓存，性能提高也非常微小，每次运行的时间花费几乎一样。<br />   <br />          </p>
										<p>注意事项：<br />  (1)不要在机器运行较长时间后运行tomcat进行测试，特别是机器启动后频繁地开启tomcat，java程序，打开较大应用程序占用很多内存的时候。那时候测试结果一定不准。比如：我昨天晚上测试先用方法1的时间是200S，60S，后运行方法2，竟然用了8000S,200S!<br />  (2)设置log4j的LOG级别，不要hibernate和sql的信息。时间会减少很多。（log4j的配置文件难道有这个规矩：一行结尾不能有空格的说？？？FT！！！）<br />  (3)在tomcat启动时进行测试，并在测试方法前调用一个会用到hibernate的方法，让hibernate初始化先完成<br />  </p>
								</td>
						</tr>
				</tbody>
		</table>
<img src ="http://www.blogjava.net/ocean07000814/aggbug/70696.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ocean07000814/" target="_blank">非洲小白脸</a> 2006-09-20 09:49 <a href="http://www.blogjava.net/ocean07000814/articles/70696.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>