﻿<?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-lsbwahaha-随笔分类-hibernate</title><link>http://www.blogjava.net/lsbwahaha/category/38817.html</link><description /><language>zh-cn</language><lastBuildDate>Mon, 06 Apr 2009 04:18:32 GMT</lastBuildDate><pubDate>Mon, 06 Apr 2009 04:18:32 GMT</pubDate><ttl>60</ttl><item><title>hibernate二级缓存</title><link>http://www.blogjava.net/lsbwahaha/archive/2009/04/06/264086.html</link><dc:creator>胡鹏</dc:creator><author>胡鹏</author><pubDate>Mon, 06 Apr 2009 04:02:00 GMT</pubDate><guid>http://www.blogjava.net/lsbwahaha/archive/2009/04/06/264086.html</guid><wfw:comment>http://www.blogjava.net/lsbwahaha/comments/264086.html</wfw:comment><comments>http://www.blogjava.net/lsbwahaha/archive/2009/04/06/264086.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lsbwahaha/comments/commentRss/264086.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lsbwahaha/services/trackbacks/264086.html</trackback:ping><description><![CDATA[<p>hibernate 二级缓存：(缓存的是实体对象，二级缓存是放变化不是很大的数据)<br />
</p>
<br />
<br />
<img alt="" src="http://www.blogjava.net/images/blogjava_net/lsbwahaha/11111.jpg" border="0" /><br />
<br />
<img alt="" src="http://www.blogjava.net/images/blogjava_net/lsbwahaha/2222.jpg" border="0" /><br />
<br />
<br />
<p>二级缓存也称进程级的缓存或SessionFactory级的缓存，而二级缓存可以被所有的session(hibernate中的)共享二级缓存的生命周期和SessionFactory的生命周期一致，SessionFactory可以管理二级缓存</p>
<p>&nbsp;<wbr></p>
<p>二级缓存的配置和使用：</p>
<p>1.将echcache.xml文件拷贝到src下, 二级缓存hibernate默认是开启的，手动开启</p>
<p>2.开启二级缓存，修改hibernate.cfg.xml文件,</p>
<p>&lt;property name=&#8221;hibernate.cache.user_second_level_cache&#8221;&gt;true&lt;/property&gt;</p>
<p>3.指定缓存产品提供商</p>
<p>&lt;property name=&#8221;hibernate.cache.provider_calss&#8221;&gt;org.hibernate.cache.EhCacheProvider&lt;/property&gt;</p>
<p>&nbsp;<wbr></p>
<p>4.指定那些实体类使用二级缓存（两种方法，推荐使用第二种）</p>
<p>第一种：在*.hbm.xml中，在&lt;id&gt;之前加入</p>
<p>&lt;cache usage=&#8221;read-only&#8221; /&gt;, 使用二级缓存</p>
<p>第二种：在hibernate.cfg.xml配置文件中,在&lt;mapping resource=&#8221;com/Studnet.hbm.xml&#8221; /&gt;后面加上：</p>
<p>&lt;class-cache class=&#8221; com.Studnet&#8221; usage=&#8221;read-only&#8221; /&gt;&nbsp;<wbr></p>
<p>&nbsp;<wbr></p>
<p>二级缓存是缓存实体对象的</p>
<p>了解一级缓存和二级缓存的交互</p>
<p>&nbsp;<wbr></p>
<p>&nbsp;<wbr></p>
<p>&nbsp;<wbr></p>
<p>&nbsp;<wbr></p>
<p><strong>测试二级缓存：</strong></p>
<p><strong>一．开启两个</strong><strong>session</strong><strong>中发出两次</strong><strong>load</strong><strong>查询（</strong><strong>get</strong><strong>与</strong><strong>load</strong><strong>一样，同样不会查询数据库）</strong><strong>,</strong></p>
<p>Student sutdent = (Student)session.load(Student.class,1);</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> System.out.println(student.getName());</p>
<p>sessioin.close();</p>
<p>&#8230;&#8230;&#8230;..</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> sutdent = (Student)session.load(Student.class,1);</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> System.out.println(student.getName());</p>
<p>开启两个session中发出两次load查询，第一次load的时候不会去查询数据库，因为他是LAZY的，当使用的时候才去查询数据库，&nbsp;<wbr> 第二次load的时候也不会，当使用的时候查询数据库，开启了二级缓存，也不会查询数据库。</p>
<p><strong>&nbsp;<wbr></strong></p>
<p><strong>&nbsp;<wbr></strong></p>
<p><strong>二．开启两个</strong><strong>session</strong><strong>，分别调用</strong><strong>load</strong><strong>，再使用</strong><strong>sessionFactory</strong><strong>清楚二级缓存</strong></p>
<p>Student sutdent = (Student)session.load(Student.class,1);</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> System.out.println(student.getName());</p>
<p>sessioin.close();</p>
<p>&#8230;&#8230;&#8230;..</p>
<p>SessionFactory factory = HibernateUtil.getSessionFactory();</p>
<p>//factory.evict(Student.class); //清除所有Student对象</p>
<p>Factory.evict(Student.class,1); //清除指定id=1 的对象</p>
<p>&nbsp;<wbr></p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> sutdent = (Student)session.load(Student.class,1);</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> System.out.println(student.getName());</p>
<p>开启两个session中发出两次load查询，第一次load的时候不会去查询数据库，因为他是LAZY的，当使用的时候才去查询数据库，&nbsp;<wbr> 第二次load的时候也不会，当使用的时候查询数据库，它要查询数据库，因为二级缓存中被清除了</p>
<p><strong>&nbsp;<wbr></strong></p>
<p><strong>三．一级缓存和二级缓存的交互</strong></p>
<p>&nbsp;<wbr></p>
<p>session.setCacheMode(CacheMode.GET);&nbsp;<wbr> &nbsp;<wbr>&nbsp;<wbr>//设置成 只是从二级缓存里读,不向二级缓存里写数据</p>
<p>Student sutdent = (Student)session.load(Student.class,1);</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> System.out.println(student.getName());</p>
<p>sessioin.close();</p>
<p>&#8230;&#8230;&#8230;..</p>
<p>SessionFactory factory = HibernateUtil.getSessionFactory();</p>
<p>//factory.evict(Student.class); //清除所有Student对象</p>
<p>Factory.evict(Student.class,1); //清除指定id=1 的对象</p>
<p>&nbsp;<wbr></p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> sutdent = (Student)session.load(Student.class,1);</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> System.out.println(student.getName());</p>
<p>开启两个session中发出两次load查询，第一次load的时候不会去查询数据库，因为他是LAZY的，当使用的时候才去查询数据库，&nbsp;<wbr> 第二次load的时候也不会，当使用的时候查询数据库，它要查询数据库，因为 设置了CacheMode为GET,(load设置成不能往二级缓冲中写数据), 所以二级缓冲中没有数据</p>
<p>&nbsp;<wbr></p>
<p>&nbsp;<wbr></p>
<p>&nbsp;<wbr></p>
<p>session.setCacheMode(CacheMode.PUT);&nbsp;<wbr> //设置成只是向二级缓存里写数据，不读数据</p>
<p>Student sutdent = (Student)session.load(Student.class,1);</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> System.out.println(student.getName());</p>
<p>sessioin.close();</p>
<p>&#8230;&#8230;&#8230;..</p>
<p>SessionFactory factory = HibernateUtil.getSessionFactory();</p>
<p>//factory.evict(Student.class); //清除所有Student对象</p>
<p>Factory.evict(Student.class,1); //清除指定id=1 的对象</p>
<p>&nbsp;<wbr></p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> sutdent = (Student)session.load(Student.class,1);</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> System.out.println(student.getName());</p>
<p>开启两个session中发出两次load查询，第一次load的时候不会去查询数据库，因为他是LAZY的，当使用的时候才去查询数据库，&nbsp;<wbr> 第二次load的时候也不会，当使用的时候查询数据库，它要查询数据库，因为设置了CacheMode为POST,(load设置成只是向二级缓存里写数据，不读数据)</p>
<p><strong>&nbsp;<wbr></strong></p>
<img src ="http://www.blogjava.net/lsbwahaha/aggbug/264086.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lsbwahaha/" target="_blank">胡鹏</a> 2009-04-06 12:02 <a href="http://www.blogjava.net/lsbwahaha/archive/2009/04/06/264086.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>hibernate一级缓存</title><link>http://www.blogjava.net/lsbwahaha/archive/2009/04/06/264085.html</link><dc:creator>胡鹏</dc:creator><author>胡鹏</author><pubDate>Mon, 06 Apr 2009 03:59:00 GMT</pubDate><guid>http://www.blogjava.net/lsbwahaha/archive/2009/04/06/264085.html</guid><wfw:comment>http://www.blogjava.net/lsbwahaha/comments/264085.html</wfw:comment><comments>http://www.blogjava.net/lsbwahaha/archive/2009/04/06/264085.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lsbwahaha/comments/commentRss/264085.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lsbwahaha/services/trackbacks/264085.html</trackback:ping><description><![CDATA[<p>hibernate 一级缓存：(缓存的是实体对象)</p>
<p>一级缓存很短和session的生命周期一致，一级缓存也叫session级的缓存或事务缓存</p>
<p><strong>&nbsp;<wbr></strong></p>
<p>哪些方法支持一级缓存：</p>
<p>*get()</p>
<p>*load()</p>
<p>*iterate()&nbsp;<wbr> (查询实体对象)</p>
<p>&nbsp;<wbr></p>
<p>如何管理一级缓存：</p>
<p>* session.clear() session.evict()</p>
<p>&nbsp;<wbr></p>
<p>如何避免一次性大量的实体数据入库导致内存溢出</p>
<p>*先flush，再clear</p>
<p>&nbsp;<wbr></p>
<p>如果数据量特别大，考虑采用jdbc实现，如果jdbc也不能满足要求，可以考虑采用数据库本身的特定导入工具</p>
<p>&nbsp;<wbr></p>
<p><strong>一．</strong><strong>Load</strong><strong>测试</strong><strong>:</strong> <strong>在同一个</strong><strong>session</strong><strong>中发出两次</strong><strong>load</strong><strong>查询</strong></p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> Student sutdent = (Student)session.load(Student.class,1);</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> System.out.println(student.getName());</p>
<p>&nbsp;<wbr></p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> sutdent = (Student)session.load(Student.class,1);</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> System.out.println(student.getName());</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 在同一个session中发出两次load查询，第一次load的时候不会去查询数据库，因为他是LAZY的，当使用的时候才去查询数据库，&nbsp;<wbr> 第二次load的时候也不会，当使用的时候也不会查询数据库，因为他在缓存里找到，不会发出sql</p>
<p>&nbsp;<wbr></p>
<p>&nbsp;<wbr></p>
<p><strong>Load</strong><strong>测试</strong><strong>:</strong> <strong>开启两个</strong><strong>session</strong><strong>中发出两次</strong><strong>load</strong><strong>查询</strong></p>
<p>Student sutdent = (Student)session.load(Student.class,1);</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> System.out.println(student.getName());</p>
<p>sessioin.close();</p>
<p>&#8230;&#8230;&#8230;..</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> sutdent = (Student)session.load(Student.class,1);</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> System.out.println(student.getName());</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 开启两个session中发出两次load查询，第一次load的时候不会去查询数据库，因为他是LAZY的，当使用的时候才去查询数据库，&nbsp;<wbr> 第二次load的时候也不会，当使用的时候查询数据库，因为session间不能共享一级缓存的数据,因为他会随session的生命周期存在和消亡</p>
<p>&nbsp;<wbr></p>
<p>&nbsp;<wbr></p>
<p><strong>二．</strong><strong>Get</strong><strong>测试</strong><strong>:</strong> <strong>在同一个</strong><strong>session</strong><strong>中发出两次</strong><strong>get</strong><strong>查询</strong></p>
<p>&nbsp;<wbr>&nbsp;<wbr> &nbsp;<wbr>Student sutdent = (Student)session.get(Student.class,1);</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> System.out.println(student.getName());</p>
<p>&nbsp;<wbr></p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> sutdent = (Student)session.get(Student.class,1);</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> System.out.println(student.getName());</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 在同一个session中发出两次get查询， 第一次get的时候去查询数据库，第二次get的时候不会查询数据库，因为他在缓存里找到，不会发出sql</p>
<p>&nbsp;<wbr></p>
<p>&nbsp;<wbr></p>
<p><strong>三．</strong><strong>iterate</strong><strong>测试</strong><strong>:</strong> <strong>在同一个</strong><strong>session</strong><strong>中发出两次</strong><strong>iterator</strong><strong>查询</strong></p>
<p>Student student = (Student)session.createQuery(&#8220;from Student s where s.id=1&#8221;).iterate().next();</p>
<p>System.out.println(student.getName());</p>
<p>&nbsp;<wbr></p>
<p>student = (Student)session.createQuery(&#8220;from Student s where s.id=1&#8221;).iterate().next();</p>
<p>System.out.println(student.getName());</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 在同一个session中发出两次iterator查询，第一次iterate().next()的时候会发出查询id的sql，使用的时候会发出相应的查询实体对象，第二次iterate().next()的时候会发出查询id的sql，不会发出查询实体对象的sql，因为iterate使用缓存，不会发出sql</p>
<p>&nbsp;<wbr></p>
<p>&nbsp;<wbr></p>
<p><strong>四．</strong><strong>Iterate</strong><strong>查询属性测试</strong><strong>:</strong> <strong>同一个</strong><strong>session</strong><strong>中发出两次查询属性</strong></p>
<p>String name = (String)session.createQuery(&#8220;select s.name from Student s where s.id=1&#8221;).iterate().next();</p>
<p>System.out.println(name);</p>
<p>&nbsp;<wbr></p>
<p>String name = (String)session.createQuery(&#8220;select s.name from Student s where s.id=1&#8221;).iterate().next();</p>
<p>System.out.println(name);</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 在同一个session中发出两次查询属性， 第一次iterate().next()的时候会发出查询属性的sql，第二次iterate().next()的时候会发出查询属性的sql，iterate查询普通属性，一级缓存不会缓存，所以会发出sql</p>
<p>&nbsp;<wbr></p>
<p>&nbsp;<wbr></p>
<strong>五．同一个</strong><strong>session</strong><strong>中先</strong><strong>save</strong><strong>，再发出</strong><strong>load</strong><strong>查询</strong><strong>save</strong><strong>过的数据</strong>
<p>&nbsp;<wbr></p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> Student stu = new Student();</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> stu.setName(&#8220;王五&#8221;);</p>
<p>&nbsp;<wbr></p>
<p>&nbsp;<wbr>&nbsp;<wbr> Serializable id = session.save(stu);</p>
<p>&nbsp;<wbr></p>
<p>Student sutdent = (Student)session.load(Student.class,id);</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> System.out.println(student.getName());</p>
<p>&nbsp;<wbr></p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr></p>
<p>save的时候，他会在缓存里放一份,不会发出sql，因为save是使用缓存的</p>
<p><strong>六．同一个</strong><strong>session</strong><strong>中先调用</strong><strong>load</strong><strong>查询，然后执行</strong><strong>sessio.clear()</strong><strong>或</strong><strong>session.evict()</strong><strong>，再调用</strong><strong>load</strong><strong>查询</strong></p>
<p>&nbsp;<wbr></p>
<p>Student sutdent = (Student)session.load(Student.class,1);</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> System.out.println(student.getName());</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> session.clear();</p>
<p>&nbsp;<wbr></p>
<p>Student sutdent = (Student)session.load(Student.class,1);</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> System.out.println(student.getName());</p>
<p>&nbsp;<wbr></p>
<p>&nbsp;<wbr></p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> sessio.clear()或session.evict()可以管理一级缓存，一级缓存无法取消，但可以管理.</p>
<p>上面的语句都会发出sql 因为一级缓存中的实体被清除了</p>
<p><strong>&nbsp;<wbr></strong></p>
<p><strong>七．向数据库中批量加入</strong><strong>1000</strong><strong>条数据</strong></p>
<p>&nbsp;<wbr></p>
<p>for(int i=0;i&lt;1000;i++){</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> Student student = new Student();</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> student.setName(&#8220;s&#8221; + i);</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> session.save(student);</p>
<p>//每20条数据就强制session将数据持久化，同时清除缓存，避免大量数据造成内存溢出</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> if( i %20 == 0 ){</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> session.flush();</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> session.clear();</p>
<p>}</p>
<p>}</p>
<p>&nbsp;</p>
<img src ="http://www.blogjava.net/lsbwahaha/aggbug/264085.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lsbwahaha/" target="_blank">胡鹏</a> 2009-04-06 11:59 <a href="http://www.blogjava.net/lsbwahaha/archive/2009/04/06/264085.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>hibernate查询缓存</title><link>http://www.blogjava.net/lsbwahaha/archive/2009/04/06/264084.html</link><dc:creator>胡鹏</dc:creator><author>胡鹏</author><pubDate>Mon, 06 Apr 2009 03:58:00 GMT</pubDate><guid>http://www.blogjava.net/lsbwahaha/archive/2009/04/06/264084.html</guid><wfw:comment>http://www.blogjava.net/lsbwahaha/comments/264084.html</wfw:comment><comments>http://www.blogjava.net/lsbwahaha/archive/2009/04/06/264084.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lsbwahaha/comments/commentRss/264084.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lsbwahaha/services/trackbacks/264084.html</trackback:ping><description><![CDATA[<br />
&nbsp;
<p>hibernate查询缓存(hibernate默认是关闭的)</p>
<p>&nbsp;<wbr></p>
<p>查询缓存是针对普通属性结果集的缓存</p>
<p>对实体对象的结果集只缓存id</p>
<p>&nbsp;<wbr></p>
<p>查询缓存的生命周期，当前关联的表发生修改，那么查询缓存生命周期结束</p>
<p>&nbsp;<wbr></p>
<p>查询缓存的配置和使用：</p>
<p>1. 启用查询缓存：在hibernate.cfg.xml中加入：</p>
<p>&lt;property name=&#8221;hibernate.cache.use_query_cache&#8221;&gt;true&lt;/property&gt;</p>
<p>&nbsp;<wbr> 2. 在程序中必须手动启用查询缓存，如：query.setCacheable(true);</p>
<p>&nbsp;<wbr></p>
<p>&nbsp;<wbr></p>
<p><strong>测试查询缓存：</strong></p>
<p><strong>一．&nbsp;<wbr></strong> <strong>开启查询缓存，关闭二级缓存，开启一个</strong><strong>session</strong><strong>，分别调用</strong><strong>query.list&nbsp;<wbr></strong> <strong>（查询属性）</strong></p>
<p>&nbsp;<wbr></p>
<p>Query query = session.createQuery(&#8220;select s.name from Student s&#8221;);</p>
<p>//启用查询缓存</p>
<p>query.setCacheable(true);</p>
<p>&nbsp;<wbr></p>
<p>List names = query.list();</p>
<p>for(Iterator iter = names.terator();iter.hasNext();){</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> String name = (String)iter.next();</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> System.out.println(name);</p>
<p>}</p>
<p>&nbsp;<wbr></p>
<p>System.out.println(&#8220;------------------------------------------&#8221;);</p>
<p>&nbsp;<wbr></p>
<p>query = session.createQuery(&#8220;select s.name from Student s&#8221;);</p>
<p>//启用查询缓存</p>
<p>query.setCacheable(true);</p>
<p>&nbsp;<wbr></p>
<p>names = query.list();</p>
<p>for(Iterator iter = names.terator();iter.hasNext();){</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> String name = (String)iter.next();</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> System.out.println(name);</p>
<p>}</p>
<p>第二次没有去查询数据库，因为启用了查询缓存</p>
<p>&nbsp;<wbr></p>
<p><strong>二．&nbsp;<wbr></strong> <strong>开启查询缓存，关闭二级缓存，开启两个</strong><strong>session</strong><strong>，分别调用</strong><strong>query.list&nbsp;<wbr></strong> <strong>（查询属性）</strong></p>
<p>&nbsp;<wbr></p>
<p>Query query = session.createQuery(&#8220;select s.name from Student s&#8221;);</p>
<p>//启用查询缓存</p>
<p>query.setCacheable(true);</p>
<p>&nbsp;<wbr></p>
<p>List names = query.list();</p>
<p>for(Iterator iter = names.terator();iter.hasNext();){</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> String name = (String)iter.next();</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> System.out.println(name);</p>
<p>}</p>
<p>&nbsp;<wbr></p>
<p>session.close();</p>
<p>&nbsp;<wbr></p>
<p>System.out.println(&#8220;------------------------------------------&#8221;);</p>
<p>&#8230;&#8230;&#8230;</p>
<p>Query query = session.createQuery(&#8220;select s.name from Student s&#8221;);</p>
<p>//启用查询缓存</p>
<p>query.setCacheable(true);</p>
<p>&nbsp;<wbr></p>
<p>List names = query.list();</p>
<p>for(Iterator iter = names.terator();iter.hasNext();){</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> String name = (String)iter.next();</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> System.out.println(name);</p>
<p>}</p>
<p>第二次没有去查询数据库，因为查询缓存生命周期与session生命周期无关</p>
<p>&nbsp;<wbr></p>
<p><strong>三．&nbsp;<wbr></strong> <strong>开启查询缓存，关闭二级缓存，开启两个</strong><strong>session</strong><strong>，分别调用</strong><strong>query.iterate</strong> <strong>（查询属性）</strong></p>
<p>&nbsp;<wbr></p>
<p>Query query = session.createQuery(&#8220;select s.name from Student s&#8221;);</p>
<p>//启用查询缓存</p>
<p>query.setCacheable(true);</p>
<p>&nbsp;<wbr></p>
<p>for(Iterator iter =query.iterate();iter.hasNext();){</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> String name = (String)iter.next();</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> System.out.println(name);</p>
<p>}</p>
<p>&nbsp;<wbr></p>
<p>session.close();</p>
<p>&nbsp;<wbr></p>
<p>System.out.println(&#8220;------------------------------------------&#8221;);</p>
<p>&#8230;&#8230;&#8230;</p>
<p>Query query = session.createQuery(&#8220;select s.name from Student s&#8221;);</p>
<p>//启用查询缓存</p>
<p>query.setCacheable(true);</p>
<p>&nbsp;<wbr></p>
<p>for(Iterator iter = query.iterate();iter.hasNext();){</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> String name = (String)iter.next();</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> System.out.println(name);</p>
<p>}</p>
<p>第二去查询数据库，因为查询缓存只对query.list()起作用，对query.iterate()不起作用,也就是说query.iterate()不使用查询缓存</p>
<p>&nbsp;<wbr></p>
<p><strong>四．&nbsp;<wbr></strong> <strong>关闭查询缓存，关闭二级缓存，开启两个</strong><strong>session</strong><strong>，分别调用</strong><strong>query.list</strong> <strong>（查询实体对象）</strong></p>
<p>&nbsp;<wbr></p>
<p>Query query = session.createQuery(&#8220; from Student s&#8221;);</p>
<p>//query.setCacheable(true);</p>
<p>List students = query.list();</p>
<p>for(Iterator iter = students.iterate();iter.hasNext();){</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> Student stu = (Student)iter.next();</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> System.out.println(stu.getName());</p>
<p>}</p>
<p>&nbsp;<wbr></p>
<p>session.close();</p>
<p>&nbsp;<wbr></p>
<p>System.out.println(&#8220;------------------------------------------&#8221;);</p>
<p>&#8230;&#8230;&#8230;</p>
<p>Query query = session.createQuery(&#8220; from Student s&#8221;);</p>
<p>//query.setCacheable(true);</p>
<p>List students = query.list();</p>
<p>for(Iterator iter = students.iterate();iter.hasNext();){</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> Student stu = (Student)iter.next();</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> System.out.println(stu.getName());</p>
<p>}</p>
<p>第二去查询数据库，因为list默认每次都会发出查询sql</p>
<p>&nbsp;<wbr></p>
<p><strong>五．&nbsp;<wbr></strong> <strong>开启查询缓存，关闭二级缓存，开启两个</strong><strong>session</strong><strong>，分别调用</strong><strong>query.list</strong> <strong>（查询实体对象）</strong></p>
<p>&nbsp;<wbr></p>
<p>Query query = session.createQuery(&#8220; from Student s&#8221;);</p>
<p>query.setCacheable(true);</p>
<p>List students = query.list();</p>
<p>for(Iterator iter = students.iterate();iter.hasNext();){</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> Student stu = (Student)iter.next();</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> System.out.println(stu.getName());</p>
<p>}</p>
<p>&nbsp;<wbr></p>
<p>session.close();</p>
<p>&nbsp;<wbr></p>
<p>System.out.println(&#8220;------------------------------------------&#8221;);</p>
<p>&#8230;&#8230;&#8230;</p>
<p>Query query = session.createQuery(&#8220; from Student s&#8221;);</p>
<p>query.setCacheable(true);</p>
<p>List students = query.list();</p>
<p>for(Iterator iter = students.iterate();iter.hasNext();){</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> Student stu = (Student)iter.next();</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> System.out.println(stu.getName());</p>
<p>}&nbsp;<wbr></p>
<p>第二去查询数据库时，会发出N条sql语句，因为开启了查询缓存，关闭了二级缓存，那么查询缓存会缓存实体对象的id，所以hibernate会根据实体对象的id去查询相应的实体，如果缓存中不存在相应的实体，那么将发出根据实体id查询的sql语句，否则不会发出sql，使用缓存中的数据</p>
<p>&nbsp;<wbr></p>
<p><strong>六．&nbsp;<wbr></strong> <strong>开启查询缓存，开启二级缓存，开启两个</strong><strong>session</strong><strong>，分别调用</strong><strong>query.list</strong> <strong>（查询实体对象）</strong></p>
<p>&nbsp;<wbr></p>
<p>Query query = session.createQuery(&#8220; from Student s&#8221;);</p>
<p>query.setCacheable(true);</p>
<p>List students = query.list();</p>
<p>for(Iterator iter = students.iterate();iter.hasNext();){</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> Student stu = (Student)iter.next();</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> System.out.println(stu.getName());</p>
<p>}</p>
<p>&nbsp;<wbr></p>
<p>session.close();</p>
<p>&nbsp;<wbr></p>
<p>System.out.println(&#8220;------------------------------------------&#8221;);</p>
<p>&#8230;&#8230;&#8230;</p>
<p>Query query = session.createQuery(&#8220; from Student s&#8221;);</p>
<p>query.setCacheable(true);</p>
<p>List students = query.list();</p>
<p>for(Iterator iter = students.iterate();iter.hasNext();){</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> Student stu = (Student)iter.next();</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> System.out.println(stu.getName());</p>
<p>}</p>
<p>&nbsp;<wbr></p>
<p>第二不会发出sql，因为开启了二级缓存和查询缓存，查询缓存缓存了实体对象的id列表，hibernate会根据实体对象的id列表到二级缓存中取得相应的数据</p>
<img src ="http://www.blogjava.net/lsbwahaha/aggbug/264084.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lsbwahaha/" target="_blank">胡鹏</a> 2009-04-06 11:58 <a href="http://www.blogjava.net/lsbwahaha/archive/2009/04/06/264084.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>hiernate抓取策略和批量策略</title><link>http://www.blogjava.net/lsbwahaha/archive/2009/04/06/264081.html</link><dc:creator>胡鹏</dc:creator><author>胡鹏</author><pubDate>Mon, 06 Apr 2009 03:57:00 GMT</pubDate><guid>http://www.blogjava.net/lsbwahaha/archive/2009/04/06/264081.html</guid><wfw:comment>http://www.blogjava.net/lsbwahaha/comments/264081.html</wfw:comment><comments>http://www.blogjava.net/lsbwahaha/archive/2009/04/06/264081.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lsbwahaha/comments/commentRss/264081.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lsbwahaha/services/trackbacks/264081.html</trackback:ping><description><![CDATA[<p><strong>在</strong><strong>hibernate</strong><strong>中设置：</strong></p>
<p><strong>查询数据库每次最多返回</strong><strong>50</strong><strong>条结果：</strong></p>
<p><strong>&lt;property name=&#8221;hibernate.jdbc.fetch_size&#8221;&gt;50&lt;/property&gt;</strong></p>
<p><strong>30</strong><strong>条更新数据库一次</strong><strong>:</strong></p>
<p><strong>&lt;property name= &#8221;hibernatejdbc.batch_size&#8221;&gt;30&lt;/property&gt;</strong></p>
<p><strong>&nbsp;<wbr></strong><strong>但不是所有的数据库都支持的，</strong><strong>sqlServer</strong> <strong>和</strong><strong>orcale</strong> <strong>都支持的。</strong></p>
<p><strong>&nbsp;<wbr></strong></p>
<p><strong>一．</strong><strong>hibernate</strong> <strong>抓取策略</strong><strong>(Fetch)</strong> <strong>单端代理批量抓取</strong></p>
<p>&nbsp;<wbr></p>
<p><strong>1.fetch=&#8221;select&#8221;</strong> <strong>关联实体</strong></p>
<p>//fetch 默认是select</p>
<p>&lt;many-to-one name="businessId" column="business_id" insert="true" update="true" fetch="select"&gt;</p>
<p>&nbsp;<wbr></p>
<p>Student student = (Student)session.load(Student.class,1);</p>
<p>System.out.println(student.getName());</p>
<p>System.out.println(student.getClasses().getName()); //多对一中的属性班级，获取班级名称</p>
<p>&nbsp;<wbr></p>
<p>Fetch=&#8221;select&#8221; ,上面程序会发2条sql语句，第二条发送一条select语句抓取当前对象关联实体或集合 (这里指是班级名称)</p>
<p>&nbsp;<wbr></p>
<p><strong>2.fetch=&#8221; join&#8221;</strong> <strong>关联实体</strong></p>
<p>//fetch 设置成 join</p>
<p>&lt;many-to-one name="businessId" column="business_id" insert="true" update="true"</p>
<p>fetch=" join "&gt;</p>
<p>&nbsp;<wbr></p>
<p>Student student = (Student)session.load(Student.class,1);</p>
<p>System.out.println(student.getName());</p>
<p>System.out.println(student.getClasses().getName()); //多对一中的属性班级，获取班级名称</p>
<p>&nbsp;<wbr></p>
<p>fetch=&#8221; join&#8221; , 上面程序会发1条sql语句， hibernate会通过select使用外链接来加载其关联实体或集合，此时lazy会失效&nbsp;<wbr></p>
<p>&nbsp;<wbr></p>
<p><strong>二．</strong><strong>hibernate</strong> <strong>抓取策略</strong><strong>(Fetch)</strong> <strong>集合代理批量抓取</strong></p>
<p>&nbsp;<wbr></p>
<p><strong>1.&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr></strong> <strong>fetch=&#8221;select&#8221;</strong></p>
<p>//fetch 默认是select</p>
<p align="left">&lt;set name="students" inverse="true" cascade="all" fetch="select"&gt;</p>
<p align="left">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &lt;key column="classid" /&gt;</p>
<p align="left">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &lt;one-to-many class="com.Student" /&gt;</p>
<p>&lt;/set&gt;</p>
<p>&nbsp;<wbr></p>
<p>Classes cla = (Classes)session.load(Classes.class,1);</p>
<p>System.out.println(cla.getName());</p>
<p>for(Iterator iter = cla.getStudents().iterator();iter.hasNext();){</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> Student student = (Student)iter.next();</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> System.out.println(student.getName());</p>
<p>}</p>
<p>&nbsp;<wbr></p>
<p>fetch=&#8221;select&#8221; ,上面程序用到了就发sql语句,第二从循环中发了N条,如果：fetch=&#8221;subselect&#8221;,则只是发送一条语句，见下面</p>
<p>&nbsp;<wbr></p>
<p><strong>2 fetch=&#8221;join&#8221;</strong></p>
<p>//fetch 设置成join</p>
<p align="left">&lt;set name="students" inverse="true" cascade="all" fetch="join"&gt;</p>
<p align="left">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &lt;key column="classid" /&gt;</p>
<p align="left">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &lt;one-to-many class="com.Student" /&gt;</p>
<p>&lt;/set&gt;</p>
<p>&nbsp;<wbr></p>
<p>Classes cla = (Classes)session.load(Classes.class,1);</p>
<p>System.out.println(cla.getName());</p>
<p>for(Iterator iter = cla.getStudents().iterator();iter.hasNext();){</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> Student student = (Student)iter.next();</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> System.out.println(student.getName());</p>
<p>}</p>
<p>&nbsp;<wbr></p>
<p>Fetch=&#8221;select&#8221; ,上面程序只发了一条sql语句</p>
<p>&nbsp;<wbr></p>
<p>&nbsp;<wbr></p>
<p><strong>三．</strong><strong>hibernate</strong> <strong>抓取策略</strong><strong>(Fetch)</strong> <strong>集合代理批量抓取</strong></p>
<p>&nbsp;<wbr></p>
<p><strong>2.&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr></strong> <strong>fetch=&#8221;subselect&#8221;</strong></p>
<p>//fetch设置成subselect</p>
<p align="left">&lt;set name="students" inverse="true" cascade="all" fetch="subselect"&gt;</p>
<p align="left">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &lt;key column="classid" /&gt;</p>
<p align="left">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &lt;one-to-many class="com.Student" /&gt;</p>
<p>&lt;/set&gt;</p>
<p>&nbsp;<wbr></p>
<p>List classesList = session.createQuery(&#8220;select c from Classes c where c.id in(1,2,3)&#8221;);</p>
<p>for(Iterator iter=classesList.iterator();iter.hasNext();){</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> Classess classess = (Classess)iter.next();</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> System.out.println(&#8220;classes.name=&#8221;+ classes.getName());</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> for(Iterator iter1 = classess.getStudents().iterator();iter1.hasNext();){</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> Student student = (Student)iter1.next();</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> System.out.println(student.getName());</p>
<p>}</p>
<p>}</p>
<p>&nbsp;<wbr></p>
<p>Fetch=&#8221;subselct&#8221; ,另外发送一条select语句抓取在前面查询到的所有实体对象的关联集合</p>
<p>&nbsp;<wbr></p>
<p>&nbsp;<wbr></p>
<p><strong>四．</strong><strong>hibernate</strong> <strong>批量策略</strong><strong>batch-size</strong><strong>属性，可以批量加载实体类，</strong></p>
<p><strong>参见</strong><strong>Classes.hbm.xml</strong><strong>，同时集合也可以是使用，如：</strong></p>
<p><strong>&nbsp;<wbr></strong>&lt;set name="students" inverse="true" cascade="save-update" batch-size=&#8221;5&#8221;&gt;</p>
<p><strong>&nbsp;<wbr></strong></p>
<p>在配置文件hbm.xml 设置中：</p>
<p>&lt;class name="com.Classes " table="tb_classes" batch-size=&#8221;3&#8221;&gt;</p>
<p>&nbsp;<wbr></p>
<p>List students = session.createQuery(&#8220;select s from Student s where s.id in(:ids)&#8221;).setParameterList(&#8220;:ids&#8221;,new Object[]{1,11,21,31,41,51,61,71,81,91}).list();</p>
<p>&nbsp;<wbr></p>
<p>for(Iterator iter=students.iterator();iter.hasNext();){</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> Student student = (Sutdent)iter.next();</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> System.out.println(student.getName());</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> System.out.println(student.getClassess().getName());</p>
<p>&nbsp;<wbr></p>
<p>}</p>
<p>&nbsp;<wbr></p>
<p>当第二个for循环时，每次加载 之前设置的 数量 实体对象,&nbsp;<wbr> 如：现在设置3，那么当Iterator iter=students.iterator();iter.hasNext();时候，他会查询出3个student对象</p>
<p><wbr></p>
<img src ="http://www.blogjava.net/lsbwahaha/aggbug/264081.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lsbwahaha/" target="_blank">胡鹏</a> 2009-04-06 11:57 <a href="http://www.blogjava.net/lsbwahaha/archive/2009/04/06/264081.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>hibernate悲观锁 与乐观锁</title><link>http://www.blogjava.net/lsbwahaha/archive/2009/04/06/264082.html</link><dc:creator>胡鹏</dc:creator><author>胡鹏</author><pubDate>Mon, 06 Apr 2009 03:57:00 GMT</pubDate><guid>http://www.blogjava.net/lsbwahaha/archive/2009/04/06/264082.html</guid><wfw:comment>http://www.blogjava.net/lsbwahaha/comments/264082.html</wfw:comment><comments>http://www.blogjava.net/lsbwahaha/archive/2009/04/06/264082.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lsbwahaha/comments/commentRss/264082.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lsbwahaha/services/trackbacks/264082.html</trackback:ping><description><![CDATA[<p><strong>悲观锁</strong></p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr></p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 悲观锁的实现，通常依赖于数据库机制，在整个过程中将数据锁定，其它任何用户都不能读取或修改。</p>
<p>&nbsp;<wbr></p>
<p>举个例子：</p>
<p>//查询id=1的那条记录，使用悲观锁</p>
<p>User user = (User)session.load(User.class, 1 ,&nbsp;<wbr> LockMode.UPGRADE);</p>
<p>使用了数据库中的 for update&nbsp;<wbr> 锁定</p>
<p><strong>&nbsp;<wbr></strong></p>
<p><strong>乐观锁</strong></p>
<p>大多数基于数据版本记录机制（version）实现，一半是在数据库表加入一个version字段，读取数据时将版本号一同读出，之后更新数据时版本号加一，如果提交数据时版本号小于或等于数据库表中的版本号，则认为数据是过期的，否则给予更新。</p>
<p>&nbsp;<wbr></p>
<p>其实并非是锁，是一种冲突检测&nbsp;<wbr> (没有hibernate也可以使用的，自己要在数据库中建字段来控制，使用hibernate方便些，封装好了)</p>
<p>&nbsp;<wbr></p>
<p>在*.hm.xml中 添加红色部分：</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr></p>
<p>&lt;class</p>
<p>name="com.tao3c.orm.TbBusinessInfo" &nbsp;<wbr>table="tb_business_info"&nbsp;<wbr> optimistic-lock=&#8221;version&#8221;&gt;</p>
<p>&nbsp;<wbr></p>
<p>其中version是com.tao3c.orm.TbBusinessInfo类的属性，hiernbate会去维护的，不用自己去该</p>
<p>&nbsp;<wbr></p>
<p>&nbsp;<wbr></p>
<img src ="http://www.blogjava.net/lsbwahaha/aggbug/264082.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lsbwahaha/" target="_blank">胡鹏</a> 2009-04-06 11:57 <a href="http://www.blogjava.net/lsbwahaha/archive/2009/04/06/264082.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>hibernate悲观锁 与乐观锁</title><link>http://www.blogjava.net/lsbwahaha/archive/2009/04/06/264083.html</link><dc:creator>胡鹏</dc:creator><author>胡鹏</author><pubDate>Mon, 06 Apr 2009 03:57:00 GMT</pubDate><guid>http://www.blogjava.net/lsbwahaha/archive/2009/04/06/264083.html</guid><wfw:comment>http://www.blogjava.net/lsbwahaha/comments/264083.html</wfw:comment><comments>http://www.blogjava.net/lsbwahaha/archive/2009/04/06/264083.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lsbwahaha/comments/commentRss/264083.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lsbwahaha/services/trackbacks/264083.html</trackback:ping><description><![CDATA[<p><strong>悲观锁</strong></p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr></p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 悲观锁的实现，通常依赖于数据库机制，在整个过程中将数据锁定，其它任何用户都不能读取或修改。</p>
<p>&nbsp;<wbr></p>
<p>举个例子：</p>
<p>//查询id=1的那条记录，使用悲观锁</p>
<p>User user = (User)session.load(User.class, 1 ,&nbsp;<wbr> LockMode.UPGRADE);</p>
<p>使用了数据库中的 for update&nbsp;<wbr> 锁定</p>
<p><strong>&nbsp;<wbr></strong></p>
<p><strong>乐观锁</strong></p>
<p>大多数基于数据版本记录机制（version）实现，一半是在数据库表加入一个version字段，读取数据时将版本号一同读出，之后更新数据时版本号加一，如果提交数据时版本号小于或等于数据库表中的版本号，则认为数据是过期的，否则给予更新。</p>
<p>&nbsp;<wbr></p>
<p>其实并非是锁，是一种冲突检测&nbsp;<wbr> (没有hibernate也可以使用的，自己要在数据库中建字段来控制，使用hibernate方便些，封装好了)</p>
<p>&nbsp;<wbr></p>
<p>在*.hm.xml中 添加红色部分：</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr></p>
<p>&lt;class</p>
<p>name="com.tao3c.orm.TbBusinessInfo" &nbsp;<wbr>table="tb_business_info"&nbsp;<wbr> optimistic-lock=&#8221;version&#8221;&gt;</p>
<p>&nbsp;<wbr></p>
<p>其中version是com.tao3c.orm.TbBusinessInfo类的属性，hiernbate会去维护的，不用自己去该</p>
<p>&nbsp;<wbr></p>
<p>&nbsp;<wbr></p>
<img src ="http://www.blogjava.net/lsbwahaha/aggbug/264083.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lsbwahaha/" target="_blank">胡鹏</a> 2009-04-06 11:57 <a href="http://www.blogjava.net/lsbwahaha/archive/2009/04/06/264083.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>hibernate多对多映射_处理</title><link>http://www.blogjava.net/lsbwahaha/archive/2009/04/06/264079.html</link><dc:creator>胡鹏</dc:creator><author>胡鹏</author><pubDate>Mon, 06 Apr 2009 03:56:00 GMT</pubDate><guid>http://www.blogjava.net/lsbwahaha/archive/2009/04/06/264079.html</guid><wfw:comment>http://www.blogjava.net/lsbwahaha/comments/264079.html</wfw:comment><comments>http://www.blogjava.net/lsbwahaha/archive/2009/04/06/264079.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lsbwahaha/comments/commentRss/264079.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lsbwahaha/services/trackbacks/264079.html</trackback:ping><description><![CDATA[<p><strong>一．</strong><strong>hibernate</strong><strong>多对多映射（单项），自动产生第三张表</strong></p>
<p>User--&#224; Role</p>
<p>user(id,name)&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> role(id,name)</p>
<p>User类：</p>
<p>private int&nbsp;<wbr> id;&nbsp;<wbr>&nbsp;<wbr> private String name; &nbsp;<wbr>private &nbsp;<wbr>Set roles;</p>
<p>&nbsp;<wbr></p>
<p>Role类：</p>
<p>private int id;&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> private String name;</p>
<p>&nbsp;<wbr></p>
<p>User.hbm.xml中：</p>
<p>&lt;set name=&#8221;roles&#8221; table=&#8221;t_user_role&#8221;&gt;</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &lt;key column=&#8221;userid&#8221; /&gt;</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &lt;many-to-many class=&#8221;com.Role&#8221; column=&#8221;roleid&#8221; /&gt;</p>
<p>&lt;/set&gt;</p>
<p>&nbsp;<wbr></p>
<p>这样，hibernate会自动产生中间表t_user_role(userid,roleid) 并且是复合主键，userid为t_user的外键，roleid为t_role的外键</p>
<p>&nbsp;<wbr></p>
<p>&nbsp;<wbr></p>
<p><strong>二．</strong><strong>hibernate</strong><strong>多对多的存储</strong></p>
<p><strong>&nbsp;<wbr></strong></p>
<p>Role r1 = new Role();</p>
<p>r1.setName(&#8220;数据录入人员&#8221;);</p>
<p>&nbsp;<wbr></p>
<p>Role r2 = new Role();</p>
<p>r2.setName(&#8220;商务主管&#8221;);</p>
<p>&nbsp;<wbr></p>
<p>Role r3 = new Role();</p>
<p>r3.setName(&#8220;大区经理&#8221;);</p>
<p>&nbsp;<wbr></p>
<p>&nbsp;<wbr></p>
<p>User u1 = new User();</p>
<p>u1.setName(&#8220;10&#8221;);</p>
<p>Set u1Roles = new HashSet();</p>
<p>u1Roles.add(r1);</p>
<p>u1Roles.add(r2);</p>
<p>u1.setRoles(u1Roles);</p>
<p>&nbsp;<wbr></p>
<p>User u2 = new User();</p>
<p>u1.setName(&#8220;祖儿&#8221;);</p>
<p>Set u2Roles = new HashSet();</p>
<p>u2Roles.add(r2);</p>
<p>u2Roles.add(r3);</p>
<p>u2.setRoles(u2Roles);</p>
<p>User u3 = new User();</p>
<p>u3.setName(&#8220;杰伦&#8221;);</p>
<p>Set u3Roles = new HashSet();</p>
<p>u3Roles.add(r1);</p>
<p>u3Roles.add(r2);</p>
<p>u3Roles.add(r3);</p>
<p>u3.setRoles(u3Roles);</p>
<p>&nbsp;<wbr></p>
<p>&nbsp;<wbr></p>
<p>session.save(r1);</p>
<p>session.save(r2);</p>
<p>session.save(r3);</p>
<p>&nbsp;<wbr></p>
<p>session.save(u1);</p>
<p>session.save(u2);</p>
<p>session.save(u3);</p>
<p>&nbsp;<wbr></p>
<p>结束之后，在第三张表中也有数据</p>
<p>&nbsp;<wbr></p>
<p>&nbsp;<wbr></p>
<p>&nbsp;<wbr></p>
<p><strong>三．</strong><strong>hibernate</strong><strong>多对多的加载</strong></p>
<p>&nbsp;<wbr></p>
<p>User user = (User)session.load(User.class,1);</p>
<p>System.out.println(user.getName());</p>
<p>for(Iterator iter = user.getRoles().iterator();iter.hasNext();){</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> Role role = (Role)iter.next();</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> System.out.println(role.getName());</p>
<p>&nbsp;<wbr></p>
<p>}</p>
<p>&nbsp;<wbr>每次加载都会发出sql语句</p>
<p>&nbsp;<wbr></p>
<p><strong>三．</strong><strong>hibernate</strong><strong>多对多的</strong> <strong>双向映射</strong></p>
<p><strong>&nbsp;<wbr></strong></p>
<p>User &#223;--.-&#224;Role</p>
<p>user(id,name)&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> role(id,name)</p>
<p>User类：</p>
<p>private int&nbsp;<wbr> id;&nbsp;<wbr>&nbsp;<wbr> private String name;&nbsp;<wbr> private Set roles;</p>
<p>&nbsp;<wbr></p>
<p>Role类：</p>
<p>private int id;&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> private String name; private Set users;</p>
<p>&nbsp;<wbr></p>
<p>User.hbm.xml中：</p>
<p>&lt;set name=&#8221;roles&#8221; table=&#8221;t_user_role&#8221;&gt;</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &lt;key column=&#8221;userid&#8221; /&gt;</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &lt;many-to-many class=&#8221;com.Role&#8221; column=&#8221;roleid&#8221; /&gt;</p>
<p>&lt;/set&gt;</p>
<p>&nbsp;<wbr></p>
<p>Role.hbm.xml中：</p>
<p>&lt;set name=&#8221;roles&#8221; table=&#8221;t_user_role&#8221;&gt;&nbsp;<wbr>&nbsp;<wbr> //这里可以设置order-by=&#8221;userid&#8221;,根据userid排序</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &lt;key column=&#8221;roleid&#8221; /&gt;</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &lt;many-to-many class=&#8221;com.User&#8221; column=&#8221;userid&#8221; /&gt;</p>
<p>&lt;/set&gt;</p>
<p>&nbsp;<wbr></p>
<p>注意，上面中间表名字是一样的</p>
<p>这样，hibernate也会自动产生中间表t_user_role(userid,roleid) 并且是复合主键，userid为t_user的外键，roleid为t_role的外键</p>
<p>&nbsp;<wbr></p>
<img src ="http://www.blogjava.net/lsbwahaha/aggbug/264079.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lsbwahaha/" target="_blank">胡鹏</a> 2009-04-06 11:56 <a href="http://www.blogjava.net/lsbwahaha/archive/2009/04/06/264079.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>hibernate多对多映射_处理</title><link>http://www.blogjava.net/lsbwahaha/archive/2009/04/06/264080.html</link><dc:creator>胡鹏</dc:creator><author>胡鹏</author><pubDate>Mon, 06 Apr 2009 03:56:00 GMT</pubDate><guid>http://www.blogjava.net/lsbwahaha/archive/2009/04/06/264080.html</guid><wfw:comment>http://www.blogjava.net/lsbwahaha/comments/264080.html</wfw:comment><comments>http://www.blogjava.net/lsbwahaha/archive/2009/04/06/264080.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lsbwahaha/comments/commentRss/264080.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lsbwahaha/services/trackbacks/264080.html</trackback:ping><description><![CDATA[<p><strong>一．</strong><strong>hibernate</strong><strong>多对多映射（单项），自动产生第三张表</strong></p>
<p>User--&#224; Role</p>
<p>user(id,name)&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> role(id,name)</p>
<p>User类：</p>
<p>private int&nbsp;<wbr> id;&nbsp;<wbr>&nbsp;<wbr> private String name; &nbsp;<wbr>private &nbsp;<wbr>Set roles;</p>
<p>&nbsp;<wbr></p>
<p>Role类：</p>
<p>private int id;&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> private String name;</p>
<p>&nbsp;<wbr></p>
<p>User.hbm.xml中：</p>
<p>&lt;set name=&#8221;roles&#8221; table=&#8221;t_user_role&#8221;&gt;</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &lt;key column=&#8221;userid&#8221; /&gt;</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &lt;many-to-many class=&#8221;com.Role&#8221; column=&#8221;roleid&#8221; /&gt;</p>
<p>&lt;/set&gt;</p>
<p>&nbsp;<wbr></p>
<p>这样，hibernate会自动产生中间表t_user_role(userid,roleid) 并且是复合主键，userid为t_user的外键，roleid为t_role的外键</p>
<p>&nbsp;<wbr></p>
<p>&nbsp;<wbr></p>
<p><strong>二．</strong><strong>hibernate</strong><strong>多对多的存储</strong></p>
<p><strong>&nbsp;<wbr></strong></p>
<p>Role r1 = new Role();</p>
<p>r1.setName(&#8220;数据录入人员&#8221;);</p>
<p>&nbsp;<wbr></p>
<p>Role r2 = new Role();</p>
<p>r2.setName(&#8220;商务主管&#8221;);</p>
<p>&nbsp;<wbr></p>
<p>Role r3 = new Role();</p>
<p>r3.setName(&#8220;大区经理&#8221;);</p>
<p>&nbsp;<wbr></p>
<p>&nbsp;<wbr></p>
<p>User u1 = new User();</p>
<p>u1.setName(&#8220;10&#8221;);</p>
<p>Set u1Roles = new HashSet();</p>
<p>u1Roles.add(r1);</p>
<p>u1Roles.add(r2);</p>
<p>u1.setRoles(u1Roles);</p>
<p>&nbsp;<wbr></p>
<p>User u2 = new User();</p>
<p>u1.setName(&#8220;祖儿&#8221;);</p>
<p>Set u2Roles = new HashSet();</p>
<p>u2Roles.add(r2);</p>
<p>u2Roles.add(r3);</p>
<p>u2.setRoles(u2Roles);</p>
<p>User u3 = new User();</p>
<p>u3.setName(&#8220;杰伦&#8221;);</p>
<p>Set u3Roles = new HashSet();</p>
<p>u3Roles.add(r1);</p>
<p>u3Roles.add(r2);</p>
<p>u3Roles.add(r3);</p>
<p>u3.setRoles(u3Roles);</p>
<p>&nbsp;<wbr></p>
<p>&nbsp;<wbr></p>
<p>session.save(r1);</p>
<p>session.save(r2);</p>
<p>session.save(r3);</p>
<p>&nbsp;<wbr></p>
<p>session.save(u1);</p>
<p>session.save(u2);</p>
<p>session.save(u3);</p>
<p>&nbsp;<wbr></p>
<p>结束之后，在第三张表中也有数据</p>
<p>&nbsp;<wbr></p>
<p>&nbsp;<wbr></p>
<p>&nbsp;<wbr></p>
<p><strong>三．</strong><strong>hibernate</strong><strong>多对多的加载</strong></p>
<p>&nbsp;<wbr></p>
<p>User user = (User)session.load(User.class,1);</p>
<p>System.out.println(user.getName());</p>
<p>for(Iterator iter = user.getRoles().iterator();iter.hasNext();){</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> Role role = (Role)iter.next();</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> System.out.println(role.getName());</p>
<p>&nbsp;<wbr></p>
<p>}</p>
<p>&nbsp;<wbr>每次加载都会发出sql语句</p>
<p>&nbsp;<wbr></p>
<p><strong>三．</strong><strong>hibernate</strong><strong>多对多的</strong> <strong>双向映射</strong></p>
<p><strong>&nbsp;<wbr></strong></p>
<p>User &#223;--.-&#224;Role</p>
<p>user(id,name)&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> role(id,name)</p>
<p>User类：</p>
<p>private int&nbsp;<wbr> id;&nbsp;<wbr>&nbsp;<wbr> private String name;&nbsp;<wbr> private Set roles;</p>
<p>&nbsp;<wbr></p>
<p>Role类：</p>
<p>private int id;&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> private String name; private Set users;</p>
<p>&nbsp;<wbr></p>
<p>User.hbm.xml中：</p>
<p>&lt;set name=&#8221;roles&#8221; table=&#8221;t_user_role&#8221;&gt;</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &lt;key column=&#8221;userid&#8221; /&gt;</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &lt;many-to-many class=&#8221;com.Role&#8221; column=&#8221;roleid&#8221; /&gt;</p>
<p>&lt;/set&gt;</p>
<p>&nbsp;<wbr></p>
<p>Role.hbm.xml中：</p>
<p>&lt;set name=&#8221;roles&#8221; table=&#8221;t_user_role&#8221;&gt;&nbsp;<wbr>&nbsp;<wbr> //这里可以设置order-by=&#8221;userid&#8221;,根据userid排序</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &lt;key column=&#8221;roleid&#8221; /&gt;</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &lt;many-to-many class=&#8221;com.User&#8221; column=&#8221;userid&#8221; /&gt;</p>
<p>&lt;/set&gt;</p>
<p>&nbsp;<wbr></p>
<p>注意，上面中间表名字是一样的</p>
<p>这样，hibernate也会自动产生中间表t_user_role(userid,roleid) 并且是复合主键，userid为t_user的外键，roleid为t_role的外键</p>
<p>&nbsp;<wbr></p>
<img src ="http://www.blogjava.net/lsbwahaha/aggbug/264080.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lsbwahaha/" target="_blank">胡鹏</a> 2009-04-06 11:56 <a href="http://www.blogjava.net/lsbwahaha/archive/2009/04/06/264080.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>hibernate配置要点详谈</title><link>http://www.blogjava.net/lsbwahaha/archive/2009/04/06/264076.html</link><dc:creator>胡鹏</dc:creator><author>胡鹏</author><pubDate>Mon, 06 Apr 2009 03:53:00 GMT</pubDate><guid>http://www.blogjava.net/lsbwahaha/archive/2009/04/06/264076.html</guid><wfw:comment>http://www.blogjava.net/lsbwahaha/comments/264076.html</wfw:comment><comments>http://www.blogjava.net/lsbwahaha/archive/2009/04/06/264076.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lsbwahaha/comments/commentRss/264076.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lsbwahaha/services/trackbacks/264076.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;
<p>1.两种配置文件：</p>
<p>A.hibernate.cfg.xml和B.hibernate.properties</p>
<p>&nbsp;<wbr></p>
<p>A中可含映射文件的配置，而B中hard codes加映射文件。</p>
<p>&nbsp;<wbr></p>
<p>A.Configuration config=new Configuration().config();</p>
<p>B. Configuration config=new Configuration();</p>
<p>config.addClass(TUser.class);</p>
<p>&nbsp;<wbr></p>
<p>2.你不必一定用hibernate.cfg.xml或hibernate.properties这两文件名，你也不一定非得把配置文件放在Classes下，　File file=new File("c:\\sample\\myhibernate.xml");　Configuration config=new Configuration().config(file);</p>
<p>&nbsp;<wbr></p>
<p>3. session.Flush() 强制数据库立即同步，当用事务时，不必用flush,事务提交自动调用flush在session关闭时也会调用flush</p>
<p>&nbsp;<wbr></p>
<p>4. Hibernate总是使用对象类型作为字段类型</p>
<p>&nbsp;<wbr></p>
<p>5. XDoclet专门建立了hibernate doclet,就是在java代码上加上一些java docTag，后来再让XDoclet分析该java代码，生成映射文件;</p>
<p>&nbsp;<wbr></p>
<p>6.HQL子句本身大小写无关，但是其中出现的类名和属性名必须注意大小写区分。</p>
<p>&nbsp;<wbr></p>
<p>7.关系：　Constrained : 约束，表明主控表的主键上是否存在一个外键（foreigh key）对其进行约束。</p>
<p>&nbsp;<wbr></p>
<p>property-ref:关联类中用于与主控类相关联的属性名，默认为关联类的主键属性名</p>
<p>&nbsp;<wbr></p>
<p>单向一对多需在一方配置，双向一对多需在双方进行配置</p>
<p>&nbsp;<wbr></p>
<p>8.lazy=false:被动方的记录由hibernate负责记取，之后存放在主控方指定的Collection类型属性中</p>
<p>&nbsp;<wbr></p>
<p>9. java.util.Set或net.sof.hibernate.collecton.Bag类型的Collection</p>
<p>&nbsp;<wbr></p>
<p>10.重要：inverse:用于标识双向关联中的被动方一端。</p>
<p>&nbsp;<wbr></p>
<p>inverse=false的一方（主控方）负责维护关联关系.默认值：false</p>
<p>&nbsp;<wbr></p>
<p>11.batch-size:采用延迟加载特征时，一次读入的数据数昨。</p>
<p>&nbsp;<wbr></p>
<p>12.一对多通过主控方更新（主控方为一方时）</p>
<p>&nbsp;<wbr></p>
<p>user.getAddresses().add(addr);</p>
<p>&nbsp;<wbr></p>
<p>session.save(user);//通过主控对象级联更新</p>
<p>&nbsp;<wbr></p>
<p>13.在one-to-many 关系中，将many 一方设为主动方（inverse=false）将有助性能的改善。在一方设置关系时，inverse=true,即将主控权交给多方，　这样多方可主动从一方获得foreign key,然后一次insert即可完工。</p>
<p>&nbsp;<wbr></p>
<p>addr.setUser(user);//设置关联的TUser对象</p>
<p>&nbsp;<wbr></p>
<p>user.getAddresses().add(addr);</p>
<p>&nbsp;<wbr></p>
<p>session.save(user);//级联更新</p>
<p>&nbsp;<wbr></p>
<p>14.只有设为主控方的一方才关心（访问）对方的属性，被动方是不关心对方的属性的。</p>
<p>&nbsp;<wbr></p>
<p>15.one-to-many与many-to-one节点的配置属性不同：</p>
<p>&nbsp;<wbr></p>
<p>一对多关系多了lazy和inverse两个属性多对多节点属性：</p>
<p>&nbsp;<wbr></p>
<p>column:中间映射表中，关联目标表的关联字段</p>
<p>&nbsp;<wbr></p>
<p>class:类名，关联目标类</p>
<p>&nbsp;<wbr></p>
<p>outer-join:是否使用外联接</p>
<p>&nbsp;<wbr></p>
<p>注意:access是设置属性值的读取方式。</p>
<p>&nbsp;<wbr></p>
<p>column是设置关联字段。</p>
<p>&nbsp;<wbr></p>
<p>16.多对多，注意两方都要设置inverse和lazy,cascade只能设为insert-update</p>
<p>&nbsp;<wbr></p>
<p>多对多关系中，由于关联关系是两张表相互引用，因此在保存关系状态时必须对双方同时保存。</p>
<p>&nbsp;<wbr></p>
<p>group1.getRoles().add(role1);　role1.getGroups().add(group1);</p>
<p>&nbsp;<wbr></p>
<p>session.save(role1);　session.save(group1);</p>
<p>&nbsp;<wbr></p>
<p>17.关于vo和po　vo经过hibernate容量处理，就变成了po(该vo的引用将被容器保存，并且在session关闭时flush,因此po如果再传到其它地方改变了，就危险了)　vo和po相互转换：BeanUtils.copyProperties(anotherUser,user);</p>
<p>&nbsp;<wbr></p>
<p>18.对于save操作而言，如果对象已经与Session相关联（即已经被加入Session的实体容器中），则无需进行具体的操作。因为之后的Session.flush过程中，Hibernate 会对此实体容器中的对象进行遍历，查找出发生变化的实体，生成并执行相应的update 语句。</p>
<p>&nbsp;<wbr></p>
<p>19.如果我们采用了延迟加载机制，但希望在一些情况下，实现非延迟加载时的功能，也就是说，我们希望在Session关闭后，依然允许操作user的addresses 属性 Hibernate.initialize方法可以通过强制加载关联对象实现这一功能： 这也正是我们为什么在编写POJO时，必须用JDK Collection接口（如Set,Map）, 而非特定的JDK Collection实现类（如HashSet、HashMap）申明Collection属性的 原因。</p>
<p>&nbsp;<wbr></p>
<p>20.事务：从sessionFactory获得session,其自动提交属性就已经关闭(AutoCommit=false),此时若执行了jdbc操作，如果不显式调用session.BeginTransaction(),是不会执行事务操作的。</p>
<p>&nbsp;<wbr></p>
<p>jdbc transaction:基于同一个session(就是同一个connection)的事务;</p>
<p>&nbsp;<wbr></p>
<p>jta　transaction:跨session（跨connection）事务.</p>
<p>&nbsp;<wbr></p>
<p>对于jta事务，有三种实现方法：</p>
<p>&nbsp;<wbr></p>
<p>A。UserTransaction tx=new InitialContext().lookup("...");</p>
<p>tx.commit();</p>
<p>&nbsp;<wbr></p>
<p>B. 使用hibernate封装的方法：(不推荐)</p>
<p>&nbsp;<wbr></p>
<p>Transaction tx=session.beginTransaction();</p>
<p>tx.commit();</p>
<p>C. 使用ejb之sessionBean的事务技持方法，你只要在把需要在发布描述符中，把需要jta事务的方法声明为require即可</p>
<p>&nbsp;<wbr></p>
<p>21.悲观锁，乐观锁：　乐观锁一般通过version来实现，注意version节点必须出现在id后。</p>
<p>&nbsp;<wbr></p>
<p>22.Hibernate中，可以通过Criteria.setFirstResult和Criteria.setFetchSize方法设定分页范围。</p>
<p>&nbsp;<wbr></p>
<p>Query接口中也提供了与其一致的方法，hibernate主要在dialect类中实现在这个功能。</p>
<p>&nbsp;<wbr></p>
<p>23.cache</p>
<p>&nbsp;<wbr></p>
<p>&#8230;&#8230;</p>
<p>&nbsp;<wbr></p>
<p>net.sf.ehcache.hibernate.Provider　</p>
<p>&nbsp;<wbr></p>
<p>还需对ecache本身进配置</p>
<p>&nbsp;<wbr></p>
<p>&nbsp;<wbr></p>
<p>&nbsp;<wbr></p>
<p>之后在映射文件中指定各个映射实体的cache策略</p>
<p>&nbsp;<wbr></p>
<p>&nbsp;<wbr></p>
<p>....</p>
<p>&nbsp;<wbr></p>
<p>&nbsp;<wbr></p>
<p>....</p>
<p>&nbsp;<wbr></p>
<p>&nbsp;<wbr></p>
<p>***************************************************** Query.list()跟Query.iterate()的不同：对于query.list()总是通过一条sql语句获取所有记录,然后将其读出，填入pojo返回; 但是query.iterate()，则是首先通过一条Select SQL 获取所有符合查询条件的记录的 id，再对这个id 集合进行循环操作，通过单独的Select SQL 取出每个id 所对应的记 录，之后填入POJO中返回。</p>
<p>&nbsp;<wbr></p>
<p>也就是说，对于list 操作，需要一条SQL 完成。而对于iterate 操作，需要n+1 条SQL。，list方法将不会从Cache中读取数据。iterator却会。</p>
<p>&nbsp;<wbr></p>
<p>24.ThreadLocal:它会为每个线程维护一个私有的变量空间。实际上， 其实现原理是在JVM 中维护一个Map，这个Map的key 就是当前的线程对象，而value则是线程通过ThreadLocal.set方法保存的对象实例。当线程调用ThreadLocal.get方法时， ThreadLocal会根据当前线程对象的引用，取出Map中对应的对象返回。</p>
<p>&nbsp;<wbr></p>
<p>这样，ThreadLocal通过以各个线程对象的引用作为区分，从而将不同线程的变量隔离开来。</p>
<p>&nbsp;<wbr></p>
<p>25.Hibernate官方开发手册标准示例:</p>
<p>&nbsp;<wbr></p>
<p>public class HibernateUtil { private static SessionFactory sessionFactory;</p>
<p>static { try { // Create the SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();</p>
<p>} catch (HibernateException ex) { throw new RuntimeException( "Configuration problem: " + ex.getMessage(), ex );</p>
<p>} } public static final ThreadLocal session = new ThreadLocal();</p>
<p>public static Session currentSession() throws HibernateException { Session s = (Session) session.get();</p>
<p>// Open a new Session, if this Thread has none yet if (s == null) { s = sessionFactory.openSession();</p>
<p>session.set(s);</p>
<p>} return s;</p>
<p>} public static void closeSession() throws HibernateException { Session s = (Session) session.get();</p>
<p>session.set(null);</p>
<p>if (s != null) s.close();</p>
<p>} }</p>
<p>&nbsp;<wbr></p>
<p>26.通过filter实现session的重用：</p>
<p>&nbsp;<wbr></p>
<p>public class PersistenceFilter implements Filter { protected static ThreadLocal hibernateHolder = new ThreadLocal();</p>
<p>public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { hibernateHolder.set(getSession());</p>
<p>try { &#8230;&#8230; chain.doFilter(request, response);</p>
<p>&#8230;&#8230; } finally { Session sess = (Session)hibernateHolder.get();</p>
<p>if (sess != null) { hibernateHolder.set(null);</p>
<p>try { sess.close(); } catch (HibernateException ex) { throw new ServletException(ex);</p>
<p>} } } } &#8230;&#8230;}</p>
<img src ="http://www.blogjava.net/lsbwahaha/aggbug/264076.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lsbwahaha/" target="_blank">胡鹏</a> 2009-04-06 11:53 <a href="http://www.blogjava.net/lsbwahaha/archive/2009/04/06/264076.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>