﻿<?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-J度空间-文章分类-Hibernate</title><link>http://www.blogjava.net/jdo/category/24568.html</link><description /><language>zh-cn</language><lastBuildDate>Sat, 18 Aug 2007 03:44:10 GMT</lastBuildDate><pubDate>Sat, 18 Aug 2007 03:44:10 GMT</pubDate><ttl>60</ttl><item><title>Hibernate应用系列之六批量处理篇</title><link>http://www.blogjava.net/jdo/articles/137712.html</link><dc:creator>蓝色幽默</dc:creator><author>蓝色幽默</author><pubDate>Fri, 17 Aug 2007 15:12:00 GMT</pubDate><guid>http://www.blogjava.net/jdo/articles/137712.html</guid><wfw:comment>http://www.blogjava.net/jdo/comments/137712.html</wfw:comment><comments>http://www.blogjava.net/jdo/articles/137712.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jdo/comments/commentRss/137712.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jdo/services/trackbacks/137712.html</trackback:ping><description><![CDATA[
		<a target="_blank" title="Hibernate应用系列之六批量处理篇" href="http://tech.it168.com/j/e/2006-09-25/200609251710239.shtml">http://tech.it168.com/j/e/2006-09-25/200609251710239.shtml</a>
<img src ="http://www.blogjava.net/jdo/aggbug/137712.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jdo/" target="_blank">蓝色幽默</a> 2007-08-17 23:12 <a href="http://www.blogjava.net/jdo/articles/137712.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Hibernate二级缓存攻略</title><link>http://www.blogjava.net/jdo/articles/135788.html</link><dc:creator>蓝色幽默</dc:creator><author>蓝色幽默</author><pubDate>Fri, 10 Aug 2007 05:24:00 GMT</pubDate><guid>http://www.blogjava.net/jdo/articles/135788.html</guid><wfw:comment>http://www.blogjava.net/jdo/comments/135788.html</wfw:comment><comments>http://www.blogjava.net/jdo/articles/135788.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jdo/comments/commentRss/135788.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jdo/services/trackbacks/135788.html</trackback:ping><description><![CDATA[　　很多人对二级缓存都不太了解，或者是有错误的认识，我一直想写一篇文章介绍一下<a href="http://dev.21tx.com/java/struts/" target="_blank"><font color="#3366cc">Hibernate</font></a>的二级缓存的，今天终于忍不住了。 <br /><br />　　我的经验主要来自hibernate2.1版本，基本原理和3.0、3.1是一样的，请原谅我的顽固不化。 <br /><br />　　hibernate的session提供了一级缓存，每个session，对同一个id进行两次load，不会发送两条sql给<a href="http://dev.21tx.com/database/" target="_blank"><font color="#3366cc">数据库</font></a>，但是session关闭的时候，一级缓存就失效了。<br /><br />　　二级缓存是SessionFactory级别的全局缓存，它底下可以使用不同的缓存类库，比如ehcache、oscache等，需要设置hibernate.cache.provider_class，我们这里用ehcache，在2.1中就是 hibernate.cache.provider_class=net.sf.hibernate.cache.EhCacheProvider如果使用查询缓存，加上hibernate.cache.use_query_cache=true<br /><br />　　缓存可以简单的看成一个Map，通过key在缓存里面找value。<br /><br />　　<b>Class的缓存</b><br /><br />　　对于一条记录，也就是一个PO来说，是根据ID来找的，缓存的key就是ID，value是POJO。无论list，load还是iterate，只要读出一个对象，都会填充缓存。但是list不会使用缓存，而iterate会先取数据库select id出来，然后一个id一个id的load，如果在缓存里面有，就从缓存取，没有的话就去数据库load。假设是读写缓存，需要设置： <br /><br /><table bordercolor="#cccccc" width="90%" align="center" bgcolor="#e7e9e9" border="1"><tbody><tr><td>＜cache usage="read-write"/＞ </td></tr></tbody></table><br />　　如果你使用的二级缓存实现是ehcache的话，需要配置ehcache.<a href="http://dev.21tx.com/web/xml/" target="_blank"><font color="#3366cc">XML</font></a><br /><br /><table bordercolor="#cccccc" width="90%" align="center" bgcolor="#e7e9e9" border="1"><tbody><tr><td>＜cache name="com.xxx.pojo.Foo" maxElementsInMemory="500" eternal="false" timeToLiveSeconds="7200" timeToIdleSeconds="3600" overflowToDisk="true" /＞ </td></tr></tbody></table><br />　　其中eternal表示缓存是不是永远不超时，timeToLiveSeconds是缓存中每个元素（这里也就是一个POJO）的超时时间，如果eternal="false"，超过指定的时间，这个元素就被移走了。timeToIdleSeconds是发呆时间，是可选的。当往缓存里面put的元素超过500个时，如果overflowToDisk="true"，就会把缓存中的部分数据保存在硬盘上的临时文件里面。 <br /><br />　　每个需要缓存的class都要这样配置。如果你没有配置，hibernate会在启动的时候警告你，然后使用defaultCache的配置，这样多个class会共享一个配置。 <br /><br />　　当某个ID通过hibernate修改时，hibernate会知道，于是移除缓存。 <br /><br />　　这样大家可能会想，同样的查询条件，第一次先list，第二次再iterate，就可以使用到缓存了。实际上这是很难的，因为你无法判断什么时候是第一次，而且每次查询的条件通常是不一样的，假如数据库里面有100条记录，id从1到100，第一次list的时候出了前50个id，第二次iterate的时候却查询到30至70号id，那么30-50是从缓存里面取的，51到70是从数据库取的，共发送1+20条sql。所以我一直认为iterate没有什么用，总是会有1+N的问题。 <br /><br />　　（题外话：有说法说大型查询用list会把整个结果集装入内存，很慢，而iterate只select id比较好，但是大型查询总是要分页查的，谁也不会真的把整个结果集装进来，假如一页20条的话，iterate共需要执行21条语句，list虽然选择若干字段，比iterate第一条select id语句慢一些，但只有一条语句，不装入整个结果集hibernate还会根据数据库方言做优化，比如使用<a href="http://dev.21tx.com/database/mysql/" target="_blank"><font color="#3366cc">MySQL</font></a>的limit，整体看来应该还是list快。） <br /><br />　　如果想要对list或者iterate查询的结果缓存，就要用到查询缓存了<br /><br />　　<b>查询缓存 </b><br /><br />　　首先需要配置hibernate.cache.use_query_cache=true <br /><br />　　如果用ehcache，配置ehcache.xml，注意hibernate3.0以后不是net.sf的包名了：<br /><br /><table bordercolor="#cccccc" width="90%" align="center" bgcolor="#e7e9e9" border="1"><tbody><tr><td>＜cache name="net.sf.hibernate.cache.StandardQueryCache" <br />maxElementsInMemory="50" eternal="false" timeToIdleSeconds="3600" <br />timeToLiveSeconds="7200" overflowToDisk="true"/＞ <br />＜cache name="net.sf.hibernate.cache.UpdateTimestampsCache" <br />maxElementsInMemory="5000" eternal="true" overflowToDisk="true"/＞ </td></tr></tbody></table><br />　　然后 <br /><br /><table bordercolor="#cccccc" width="90%" align="center" bgcolor="#e7e9e9" border="1"><tbody><tr><td>query.setCacheable(true);//激活查询缓存 <br />query.setCacheRegion("myCacheRegion");//指定要使用的cacheRegion，可选 </td></tr></tbody></table><br />　　第二行指定要使用的cacheRegion是myCacheRegion，即你可以给每个查询缓存做一个单独的配置，使用setCacheRegion来做这个指定，需要在ehcache.xml里面配置它： <br /><br /><table bordercolor="#cccccc" width="90%" align="center" bgcolor="#e7e9e9" border="1"><tbody><tr><td>＜cache name="myCacheRegion" maxElementsInMemory="10" eternal="false" timeToIdleSeconds="3600" timeToLiveSeconds="7200" overflowToDisk="true" /＞ </td></tr></tbody></table><br />　　如果省略第二行，不设置cacheRegion的话，那么会使用上面提到的标准查询缓存的配置，也就是：net.sf.hibernate.cache.StandardQueryCache<br /><br />　　对于查询缓存来说，缓存的key是根据hql生成的sql，再加上参数，分页等信息（可以通过日志输出看到，不过它的输出不是很可读，最好改一下它的代码）。 <br /><br />　　比如hql： <br /><br /><table bordercolor="#cccccc" width="90%" align="center" bgcolor="#e7e9e9" border="1"><tbody><tr><td>from Cat c where c.name like ? </td></tr></tbody></table><br />　　生成大致如下的sql： <br /><br /><table bordercolor="#cccccc" width="90%" align="center" bgcolor="#e7e9e9" border="1"><tbody><tr><td>select * from cat c where c.name like ? </td></tr></tbody></table><br />　　参数是"tiger%"，那么查询缓存的key*大约*是这样的字符串（我是凭记忆写的，并不精确，不过看了也该明白了）： <br /><br /><table bordercolor="#cccccc" width="90%" align="center" bgcolor="#e7e9e9" border="1"><tbody><tr><td>select * from cat c where c.name like ? , parameter:tiger% </td></tr></tbody></table><br />　　这样，保证了同样的查询、同样的参数等条件下具有一样的key。 <br /><br />　　现在说说缓存的value，如果是list方式的话，value在这里并不是整个结果集，而是查询出来的这一串ID。也就是说，不管是list方法还是iterate方法，第一次查询的时候，它们的查询方式很它们平时的方式是一样的，list执行一条sql，iterate执行1+N条，多出来的行为是它们填充了缓存。但是到同样条件第二次查询的时候，就都和iterate的行为一样了，根据缓存的key去缓存里面查到了value，value是一串id，然后在到class的缓存里面去一个一个的load出来。这样做是为了节约内存。 <br /><br />　　可以看出来，查询缓存需要打开相关类的class缓存。list和iterate方法第一次执行的时候，都是既填充查询缓存又填充class缓存的。 <br />这里还有一个很容易被忽视的重要问题，即打开查询缓存以后，即使是list方法也可能遇到1+N的问题！相同条件第一次list的时候，因为查询缓存中找不到，不管class缓存是否存在数据，总是发送一条sql语句到数据库获取全部数据，然后填充查询缓存和class缓存。但是第二次执行的时候，问题就来了，如果你的class缓存的超时时间比较短，现在class缓存都超时了，但是查询缓存还在，那么list方法在获取id串以后，将会一个一个去数据库load！因此，class缓存的超时时间一定不能短于查询缓存设置的超时时间！如果还设置了发呆时间的话，保证class缓存的发呆时间也大于查询的缓存的生存时间。这里还有其他情况，比如class缓存被程序强制evict了，这种情况就请自己注意了。<br /><br />　　另外，如果hql查询包含select字句，那么查询缓存里面的value就是整个结果集了。<br /><br />　　当hibernate更新数据库的时候，它怎么知道更新哪些查询缓存呢？ <br /><br />　　hibernate在一个地方维护每个表的最后更新时间，其实也就是放在上面net.sf.hibernate.cache.UpdateTimestampsCache所指定的缓存配置里面。 <br /><br />　　当通过hibernate更新的时候，hibernate会知道这次更新影响了哪些表。然后它更新这些表的最后更新时间。每个缓存都有一个生成时间和这个缓存所查询的表，当hibernate查询一个缓存是否存在的时候，如果缓存存在，它还要取出缓存的生成时间和这个缓存所查询的表，然后去查找这些表的最后更新时间，如果有一个表在生成时间后更新过了，那么这个缓存是无效的。 <br /><br />　　可以看出，只要更新过一个表，那么凡是涉及到这个表的查询缓存就失效了，因此查询缓存的命中率可能会比较低。<br /><br /><strong>Collection缓存 <br /><br /></strong>　　需要在hbm的collection里面设置：<br /><br /><table bordercolor="#cccccc" width="90%" align="center" bgcolor="#e7e9e9" border="1"><tbody><tr><td>＜cache usage="read-write"/＞ </td></tr></tbody></table><br />　　假如class是Cat，collection叫children，那么ehcache里面配置 <br /><br /><table bordercolor="#cccccc" width="90%" align="center" bgcolor="#e7e9e9" border="1"><tbody><tr><td>＜cache name="com.xxx.pojo.Cat.children" <br />maxElementsInMemory="20" eternal="false" timeToIdleSeconds="3600" timeToLiveSeconds="7200" <br />overflowToDisk="true" /＞ </td></tr></tbody></table><br />　　Collection的缓存和前面查询缓存的list一样，也是只保持一串id，但它不会因为这个表更新过就失效，一个collection缓存仅在这个collection里面的元素有增删时才失效。 <br /><br />　　这样有一个问题，如果你的collection是根据某个字段排序的，当其中一个元素更新了该字段时，导致顺序改变时，collection缓存里面的顺序没有做更新。<br /><br />　　<b>缓存策略</b><br /><br />　　只读缓存（read-only）：没有什么好说的 <br /><br />　　读/写缓存（read-write）:程序可能要的更新数据 <br /><br />　　不严格的读/写缓存（nonstrict-read-write）：需要更新数据，但是两个事务更新同一条记录的可能性很小，性能比读写缓存好 <br />事务缓存（transactional）：缓存支持事务，发生异常的时候，缓存也能够回滚，只支持jta环境，这个我没有怎么研究过<br /><br />　　读写缓存和不严格读写缓存在实现上的区别在于，读写缓存更新缓存的时候会把缓存里面的数据换成一个锁，其他事务如果去取相应的缓存数据，发现被锁住了，然后就直接取<a href="http://dev.21tx.com/database/" target="_blank"><font color="#3366cc">数据库</font></a>查询。 <br /><br />　　在<a href="http://dev.21tx.com/java/struts/" target="_blank"><font color="#3366cc">Hibernate</font></a>2.1的ehcache实现中，如果锁住部分缓存的事务发生了异常，那么缓存会一直被锁住，直到60秒后超时。 <br /><br />　　不严格读写缓存不锁定缓存中的数据。 使用二级缓存的前置条件。<br /><br />　　你的hibernate程序对数据库有独占的写访问权，其他的进程更新了数据库，hibernate是不可能知道的。你操作数据库必需直接通过hibernate，如果你调用存储过程，或者自己使用<a href="http://dev.21tx.com/java/adv/jdbc/" target="_blank"><font color="#3366cc">JDBC</font></a>更新数据库，hibernate也是不知道的。hibernate3.0的大批量更新和删除是不更新二级缓存的，但是据说3.1已经解决了这个问题。 <br /><br />　　这个限制相当的棘手，有时候hibernate做批量更新、删除很慢，但是你却不能自己写jdbc来优化，很郁闷吧。 <br /><br />　　SessionFactory也提供了移除缓存的方法，你一定要自己写一些JDBC的话，可以调用这些方法移除缓存，这些方法是： <br /><br /><table bordercolor="#cccccc" width="90%" align="center" bgcolor="#e7e9e9" border="1"><tbody><tr><td>void evict(Class persistentClass) <br />Evict all entries from the second-level cache. <br />void evict(Class persistentClass, Serializable id) <br />Evict an entry from the second-level cache. <br />void evictCollection(String roleName) <br />Evict all entries from the second-level cache. <br />void evictCollection(String roleName, Serializable id) <br />Evict an entry from the second-level cache. <br />void evictQueries() <br />Evict any query result sets cached in the default query cache region. <br />void evictQueries(String cacheRegion) <br />Evict any query result sets cached in the named query cache region. </td></tr></tbody></table><br />　　不过我不建议这样做，因为这样很难维护。比如你现在用JDBC批量更新了某个表，有3个查询缓存会用到这个表，用evictQueries(String cacheRegion)移除了3个查询缓存，然后用evict(Class persistentClass)移除了class缓存，看上去好像完整了。不过哪天你添加了一个相关查询缓存，可能会忘记更新这里的移除代码。如果你的jdbc代码到处都是，在你添加一个查询缓存的时候，还知道其他什么地方也要做相应的改动吗？<br /><br />　　<b>总结</b>： <br /><br />　　不要想当然的以为缓存一定能提高性能，仅仅在你能够驾驭它并且条件合适的情况下才是这样的。hibernate的二级缓存限制还是比较多的，不方便用jdbc可能会大大的降低更新性能。在不了解原理的情况下乱用，可能会有1+N的问题。不当的使用还可能导致读出脏数据。 <br />如果受不了hibernate的诸多限制，那么还是自己在应用程序的层面上做缓存吧。 <br /><br />　　在越高的层面上做缓存，效果就会越好。就好像尽管磁盘有缓存，数据库还是要实现自己的缓存，尽管数据库有缓存，咱们的应用程序还是要做缓存。因为底层的缓存它并不知道高层要用这些数据干什么，只能做的比较通用，而高层可以有针对性的实现缓存，所以在更高的级别上做缓存，效果也要好些吧。 <img src ="http://www.blogjava.net/jdo/aggbug/135788.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jdo/" target="_blank">蓝色幽默</a> 2007-08-10 13:24 <a href="http://www.blogjava.net/jdo/articles/135788.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Hibernate+Struts分页代码(节选)</title><link>http://www.blogjava.net/jdo/articles/134831.html</link><dc:creator>蓝色幽默</dc:creator><author>蓝色幽默</author><pubDate>Mon, 06 Aug 2007 16:47:00 GMT</pubDate><guid>http://www.blogjava.net/jdo/articles/134831.html</guid><wfw:comment>http://www.blogjava.net/jdo/comments/134831.html</wfw:comment><comments>http://www.blogjava.net/jdo/articles/134831.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jdo/comments/commentRss/134831.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jdo/services/trackbacks/134831.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 转自：http://blog.csdn.net/yeno/archive/2007/01/25/1492788.aspxCode highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->public class HibernateUtil {    private Hi...&nbsp;&nbsp;<a href='http://www.blogjava.net/jdo/articles/134831.html'>阅读全文</a><img src ="http://www.blogjava.net/jdo/aggbug/134831.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jdo/" target="_blank">蓝色幽默</a> 2007-08-07 00:47 <a href="http://www.blogjava.net/jdo/articles/134831.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[原创]Hibernate入门(1)</title><link>http://www.blogjava.net/jdo/articles/134430.html</link><dc:creator>蓝色幽默</dc:creator><author>蓝色幽默</author><pubDate>Sat, 04 Aug 2007 12:20:00 GMT</pubDate><guid>http://www.blogjava.net/jdo/articles/134430.html</guid><wfw:comment>http://www.blogjava.net/jdo/comments/134430.html</wfw:comment><comments>http://www.blogjava.net/jdo/articles/134430.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jdo/comments/commentRss/134430.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jdo/services/trackbacks/134430.html</trackback:ping><description><![CDATA[
		<div align="left">
				<i>说明下，我也是新手，我现在的目的是为了快速上手Hibernate（以下简称H），因此并没有作深入研究。</i>
				<br />
		</div>
		<br />
		<div align="left">参考资料：《Hibernate_Reference》、《深入浅出Hibernate》<br /><br /><br /><b>正文<br /><br /></b>下面我们将创建一个简单的基于控制台的(console-based)Hibernate应用程序。<br /><p>我们所做的第一件事就是创建我们的开发目录，并且把所有需要用到的Java库文件放进去。万幸的是我们有了myeclipse，由他创建的工程可以很方便地打包，然后交给另一个同样拥有myeclipse的使用者，只需要简单的导入即可使用^_^</p><p><u>右键工程目录 → myeclipse → Add Hibernate……</u><br /></p><p>这样子你的工程就可以导入Hibernate所需要的所有库文件，接下来我们创建一个类，用来代表那些我们希望储存在数据库里的event。 </p><br /><b>1.1<br /></b>这里假设你已经拥有了一个数据库，并且尽量将数据库中的各种关联设置完毕，如果你能这样子做，接下来的事情将会变得非常简单^_^<br /><br /><u>打开透视图（perspective）中的myeclipse database exploer<br /><br /></u>在里面我们要配置下数据源<br /><br /><img src="http://photo1.yupoo.com/20070804/194944_2098458874_eetpnpop.jpg" /><br /><br />完成后即可建立连接，然后我们就可以用myec自带的工具进行映射配置，如下图：<br /><br /><img src="http://photo8.yupoo.com/20070804/194937_708013566_twwjrgda.jpg" /><br /><br /><br /><b>1.2</b><br /><br />一路默认即可，最后将会生成一堆配置的文件一共有3类：<br />1.持久化类，就是一个带有一些属性（property）的简单JavaBean类如：<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">abstract</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> AbstractTest </span><span style="color: rgb(0, 0, 255);">implements</span><span style="color: rgb(0, 0, 0);"> java.io.Serializable {<br /><br />    </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> Fields</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);"><br />    </span><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);"> Integer id;<br /><br />    </span><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);"> String name;<br /><br />    </span><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);"> Set</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">Testaddr</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"> testaddr </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> HashSet</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">Testaddr</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">);<br /><br />    </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> Set</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">Testaddr</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"> getTestaddr() {<br />        </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> testaddr;<br />    }<br /><br />    </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> setTestaddr(Set</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">Testaddr</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"> testaddr) {<br />        </span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">.testaddr </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> testaddr;<br />    }<br /><br />    </span><span style="color: rgb(0, 128, 0);">/**</span><span style="color: rgb(0, 128, 0);"> default constructor </span><span style="color: rgb(0, 128, 0);">*/</span><span style="color: rgb(0, 0, 0);"><br />    </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> AbstractTest() {<br />    }<br /><br />    </span><span style="color: rgb(0, 128, 0);">/**</span><span style="color: rgb(0, 128, 0);"> full constructor </span><span style="color: rgb(0, 128, 0);">*/</span><span style="color: rgb(0, 0, 0);"><br />    </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> AbstractTest(Integer id, String name) {<br />        </span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">.id </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> id;<br />        </span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">.name </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> name;<br />    }<br /><br />    </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> Property accessors</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);"><br />    </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> Integer getId() {<br />        </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">.id;<br />    }<br /><br />    </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> setId(Integer id) {<br />        </span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">.id </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> id;<br />    }<br /><br />    </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> String getName() {<br />        </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">.name;<br />    }<br /><br />    </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> setName(String name) {<br />        </span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">.name </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> name;<br />    }<br /><br />}</span></div><br />你可以看到这个类对属性的存取方法（getter and setter 
method）使用了标准JavaBean命名约定，同时把类属性（field）的访问级别设成私有的（private）。这是推荐的设计，但并不是必须的。<br /><br />2.xml映射配置<br /><br />Hibernate需要知道怎样去加载（load）和存储（store）持久化类的对象。这正是Hibernate映射文件发挥作用的地方。映射文件告诉Hibernate它，应该访问数据库(database)里面的哪个表（table）及应该使用表里面的哪些字段（column）。 

<p>一个映射文件的基本结构看起来像这样：</p><br /><p></p><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">&lt;?</span><span style="color: rgb(255, 0, 255);">xml version="1.0" encoding="utf-8"</span><span style="color: rgb(0, 0, 255);">?&gt;</span><span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 0, 255);">&lt;!</span><span style="color: rgb(255, 0, 255);">DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"<br />"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 128, 0);">&lt;!--</span><span style="color: rgb(0, 128, 0);"> <br />    Mapping file autogenerated by MyEclipse Persistence Tools<br /></span><span style="color: rgb(0, 128, 0);">--&gt;</span><span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">hibernate-mapping</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />    </span><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">class </span><span style="color: rgb(255, 0, 0);">name</span><span style="color: rgb(0, 0, 255);">="HibernateFactory.Test"</span><span style="color: rgb(255, 0, 0);"> table</span><span style="color: rgb(0, 0, 255);">="test"</span><span style="color: rgb(255, 0, 0);"><br />        catalog</span><span style="color: rgb(0, 0, 255);">="himessage"</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />        </span><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">id </span><span style="color: rgb(255, 0, 0);">name</span><span style="color: rgb(0, 0, 255);">="id"</span><span style="color: rgb(255, 0, 0);"> type</span><span style="color: rgb(0, 0, 255);">="java.lang.Integer"</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />            </span><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">column </span><span style="color: rgb(255, 0, 0);">name</span><span style="color: rgb(0, 0, 255);">="id"</span><span style="color: rgb(255, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">/&gt;</span><span style="color: rgb(0, 0, 0);"><br />            </span><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">generator </span><span style="color: rgb(255, 0, 0);">class</span><span style="color: rgb(0, 0, 255);">="native"</span><span style="color: rgb(255, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">/&gt;</span><span style="color: rgb(0, 0, 0);"><br />        </span><span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">id</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />        </span><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">property </span><span style="color: rgb(255, 0, 0);">name</span><span style="color: rgb(0, 0, 255);">="name"</span><span style="color: rgb(255, 0, 0);"> type</span><span style="color: rgb(0, 0, 255);">="java.lang.String"</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />            </span><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">column </span><span style="color: rgb(255, 0, 0);">name</span><span style="color: rgb(0, 0, 255);">="name"</span><span style="color: rgb(255, 0, 0);"> not-null</span><span style="color: rgb(0, 0, 255);">="true"</span><span style="color: rgb(255, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">/&gt;</span><span style="color: rgb(0, 0, 0);"><br />        </span><span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">property</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);"><br /><br />        </span><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">set </span><span style="color: rgb(255, 0, 0);">name</span><span style="color: rgb(0, 0, 255);">="testaddr"</span><span style="color: rgb(255, 0, 0);"> cascade</span><span style="color: rgb(0, 0, 255);">="all"</span><span style="color: rgb(255, 0, 0);"> lazy</span><span style="color: rgb(0, 0, 255);">="false"</span><span style="color: rgb(255, 0, 0);"> inverse</span><span style="color: rgb(0, 0, 255);">="true"</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />            </span><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">key </span><span style="color: rgb(255, 0, 0);">column</span><span style="color: rgb(0, 0, 255);">="test_id"</span><span style="color: rgb(0, 0, 255);">&gt;&lt;/</span><span style="color: rgb(128, 0, 0);">key</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />            </span><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">one-to-many </span><span style="color: rgb(255, 0, 0);">class</span><span style="color: rgb(0, 0, 255);">="HibernateFactory.Testaddr"</span><span style="color: rgb(255, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">/&gt;</span><span style="color: rgb(0, 0, 0);"><br />        </span><span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">set</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);"><br /><br />    </span><span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">class</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">hibernate-mapping</span><span style="color: rgb(0, 0, 255);">&gt;</span></div><p>在<code class="literal">hibernate-mapping</code>标签（tag）之间, 含有一个<code class="literal">class</code>元素。所有的持久化实体类（再次声明，或许接下来会有依赖类，就是那些次要的实体）都需要一个这样的映射，来把类对象映射到SQL数据库里的表。 <br /></p><p><code class="literal">id</code>元素是标识符属性的声明，<code class="literal">name="id"</code> 
声明了Java属性的名字 － Hibernate会使用<code class="literal">getId()</code>和<code class="literal">setId()</code>来访问它。 <code class="literal">column</code>属性则告诉Hibernate, 我们使用<code class="literal">EVENTS</code>表的哪个字段作为主键。嵌套的<code class="literal">generator</code>元素指定了标识符生成策略，在这里我们指定<code class="literal">native</code>，它根据已配置的数据库自动选择最佳的标识符生成策略。Hibernate支持由数据库生成，全局唯一性（globally 
unique）和应用程序指定（或者你自己为任何已有策略所写的扩展）这些策略来生成标识符。  </p>关于具体的配置请参阅《深入浅出Hibernate》P146 数据关联，所有的参数表请查此书P411<br /><br />3.Hibernate配置<br />现在我们已经有了一个持久化类和它的映射文件，该是配置Hibernate的时候了。<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">&lt;?</span><span style="color: rgb(255, 0, 255);">xml version='1.0' encoding='UTF-8'</span><span style="color: rgb(0, 0, 255);">?&gt;</span><span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 0, 255);">&lt;!</span><span style="color: rgb(255, 0, 255);">DOCTYPE hibernate-configuration PUBLIC<br />          "-//Hibernate/Hibernate Configuration DTD 3.0//EN"<br />          "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);"><br /><br /></span><span style="color: rgb(0, 128, 0);">&lt;!--</span><span style="color: rgb(0, 128, 0);"> Generated by MyEclipse Hibernate Tools.                   </span><span style="color: rgb(0, 128, 0);">--&gt;</span><span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">hibernate-configuration</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);"><br /><br />    </span><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">session-factory</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />        </span><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">property </span><span style="color: rgb(255, 0, 0);">name</span><span style="color: rgb(0, 0, 255);">="show_sql"</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);">true</span><span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">property</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />        </span><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">property </span><span style="color: rgb(255, 0, 0);">name</span><span style="color: rgb(0, 0, 255);">="connection.username"</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);">root</span><span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">property</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />        </span><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">property </span><span style="color: rgb(255, 0, 0);">name</span><span style="color: rgb(0, 0, 255);">="connection.url"</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />            jdbc:mysql://localhost/himessage?useUnicode=true</span><span style="color: rgb(255, 0, 0);">&amp;amp;</span><span style="color: rgb(0, 0, 0);">amp;characterEncoding=utf-8<br />        </span><span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">property</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />        </span><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">property </span><span style="color: rgb(255, 0, 0);">name</span><span style="color: rgb(0, 0, 255);">="dialect"</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />            org.hibernate.dialect.MySQLDialect<br />        </span><span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">property</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />        </span><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">property </span><span style="color: rgb(255, 0, 0);">name</span><span style="color: rgb(0, 0, 255);">="myeclipse.connection.profile"</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);">Hb</span><span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">property</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />        </span><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">property </span><span style="color: rgb(255, 0, 0);">name</span><span style="color: rgb(0, 0, 255);">="connection.password"</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);">1234</span><span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">property</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />        </span><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">property </span><span style="color: rgb(255, 0, 0);">name</span><span style="color: rgb(0, 0, 255);">="connection.driver_class"</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />            com.mysql.jdbc.Driver<br />        </span><span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">property</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />        </span><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">mapping </span><span style="color: rgb(255, 0, 0);">resource</span><span style="color: rgb(0, 0, 255);">="HibernateFactory/Admin.hbm.xml"</span><span style="color: rgb(255, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">/&gt;</span><span style="color: rgb(0, 0, 0);"><br />        </span><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">mapping </span><span style="color: rgb(255, 0, 0);">resource</span><span style="color: rgb(0, 0, 255);">="HibernateFactory/Test.hbm.xml"</span><span style="color: rgb(255, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">/&gt;</span><span style="color: rgb(0, 0, 0);"><br />        </span><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">mapping </span><span style="color: rgb(255, 0, 0);">resource</span><span style="color: rgb(0, 0, 255);">="HibernateFactory/Testaddr.hbm.xml"</span><span style="color: rgb(255, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">/&gt;</span><span style="color: rgb(0, 0, 0);"><br /><br />    </span><span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">session-factory</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);"><br /><br /></span><span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">hibernate-configuration</span><span style="color: rgb(0, 0, 255);">&gt;</span></div><br />这里需要特别指出的是<span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">property </span><span style="color: rgb(255, 0, 0);">name</span><span style="color: rgb(0, 0, 255);">="show_sql"</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);">true</span><span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">property</span><span style="color: rgb(0, 0, 255);">&gt;<br /><font color="#000000">用了这句我们可以直接在ec控制台看到</font></span>Hibernate生成的sql语句，对调试程序是相当有帮助的！<br /><br />示例的基本框架完成了 － 现在我们可以用Hibernate来做些真正的工作。 <br /><br /><b>1.3</b><br />我们终于可以使用Hibernate来加载和存储对象了，编写一个带有<code class="literal">main()</code>方法的<code class="literal">AdminActionr</code>类： <br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> AdminAction {<br />    </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">static</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> main(String[] args) {<br />        Session session </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> HibernateSessionFactory.getSession();<br />        session.beginTransaction();<br /></span><span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 0);">    Admin admin </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> Admin();<br /></span><span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 0);">    admin.setEmail(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">tantan85@163.com</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br /></span><span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 0);">    admin.setName(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">tantan</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />    </span><span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 0);">admin.setPsw(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">111111</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />        admin.setAddAdmin(</span><span style="color: rgb(0, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">);<br />        session.save(admin);<br />        session.getTransaction().commit();<br />    }<br />}</span></div><br />我们创建了个新的<code class="literal">Admin</code>对象并把它传递给Hibernate。现在Hibernate负责与SQL打交道，并把<code class="literal">INSERT</code>命令传给数据库。在运行之前，让我们看一下处理<code class="literal">Session</code>和<code class="literal">Transaction</code>的代码。 <br /><br />一个<code class="literal">Session</code>就是个单一的工作单元。我们暂时让事情简单一些，并假设Hibernate<code class="literal">Session</code>和数据库事务是一一对应的。<br /><span style="color: rgb(0, 0, 0);">HibernateSessionFactory.getSession()</span>是干什么的呢？返回“当前的”工作单元。<br />getTransaction()则表示取出一个事务对象，commit()则是事务的提交，即将缓存中的数据写入数据库。<br /><br />就是这么面向对象的方法，你就完成了传统的sql语句的功能，是不是很爽？更爽的是你还可以用hql语言来完成更强大的功能，当然这里不可能一一列举，只有看书了，请参考《深入浅出Hibernate》P173 ^_^<br /></div>
<img src ="http://www.blogjava.net/jdo/aggbug/134430.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jdo/" target="_blank">蓝色幽默</a> 2007-08-04 20:20 <a href="http://www.blogjava.net/jdo/articles/134430.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[原创]Hibernate过滤器</title><link>http://www.blogjava.net/jdo/articles/134423.html</link><dc:creator>蓝色幽默</dc:creator><author>蓝色幽默</author><pubDate>Sat, 04 Aug 2007 10:30:00 GMT</pubDate><guid>http://www.blogjava.net/jdo/articles/134423.html</guid><wfw:comment>http://www.blogjava.net/jdo/comments/134423.html</wfw:comment><comments>http://www.blogjava.net/jdo/articles/134423.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jdo/comments/commentRss/134423.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jdo/services/trackbacks/134423.html</trackback:ping><description><![CDATA[最近在项目中使用了Struts + Hibernate的组合，在session和事务管理上遇到了些问题，查阅了一些资料后，决定采用servlet的过滤器来解决管理问题。<br /><br />主要修改了<span style="color: rgb(0, 0, 0);">HibernateSessionFactory.java（由原文件由myeclipse自动生成的）</span><span style="color: rgb(0, 0, 0);"></span><br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> HibernateSessionFactory {<br /><br />    </span><span style="color: rgb(0, 128, 0);">/**</span><span style="color: rgb(0, 128, 0);"><br />     * Location of hibernate.cfg.xml file. Location should be on the classpath<br />     * as Hibernate uses #resourceAsStream style lookup for its configuration<br />     * file. The default classpath location of the hibernate config file is in<br />     * the default package. Use #setConfigFile() to update the location of the<br />     * configuration file for the current session.<br />     </span><span style="color: rgb(0, 128, 0);">*/</span><span style="color: rgb(0, 0, 0);"><br />    </span><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">static</span><span style="color: rgb(0, 0, 0);"> String CONFIG_FILE_LOCATION </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">/hibernate.cfg.xml</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">;<br /><br />    </span><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">static</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">final</span><span style="color: rgb(0, 0, 0);"> ThreadLocal</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">Session</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"> threadLocal </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> ThreadLocal</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">Session</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);">();<br /><br />    </span><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">static</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">final</span><span style="color: rgb(0, 0, 0);"> ThreadLocal</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">Transaction</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"> tLocaltx </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> ThreadLocal</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">Transaction</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);">();<br /><br />    </span><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">static</span><span style="color: rgb(0, 0, 0);"> Configuration configuration </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> Configuration();<br /><br />    </span><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">static</span><span style="color: rgb(0, 0, 0);"> org.hibernate.SessionFactory sessionFactory;<br /><br />    </span><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">static</span><span style="color: rgb(0, 0, 0);"> String configFile </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> CONFIG_FILE_LOCATION;<br /><br />    </span><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);"> HibernateSessionFactory() {<br />    }<br /><br />    </span><span style="color: rgb(0, 128, 0);">/**</span><span style="color: rgb(0, 128, 0);"><br />     * Returns the ThreadLocal Session instance. Lazy initialize the<br />     * &lt;code&gt;SessionFactory&lt;/code&gt; if needed.<br />     * <br />     * </span><span style="color: rgb(128, 128, 128);">@return</span><span style="color: rgb(0, 128, 0);"> Session<br />     * </span><span style="color: rgb(128, 128, 128);">@throws</span><span style="color: rgb(0, 128, 0);"> HibernateException<br />     </span><span style="color: rgb(0, 128, 0);">*/</span><span style="color: rgb(0, 0, 0);"><br />    </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">static</span><span style="color: rgb(0, 0, 0);"> Session getSession() </span><span style="color: rgb(0, 0, 255);">throws</span><span style="color: rgb(0, 0, 0);"> HibernateException {<br />        Session session </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> (Session) threadLocal.get();<br /><br />        </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (session </span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">||</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">!</span><span style="color: rgb(0, 0, 0);">session.isOpen()) {<br />            </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (sessionFactory </span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);">) {<br />                rebuildSessionFactory();<br />            }<br />            session </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> (sessionFactory </span><span style="color: rgb(0, 0, 0);">!=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);">) </span><span style="color: rgb(0, 0, 0);">?</span><span style="color: rgb(0, 0, 0);"> sessionFactory.openSession() : </span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);">;<br />            threadLocal.set(session);<br />        }<br /><br />        </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> session;<br />    }<br /><br />    </span><span style="color: rgb(0, 128, 0);">/**</span><span style="color: rgb(0, 128, 0);"><br />     * Rebuild hibernate session factory<br />     * <br />     </span><span style="color: rgb(0, 128, 0);">*/</span><span style="color: rgb(0, 0, 0);"><br />    </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">static</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> rebuildSessionFactory() {<br />        </span><span style="color: rgb(0, 0, 255);">try</span><span style="color: rgb(0, 0, 0);"> {<br />            configuration.configure(configFile);<br />            sessionFactory </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> configuration.buildSessionFactory();<br />        } </span><span style="color: rgb(0, 0, 255);">catch</span><span style="color: rgb(0, 0, 0);"> (Exception e) {<br />            System.err.println(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">%%%% Error Creating SessionFactory %%%%</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />            e.printStackTrace();<br />        }<br />    }<br /><br />    </span><span style="color: rgb(0, 128, 0);">/**</span><span style="color: rgb(0, 128, 0);"><br />     * Close the single hibernate session instance.<br />     * <br />     * </span><span style="color: rgb(128, 128, 128);">@throws</span><span style="color: rgb(0, 128, 0);"> HibernateException<br />     </span><span style="color: rgb(0, 128, 0);">*/</span><span style="color: rgb(0, 0, 0);"><br />    </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">static</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> closeSession() </span><span style="color: rgb(0, 0, 255);">throws</span><span style="color: rgb(0, 0, 0);"> HibernateException {<br />        Session session </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> (Session) threadLocal.get();<br />        threadLocal.set(</span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);">);<br /><br />        </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (session </span><span style="color: rgb(0, 0, 0);">!=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);">) {<br />            session.close();<br />        }<br />    }<br /><br />    </span><span style="color: rgb(0, 128, 0);">/**</span><span style="color: rgb(0, 128, 0);"><br />     * return session factory<br />     * <br />     </span><span style="color: rgb(0, 128, 0);">*/</span><span style="color: rgb(0, 0, 0);"><br />    </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">static</span><span style="color: rgb(0, 0, 0);"> org.hibernate.SessionFactory getSessionFactory() {<br />        </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> sessionFactory;<br />    }<br /><br />    </span><span style="color: rgb(0, 128, 0);">/**</span><span style="color: rgb(0, 128, 0);"><br />     * return session factory<br />     * <br />     * session factory will be rebuilded in the next call<br />     </span><span style="color: rgb(0, 128, 0);">*/</span><span style="color: rgb(0, 0, 0);"><br />    </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">static</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> setConfigFile(String configFile) {<br />        HibernateSessionFactory.configFile </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> configFile;<br />        sessionFactory </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);">;<br />    }<br /><br />    </span><span style="color: rgb(0, 128, 0);">/**</span><span style="color: rgb(0, 128, 0);"><br />     * return hibernate configuration<br />     * <br />     </span><span style="color: rgb(0, 128, 0);">*/</span><span style="color: rgb(0, 0, 0);"><br />    </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">static</span><span style="color: rgb(0, 0, 0);"> Configuration getConfiguration() {<br />        </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> configuration;<br />    }<br /><br />    </span><span style="color: rgb(0, 128, 0);">/**</span><span style="color: rgb(0, 128, 0);"><br />     * 打开一个事务<br />     </span><span style="color: rgb(0, 128, 0);">*/</span><span style="color: rgb(0, 0, 0);"><br />    </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">static</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> beginTransaction() {<br />        Transaction tx </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> tLocaltx.get();<br />        </span><span style="color: rgb(0, 0, 255);">try</span><span style="color: rgb(0, 0, 0);"> {<br />            </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (tx </span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);">) {<br />                tx </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> getSession().beginTransaction();<br />                tLocaltx.set(tx);<br />            }<br />        } </span><span style="color: rgb(0, 0, 255);">catch</span><span style="color: rgb(0, 0, 0);"> (Exception e) {<br />            System.err.println(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">%%%% Error beginTransaction %%%%</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />            e.printStackTrace();<br />        }<br />    }<br /><br />    </span><span style="color: rgb(0, 128, 0);">/**</span><span style="color: rgb(0, 128, 0);"><br />     * 关闭一个事务<br />     </span><span style="color: rgb(0, 128, 0);">*/</span><span style="color: rgb(0, 0, 0);"><br />    </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">static</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> commitTransaction() {<br />        Transaction tx </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> tLocaltx.get();<br />        </span><span style="color: rgb(0, 0, 255);">try</span><span style="color: rgb(0, 0, 0);"> {<br />            </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (tx </span><span style="color: rgb(0, 0, 0);">!=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">&amp;&amp;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">!</span><span style="color: rgb(0, 0, 0);">tx.wasCommitted() </span><span style="color: rgb(0, 0, 0);">&amp;&amp;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">!</span><span style="color: rgb(0, 0, 0);">tx.wasRolledBack()) {<br />                tx.commit();<br />                </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">一个事务结束就立即解除与tLocaltx的关联</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">                tLocaltx.set(</span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);">);<br />            }<br />        } </span><span style="color: rgb(0, 0, 255);">catch</span><span style="color: rgb(0, 0, 0);"> (Exception e) {<br />            System.err.println(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">%%%% Error commitTransaction %%%%</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />            e.printStackTrace();<br />        }<br />    }<br />    <br />    </span><span style="color: rgb(0, 128, 0);">/**</span><span style="color: rgb(0, 128, 0);"><br />     * 事务回滚<br />     </span><span style="color: rgb(0, 128, 0);">*/</span><span style="color: rgb(0, 0, 0);"><br />    </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">static</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> rollbackTransaction() {<br />        Transaction tx </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> tLocaltx.get();<br />        </span><span style="color: rgb(0, 0, 255);">try</span><span style="color: rgb(0, 0, 0);"> {<br />            tLocaltx.set(</span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);">);<br />            </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (tx </span><span style="color: rgb(0, 0, 0);">!=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">&amp;&amp;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">!</span><span style="color: rgb(0, 0, 0);">tx.wasCommitted() </span><span style="color: rgb(0, 0, 0);">&amp;&amp;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">!</span><span style="color: rgb(0, 0, 0);">tx.wasRolledBack()) <br />                tx.rollback();<br />        } </span><span style="color: rgb(0, 0, 255);">catch</span><span style="color: rgb(0, 0, 0);"> (Exception e) {<br />            System.err.println(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">%%%% Error rollbackTransaction %%%%</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />            e.printStackTrace();<br />        }<br />    }<br />}</span></div><br /><span style="color: rgb(0, 0, 0);">在myec生成的HibernateSessionFactory源代码</span>中，保证了在一次请求过程中共享单一的session实例，我们现在要加入的内容就是在一次请求中共享一个<span style="color: rgb(0, 0, 0);">Transaction实例，</span>很明显，中文部分是增加的内容。添加的代码封装了事务的开始，提交以及回滚。这样子session和<span style="color: rgb(0, 0, 0);">Transaction实例可以跨越一次请求的多种方法，这有助于实现集合的延迟加载等</span><span style="color: rgb(0, 0, 0);">Hibernate特性。<br /><br />在用的时候，我们就应该使用封装后的</span>事务方法和session方法，使用方法如下：<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">获得唯一的session 实例</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">Session session </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> HibernateSessionFactory.getSession();<br /><br />HibernateSessionFactory.beginTransaction();<br /></span><span style="color: rgb(0, 128, 0);">//do something……（</span><span style="color: rgb(0, 128, 0);">数据库操作如：添加、删除等）</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">HibernateSessionFactory.commitTransaction();</span></div><br />在我们的项目中，BaseDAO类封装了<span style="color: rgb(0, 0, 0);">Hibernate常用的数据库操作方法，其中</span><span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 0);">HibernateSessionFactory.beginTransaction()已经一起封入了</span>BaseDAO类，于是，我们便不用在使用代码中加入事务开始的方法，直接调用<span style="color: rgb(0, 0, 0);"></span>BaseDAO类的方法即可。在调试过程中，如果我们需要测试数据是否能够写入数据库，就应该手工调用事务结束方法<span style="color: rgb(0, 0, 0);">HibernateSessionFactory.commitTransaction()，即可立即</span>写入数据库。<br /><br /><b>注意：在一次业务逻辑中，只能用一次事务提交，也只需要一次事务提交，我们一般把事务提交放到语句执行的最后面。（如果你用了多次提交，只对第一次提交有效！）</b><br /><br /><span style="color: rgb(0, 0, 0);">下面举例：<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">testDAO 继承 BaseDAO </span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">class </span><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);">test</span></span><span style="color: rgb(0, 0, 0);">DAO </span><span style="color: rgb(0, 0, 255);">extends</span><span style="color: rgb(0, 0, 0);"> BaseDAO {<br />    </span><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 255);"></span><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 0, 0);">test</span></span><span style="color: rgb(0, 0, 0);">DAO</span></span><span style="color: rgb(0, 0, 0);">(){<br />        </span><span style="color: rgb(0, 0, 255);">super</span><span style="color: rgb(0, 0, 0);">();<br />    }<br />}</span></div><br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> testAction {<br />    </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">static</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> main(String[] args) {<br />        ActionDAO ad </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> ActionDAO();<br />        ad.add(object);<br />        </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> 手工调用事务提交，可将缓存中的数据立即写入数据库</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">        HibernateSessionFactory.commitTransaction();<br />        </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> 手工调用session关闭</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">        HibernateSessionFactory.closeSession();<br />    }<br />}<br /></span></div><br />但在实际的应用中，我们应该把测试用的手工代码删除，因为事务和session的关闭还有事务的回滚是通过过滤器来完成的，当然过滤器需要servlet</span>的支持，我们先来看看过滤器的代码：<br /><span style="color: rgb(0, 0, 0);"><span style="color: rgb(0, 128, 0);"></span></span><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> CloseSessionFilter </span><span style="color: rgb(0, 0, 255);">extends</span><span style="color: rgb(0, 0, 0);"> HttpServlet </span><span style="color: rgb(0, 0, 255);">implements</span><span style="color: rgb(0, 0, 0);"> Filter {</span><span style="color: rgb(0, 128, 0);"></span><span style="color: rgb(0, 128, 0);"></span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 128, 0);">/**</span><span style="color: rgb(0, 128, 0);"><br />     * <br />     </span><span style="color: rgb(0, 128, 0);">*/</span><span style="color: rgb(0, 0, 0);"><br />    </span><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">static</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">final</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">long</span><span style="color: rgb(0, 0, 0);"> serialVersionUID </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">1L</span><span style="color: rgb(0, 0, 0);">;<br /><br />    </span><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);"> FilterConfig filterConfig;<br /><br />    </span><span style="color: rgb(0, 0, 255);">protected</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">boolean</span><span style="color: rgb(0, 0, 0);"> enable; </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> 是否起用此过滤器</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);"><br />    </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> init(FilterConfig filterConfig) </span><span style="color: rgb(0, 0, 255);">throws</span><span style="color: rgb(0, 0, 0);"> ServletException {<br />        </span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">.filterConfig </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> filterConfig;<br />        loadConfigParams();<br />    }<br /><br />    </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> loadConfigParams() { </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> 取得初始化参数</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">        String enableStr </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">.filterConfig.getInitParameter(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">enable</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />        </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (enableStr.trim().equals(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">true</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">)) {<br />            </span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">.enable </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">true</span><span style="color: rgb(0, 0, 0);">;<br />        } </span><span style="color: rgb(0, 0, 255);">else</span><span style="color: rgb(0, 0, 0);"> {<br />            </span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">.enable </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">false</span><span style="color: rgb(0, 0, 0);">;<br />        }<br />    }<br /><br />    </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> Process the request/response pair</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) {<br />        </span><span style="color: rgb(0, 0, 255);">try</span><span style="color: rgb(0, 0, 0);"> {<br />            filterChain.doFilter(request, response);<br />        } </span><span style="color: rgb(0, 0, 255);">catch</span><span style="color: rgb(0, 0, 0);"> (Exception sx) {<br />        } </span><span style="color: rgb(0, 0, 255);">finally</span><span style="color: rgb(0, 0, 0);"> {<br />            </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (enable) {<br />                </span><span style="color: rgb(0, 0, 255);">try</span><span style="color: rgb(0, 0, 0);"> {<br />                    HibernateSessionFactory.commitTransaction();<br />                } </span><span style="color: rgb(0, 0, 255);">catch</span><span style="color: rgb(0, 0, 0);"> (Exception e) {<br />                    HibernateSessionFactory.rollbackTransaction();<br />                } </span><span style="color: rgb(0, 0, 255);">finally</span><span style="color: rgb(0, 0, 0);"> {<br />                    HibernateSessionFactory.closeSession();<br />                }<br />            }<br />        }<br />    }<br /><br />    </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> Clean up resources</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> destroy() {<br />    }<br />}</span></div><br />相应的web.xml配置：<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 128, 0);">&lt;!--</span><span style="color: rgb(0, 128, 0);"> 过滤器 settings: </span><span style="color: rgb(0, 128, 0);">--&gt;</span><span style="color: rgb(0, 0, 0);"><br />    </span><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">filter</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />        </span><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">filter-name</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);">CloseSessionFilter</span><span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">filter-name</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />        </span><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">filter-class</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />            com.struts.common.CloseSessionFilter<br />        </span><span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">filter-class</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />        </span><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">init-param</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />            </span><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">param-name</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);">enable</span><span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">param-name</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />            </span><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">param-value</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);">true</span><span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">param-value</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />        </span><span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">init-param</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />    </span><span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">filter</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />    <br />    </span><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">filter-mapping</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />        </span><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">filter-name</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 255);"></span><span style="color: rgb(0, 0, 0);">CloseSessionFilter</span><span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">filter-name</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />        </span><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">servlet-name</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);">action</span><span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">servlet-name</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />    </span><span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">filter-mapping</span><span style="color: rgb(0, 0, 255);">&gt;</span></div><br /><br />需要注意的是多个过滤器之间的顺序位置，<span style="color: rgb(0, 0, 0);">filterChain.doFilter(request, response);是指调用下一个过滤器，也就是说，要调用完所有过滤器后，才会继续运行</span><span style="color: rgb(0, 0, 0);">filterChain.doFilter(request, response);下面的内容，这是一个递归的过程。所以，在web.xml的配置中，我们要把</span><span style="color: rgb(0, 0, 0);">Hibernate过滤器放在第一位，确保所有servlet运行完毕后，才调用最后的关闭方法。<br /><br /><br /></span><span style="color: rgb(0, 0, 0);"></span><img src ="http://www.blogjava.net/jdo/aggbug/134423.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jdo/" target="_blank">蓝色幽默</a> 2007-08-04 18:30 <a href="http://www.blogjava.net/jdo/articles/134423.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>myeclipse试用小记----多对一单向关联（1）</title><link>http://www.blogjava.net/jdo/articles/133881.html</link><dc:creator>蓝色幽默</dc:creator><author>蓝色幽默</author><pubDate>Wed, 01 Aug 2007 15:59:00 GMT</pubDate><guid>http://www.blogjava.net/jdo/articles/133881.html</guid><wfw:comment>http://www.blogjava.net/jdo/comments/133881.html</wfw:comment><comments>http://www.blogjava.net/jdo/articles/133881.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jdo/comments/commentRss/133881.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jdo/services/trackbacks/133881.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 转自：http://lavasoft.blog.51cto.com/62575/d-5说明：一个客户可以对应多个订单。以此为例说明用myeclipse如何来实现这个应用，看看myeclipse是如何做的，生成配置文件质量如何。&nbsp;环境：开发工具：myeclipse 5.5.1 GA数 据 库：mysql-5.0.37操作系统：windows xp profess...&nbsp;&nbsp;<a href='http://www.blogjava.net/jdo/articles/133881.html'>阅读全文</a><img src ="http://www.blogjava.net/jdo/aggbug/133881.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jdo/" target="_blank">蓝色幽默</a> 2007-08-01 23:59 <a href="http://www.blogjava.net/jdo/articles/133881.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>