﻿<?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-走好脚下的路,让别人去说吧!-随笔分类-Java技术-hibernate</title><link>http://www.blogjava.net/human2008/category/28759.html</link><description /><language>zh-cn</language><lastBuildDate>Fri, 11 Jan 2008 13:22:56 GMT</lastBuildDate><pubDate>Fri, 11 Jan 2008 13:22:56 GMT</pubDate><ttl>60</ttl><item><title>Java －－ 在Eclipse上使用Hibernate </title><link>http://www.blogjava.net/human2008/archive/2008/01/11/174496.html</link><dc:creator>灵!</dc:creator><author>灵!</author><pubDate>Fri, 11 Jan 2008 01:34:00 GMT</pubDate><guid>http://www.blogjava.net/human2008/archive/2008/01/11/174496.html</guid><wfw:comment>http://www.blogjava.net/human2008/comments/174496.html</wfw:comment><comments>http://www.blogjava.net/human2008/archive/2008/01/11/174496.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/human2008/comments/commentRss/174496.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/human2008/services/trackbacks/174496.html</trackback:ping><description><![CDATA[&nbsp; 最近一个项目要用Java做，一点都不熟啊。没办法，只好硬着头皮啃了，花了大半天的时间，终于在Eclipse上完成了第一个Hibernate例子。下面记录关键的步骤，权作笔记，以备日后查看。<br />
<br />
&nbsp;（1）下载Hibernate，并向项目中导入Hibernate。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Project-&gt;Properies-&gt;Java Build Path-&gt;Libraries-&gt;Add External JARs...，选择Hibernate根目录下的hibernate3.jar，添加到项目中。<br />
&nbsp;&nbsp;&nbsp;&nbsp;接着，要将Hibernate下的lib文件夹下的所有文件都作为一个User Library添加到项目中，否则，如果仅仅添加hibernate3.jar，编译可以通过，运行却会抛出ClassNotDef的异常，因为hibernate3.jar依赖于Hibernate下的lib文件夹下的文件。<br />
<br />
&nbsp;2）我们的应用的后台数据库使用的是Oracle，所以首先要在例子项目中引入含有Oracle jdbc driver的包，classes12.jar。该jar文件位于oracle安装目录的jdbc\lib目录下。<br />
&nbsp;&nbsp;&nbsp;&nbsp;在Eclipse中，Project-&gt;Properies-&gt;Java Build Path-&gt;Libraries-&gt;Add External JARs...，选择classes12.jar，将其添加到项目中。<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
（3）生成hibernate.cfg.xml文件。<br />
&nbsp;&nbsp;&nbsp; 通常Hibernate的配置文件和.hbm.xml文件都可以自动生成，这种自动生成的工具很多，我使用的是HibernateSynchronizer，它可以作为一个插件添加到Eclipse中。当HibernateSynchronizer插件正确加载后，我们可以向当前项目中添加Hibernate配置文件：File-&gt;New-&gt;Other-&gt;Hibernate-&gt;Hibernate Configuration File，出现如下界面：<br />
<img style="width: 561px; height: 493px" height="493" alt="" src="http://www.cnblogs.com/images/cnblogs_com/zhuweisky/Hibernate01.JPG" width="561" border="0" /><br />
<br />
&nbsp; 注意，Driver Class要选择针对Oracle的oracle.jdbc.driver.OracleDriver，而且Database&nbsp;URL的格式也要正确，如：<br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><span style="color: #000000">jdbc:oracle:thin:@</span><span style="color: #000000">10.8</span><span style="color: #000000">.</span><span style="color: #000000">8.221</span><span style="color: #000000">:</span><span style="color: #000000">1521</span><span style="color: #000000">:ORCL</span></div>
<br />
<p>&nbsp;&nbsp;&nbsp;&nbsp;最好将hibernate.cfg.xml文件存放于项目的根目录下。<br />
<br />
&nbsp;4）生成.hbm.xml文件。File-&gt;New-&gt;Other-&gt;Hibernate-&gt;Hibernate Mapping File，出现如下界面：<br />
<img alt="" src="http://www.cnblogs.com/images/cnblogs_com/zhuweisky/Hibernate02.JPG" border="0" /><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp; 在填写完Password后，点击Refresh按钮，就会在Tables中列出所有可以访问的数据库表，然后选中要为其生成.hbm.xml文件的表，点击Finish，即会生成对应的.hbm.xml文件，比如我上面选择的是Mobileuser表，就会生成Mobileuser.hbm.xml文件。<br />
<br />
（5）从.hbm.xml文件自动生成实体类。<br />
&nbsp;&nbsp;&nbsp; 在Package Explorer中选中Mobileuser.hbm.xml文件，右键-&gt;Hibernate Synchronizer-&gt;Synchronize Files&nbsp;，即可生成对应的实体类和DAO类。如果你仅仅想要实体类，那么可以在Project-&gt;Properies-&gt;Hibernate Synchronizer-&gt;Data Access Objects&nbsp;，将&#8220;I would like to have DAOs created for me&#8221;的钩选项去掉即可。<br />
<br />
（6）在hibernate.cfg.xml文件中添加对应的mapping resource。<br />
&nbsp;&nbsp;&nbsp;&nbsp;在Package Explorer中选中Mobileuser.hbm.xml文件，右键-&gt;Hibernate Synchronizer-&gt;Add Mapping Reference，即会在<br />
hibernate.cfg.xml中自动生成如下配置：</p>
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><span style="color: #000000">&lt;</span><span style="color: #000000">mapping&nbsp;resource</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">HibernateTest/Mobileuser.hbm.xml</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">/&gt;</span></div>
<p>（7）修改自动生成的hibernate.cfg.xml文件。需要在hibernate.cfg.xml文件的首部添加：</p>
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><span style="color: #000000">&lt;!</span><span style="color: #000000">DOCTYPE&nbsp;hibernate</span><span style="color: #000000">-</span><span style="color: #000000">configuration&nbsp;PUBLIC<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">-//Hibernate/Hibernate&nbsp;Configuration&nbsp;DTD&nbsp;3.0//EN</span><span style="color: #000000">"</span><span style="color: #000000"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd</span><span style="color: #000000">"</span><span style="color: #000000">&gt;</span></div>
<p>&nbsp;&nbsp;&nbsp;&nbsp;比较繁琐的是，每次自动修改hibernate.cfg.xml文件后，都要重新添加这个xml片断。<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;万事具备，现在可以写个测试来检验一下了：</p>
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><span style="color: #008000">&nbsp;&nbsp;&nbsp; //</span><span style="color: #008000">仅仅作为示例，没有进行异常处理</span><span style="color: #008000"><br />
</span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;main(String[]&nbsp;args)<br />
&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Configuration&nbsp;cfg&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;Configuration().configure()&nbsp;;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SessionFactory&nbsp;&nbsp;sFactory&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;cfg.buildSessionFactory()&nbsp;;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Session&nbsp;session&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;sFactory.openSession()&nbsp;;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Transaction&nbsp;tx&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;session.beginTransaction();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Mobileuser&nbsp;user&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;(Mobileuser)session.load(Mobileuser.</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;,&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;Integer(</span><span style="color: #000000">2</span><span style="color: #000000">))&nbsp;;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;age&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;user.getMobilenumber()&nbsp;;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.</span><span style="color: #0000ff">out</span><span style="color: #000000">.println(age)&nbsp;;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tx.commit();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;session.close()&nbsp;;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}</span></div>
<img src ="http://www.blogjava.net/human2008/aggbug/174496.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/human2008/" target="_blank">灵!</a> 2008-01-11 09:34 <a href="http://www.blogjava.net/human2008/archive/2008/01/11/174496.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Hibernate 3新增XML关系持久性介绍（转） </title><link>http://www.blogjava.net/human2008/archive/2008/01/10/174227.html</link><dc:creator>灵!</dc:creator><author>灵!</author><pubDate>Thu, 10 Jan 2008 03:41:00 GMT</pubDate><guid>http://www.blogjava.net/human2008/archive/2008/01/10/174227.html</guid><wfw:comment>http://www.blogjava.net/human2008/comments/174227.html</wfw:comment><comments>http://www.blogjava.net/human2008/archive/2008/01/10/174227.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/human2008/comments/commentRss/174227.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/human2008/services/trackbacks/174227.html</trackback:ping><description><![CDATA[非常感谢最近发布的Hibernate 3中的XML持久性特性，Java开发者现在拥有了一个框架组件，它为易于实现的对象关系(OR)和XML持久性提供了高效的和一致的方法。
<p>　　Hibernate的易用性、高性能和对象关系持久性等高级特性给IT界带来了很大的惊喜。<!--newszw_hzh_begin--> Hibernate的最新版本(版本3，3月29日发布的)给产品API带来了一个重要的新特性：XML持久性。有了Hibernate 3之后，Java应用程序开发者可以轻易地把XML文档合并到关系型数据库中。</p>
<p>　　这个新特性应该明确地告诉已有的Hibernate开发者，因为它也遵循POJO(纯的旧Java对象)相同的一致性方法，需要学习的知识最少。XML持久性的优点也应该介绍给新用户。本文讲解的是Hibernate 3持久性方法。 </p>
<p><strong>　　XML持久性为什么重要</strong></p>
<p>　　大多数大型商业数据库都支持某种形式的本地XML持久性。由于XML持久性是一个相对较新的机制--即使对大型厂商也是如此，这个领域中的标准还在不断地浮现。其结果是，为了把无处不在的关系型持久性机制与日益增长的XML解决方案集成在一起，架构师必须依赖厂商特定的特性或者实现定制的XML持久性框架组件。这两个选择都没有太大的吸引力。厂商特定的特性不是普及的，因为可能产生厂商封锁(lock-in)，而定制的框架组件实现可能耗费大量的时间和财力，导致代码难于维护。</p>
<p>　　在OR(对象关系)持久性方面，Hibernate XML持久性是一个自然而然的解决方案。它可以跨越Hibernate支持的所有关系型平台(如虚拟的或真实的关系型平台)移<!-- -->动，允许自由的迁移对象、基于XML的应用程序和集成解决方案而不用担心下层的关系型实现方法。</p>
<p><strong>　　体系结构的细节信息</strong></p>
<p>　　Hibernate是一个良好架构的框架组件，它无缝地利用了本地的环境，不需要用户进行任何特殊的干涉或安装操作。从一个数据库切换到另外一个数据库通常只需要改变驱动程序，并配置Hibernate(在线配置设置信息)来使用另外一种数据库语言。</p>
<p>　　Hibernate利用dom4j框架组件进行XML的分析和维护。如果需要完全利用Hibernate的XML特性，你就必须对dom4j非常熟悉。一般来说，你会发现dom4j比Java提供的JAXP或与JAXP兼容的XML分析器要容易使用一些。它要求我们学习的相关知识较少，并且利用最少的dom4j知识你就能够高效率地使用Hibernate XML持久性。 </p>
<strong>实际例子：价格目录同步<br />
<br />
</strong>　　通用的电子商务案例可以演示XML关系持久性机制的作用。我们来考虑一个示例，在这个例子中XML集成了在线零售商和供应商之间的产品标价目录。<br />
<br />
　　该电子目录包含了已标价的产品列表。在线商店销售产品，通过自己的存货清单来管理（类似于Amazon与Toys-R-Us和运动产品商店之间的关系）。为了精确地和有效地反映价格的变化，在线零售商必须频繁地接收产品价格信息。它把这些信息存放为XML文档，如下所示：<br />
<br />
<table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#dadacf" border="1">
    <tbody>
        <tr>
            <td>＜products＞<br />
            ＜product prod_id="3" sku="100101"＞ <br />
            ＜description＞Athlete mode body fat scale＜/description＞<br />
            ＜list_price＞100.00＜/list_price＞<br />
            ＜drop_price＞60.00＜/drop_price＞<br />
            ＜/product＞ <br />
            ＜product prod_id="4" sku="100102"＞<br />
            ＜description＞Thermometer＜/description＞<br />
            ＜list_price＞20.00＜/list_price＞<br />
            ＜drop_price＞11.00＜/drop_price＞<br />
            ＜/product＞<br />
            ＜/products＞</td>
        </tr>
    </tbody>
</table>
<br />
　　全面的主要的产品价格列表存储在数据库中，如下所示：<br />
<br />
<table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#dadacf" border="1">
    <tbody>
        <tr>
            <td>CREATE TABLE PRODUCT<br />
            (<br />
            id INT UNIQUE NOT NULL,<br />
            description VARCHAR(45) NOT NULL,<br />
            sku VARCHAR(45) UNIQUE NOT NULL,<br />
            list_price FLOAT,<br />
            base_price FLOAT,<br />
            order_price FLOAT,<br />
            CONSTRAINT PK_PRODUCT PRIMARY KEY (id )<br />
            )</td>
        </tr>
    </tbody>
</table>
<br />
　　在线零售商通过已有的OR映射提供定价目录的Web表现形式，定价产品都表现为demo.Product Java对象：<br />
<br />
<table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#dadacf" border="1">
    <tbody>
        <tr>
            <td>/** Product对象表现了定价目录项*/<br />
            public class Product {<br />
            int id;<br />
            String sku;<br />
            String description;<br />
            Double listPrice;<br />
            Double basePrice;<br />
            Double orderPrice;</td>
        </tr>
    </tbody>
</table>
<br />
　　这些对象按照下面的方式映射（为了清楚，我们列出了列名，尽管在属性和列名相匹配的时候Hibernate可以自动地把属性映射为列名）：<br />
<br />
<table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#dadacf" border="1">
    <tbody>
        <tr>
            <td>＜?xml version="1.0"?＞<br />
            ＜!DOCTYPE hibernate-mapping PUBLIC<br />
            "-//Hibernate/Hibernate Mapping DTD 3.0//EN"<br />
            "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"＞<br />
            ＜hibernate-mapping package="demo"＞<br />
            ＜class name="Product" <br />
            table="product"<br />
            node="product"＞<br />
            ＜id name="id" <br />
            type="int"<br />
            node="@prod_id"<br />
            column="id"＞<br />
            ＜/id＞<br />
            ＜property name="sku" node="@sku" column="sku" not-null="true"/＞<br />
            ＜property name="description" node="description" column="description" not-null="true"/＞ <br />
            ＜property name="listPrice" node="list_price" column="list_price" /＞<br />
            ＜property name="basePrice" node="drop_price" column="base_price"/＞<br />
            ＜property name="orderPrice" column="order_price"/＞<br />
            ＜/class＞<br />
            ＜/hibernate-mapping＞</td>
        </tr>
    </tbody>
</table>
<br />
　　在这种情况下，Hibernate的XML关系持久性就非常方便了。由于该电子商务应用程序接收了包含产品价格更新的XML，它就利用Hibernate的XML持久性机制把这些XML写入到产品数据库中。Hibernate提供了几种XML持久性选择，包括Hibernate的saveOrUpdate方法：<br />
<br />
<table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#dadacf" border="1">
    <tbody>
        <tr>
            <td>document = saxReader.read(inputXML);<br />
            List users = document.selectNodes("//product");<br />
            try {<br />
            　Session session = ibernateUtil.sessionFactory.openSession();<br />
            　Transaction transaction = session.beginTransaction();<br />
            　Session dom4jSession = session.openSession(EntityMode.DOM4J);<br />
            　Iterator iter = users.iterator();<br />
            　while (iter.hasNext()) {<br />
            　　Object next = iter.next();<br />
            　　dom4jSession.saveOrUpdate("demo.Product", next );<br />
            　}// end while<br />
            transaction.commit();<br />
            session.close();　</td>
        </tr>
    </tbody>
</table>
<br />
　　<strong>XML映射语法</strong><br />
<br />
　　上面的例子中使用的映射文件不用于Hibernate 2的映射文件。Hibernate 3引入了几种专门用于XML持久性的新映射类型。<br />
<br />
　　主要的新映射属性是节点（node），它与被映射的XML文档中的一个元素或文档中的属性相关联。<br />
<br />
　　一个"节点"可能表现为下面的某种映射：<br />
<br />
　　&#183; "element-name（元素名）"：在例子中，＜product＞＜/product＞元素会被表示为node="product"。<br />
<br />
　　&#183; "@attribute-name（属性名）"：在例子中，node="@sku"会被映射为XML属性＜product sku="1001001"＞。<br />
<br />
　　&#183; ".（句点）"：映射为元素的父元素（例如＜products＞就＜product＞是的父元素）。<br />
<br />
　　&#183; "element-name/@attribute-name（元素名/属性名）"：映射为命名元素的属性（product/@sku）。<br />
<br />
　　<strong>XML持久性并非Hibernate的主要任务</strong><br />
<br />
　　Hibernate 3框架组件高效率地实现了目前最通用的一些方法（除了LDAP之外）。Java社团现在拥有了一套框架组件，它为易于实现的OR和XML持久性提供了高效率的和一致性的方法。<br />
<br />
　　在我们知道上面一些内容之后，了解Hibernate项目的任务是很重要的。尽管Hibernate 3的XML特性非常有用、有吸引力，但是它们并不是用来代替最流行的XML编组（marshalling）和转换（transformation）框架组件的。不管它的OR映射解决方案多么完善，我们都不应该期待Hibernate成为主流的XML维护框架组件（根据Hibernate的作者Gavin King在TheServerSide Java Symposium 2005上的发言）。<br />
<br />
　　由于这个原因，你应该把XML持久性特性看作是已有的强大的Hibernate框架组件的有用的扩展，它允许你轻易地把现在流行的其它的数据表现机制合并到自己的应用程序中。但是，如果你必须处理复杂的集成和转换情况，最好去寻找其它的XML专用的框架组件。<!--newszw_hzh_end--> 
<img src ="http://www.blogjava.net/human2008/aggbug/174227.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/human2008/" target="_blank">灵!</a> 2008-01-10 11:41 <a href="http://www.blogjava.net/human2008/archive/2008/01/10/174227.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>hibernate入门 </title><link>http://www.blogjava.net/human2008/archive/2008/01/10/174226.html</link><dc:creator>灵!</dc:creator><author>灵!</author><pubDate>Thu, 10 Jan 2008 03:40:00 GMT</pubDate><guid>http://www.blogjava.net/human2008/archive/2008/01/10/174226.html</guid><wfw:comment>http://www.blogjava.net/human2008/comments/174226.html</wfw:comment><comments>http://www.blogjava.net/human2008/archive/2008/01/10/174226.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/human2008/comments/commentRss/174226.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/human2008/services/trackbacks/174226.html</trackback:ping><description><![CDATA[<span style="color: #800080">一、首先学习hibernate.cfg.xml配置文件的具体配置<br />
&lt;?xml version="1.0" encoding="UTF-8"?&gt;</span><br />
<span style="color: #993300">&lt;!--指定该文件的官方dtd--&gt;</span><br />
<span style="color: #0000ff">&lt;!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "</span><a href="http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"><span style="color: #0000ff"><u>http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd</u></span></a><span style="color: #0000ff">" &gt;<br />
</span><span style="color: #800080">&lt;hibernate-configuration&gt;<br />
&nbsp; &lt;session-factory&gt;<br />
&nbsp;&nbsp;&nbsp; <span style="color: #993300">&lt;!-- 显示sql语言 --&gt;</span><br />
&nbsp;&nbsp;&nbsp; &lt;property name="show_sql"&gt;true&lt;/property&gt;<br />
&nbsp;&nbsp;&nbsp; <span style="color: #993300">&lt;!-- sql语言 --&gt;</span><br />
&nbsp;&nbsp;&nbsp; &lt;property name="dialect"&gt;org.hibernate.dialect.MySQLDialect&lt;/property&gt;<br />
&nbsp;&nbsp;&nbsp; <span style="color: #993300">&lt;!-- jdbc驱动程式 --&gt;</span><br />
&nbsp;&nbsp;&nbsp; &lt;property name="connection.driver_class"&gt;com.mysql.jdbc.Driver&lt;/property&gt;<br />
&nbsp;&nbsp;&nbsp; <span style="color: #993300">&lt;!-- jdbc url --&gt;<br />
</span>&nbsp;&nbsp;&nbsp; &lt;property name="connection.url"&gt;jdbc:mysql://localhost:3306/test&lt;/property&gt;<br />
&nbsp;&nbsp;&nbsp; <span style="color: #993300">&lt;!-- 数据库用户名 --&gt;<br />
</span>&nbsp;&nbsp;&nbsp; &lt;property name="connection.username"&gt;root&lt;/property&gt;<br />
&nbsp;&nbsp;&nbsp; <span style="color: #993300">&lt;!-- 数据库密码 --&gt;<br />
</span>&nbsp;&nbsp;&nbsp; &lt;property name="connection.password"&gt;wyq&lt;/property&gt;<br />
&nbsp;&nbsp;&nbsp; <span style="color: #993300">&lt;!-- C3P0连接池设定 --&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;!--最小连接数--&gt;<br />
</span>&nbsp;&nbsp;&nbsp; &lt;property name="c3p0.min_size"&gt;5&lt;/property&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<font color="#993300">&lt;!--最大连接数--&gt;</font><br />
&nbsp;&nbsp;&nbsp; &lt;property name="c3p0.max_size"&gt;20&lt;/property&gt;<br />
<font color="#993300">&nbsp;&nbsp;&nbsp;&lt;!--延迟所允许的时间--&gt;</font><br />
&nbsp;&nbsp;&nbsp; &lt;property name="c3p0.timeout"&gt;1800&lt;/property&gt;<br />
&nbsp;&nbsp;&nbsp;<font color="#993300">&lt;!--缓存所允许的最大连接数--&gt;</font><br />
&nbsp;&nbsp;&nbsp; &lt;property name="c3p0.max_statements"&gt;50&lt;/property&gt;<br />
&nbsp;&nbsp;&nbsp; <span style="color: #993300">&lt;!-- 每隔100笔资料送入资料库，清除缓存（定期清除缓存，减小压力） --&gt;</span><br />
&nbsp;&nbsp;&nbsp; &lt;property name="hibernate.jdbc.batch_size"&gt;100&lt;/property&gt;<br />
&nbsp;&nbsp;&nbsp; <span style="color: #993300">&lt;!-- 设定事务管理的工厂类 --&gt;</span><br />
&nbsp;&nbsp;&nbsp; &lt;property name="hibernate.transaction.factiory_class"&gt;org.hibernate.transaction.JDBCTransactionFactory&lt;/property&gt;<br />
&nbsp; &nbsp;&lt;mapping resource="com/wyq/hibernate/pojo/User.hbm.xml"/&gt;<br />
&nbsp; &nbsp;&lt;mapping resource="com/wyq/hibernate/pojo/TUser.hbm.xml"/&gt;<br />
&nbsp; &nbsp;&lt;mapping resource="com/wyq/hibernate/pojo/Room.hbm.xml"/&gt;<br />
&nbsp; &lt;/session-factory&gt;<br />
&lt;/hibernate-configuration&gt;<br />
需要的jar包有c3p0.jar,hibernate3.jar,数据库.jar,log4j.jar</span> <br />
<br />
------------------------------------------------------------------------------------------------------------------------<br />
<div class="postTitle"><a class="postTitle2" id="viewpost1_TitleUrl" href="http://www.cnblogs.com/wyqtomorrow/archive/2007/05/11/743215.html"><font color="#6faf30">hibernate学习笔记(二)------------使用criteria进行查询</font></a> </div>
<br />
<span style="color: #800080">1、读取配置文件获得连接<br />
</span>&nbsp;&nbsp;&nbsp;<span style="color: #993300">读取hibernate.cfg.xml配置文件，hibernate.cfg.xml文件放在Classpath下，使用下面的方式读入该文件</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #339966">//Configuration 负责管理hibernate配置信息</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Configuration config=new Configuration().configure();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #339966">//根据config建立SessionFactory<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//SessionFactory用于建立Session<br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SessionFactory sessionFactory=config.buildSessionFactory();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #339966">//开启session,相当于jdbc的Connection<br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;session = sessionFactory.openSession();<br />
<br />
<span style="color: #800080">2、Criteria 基本资料查询<br />
(1)标准查询:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #339966">//创建查询标准<br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Criteria criteria=session.creteCriteria(User.class);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #339966">//查询条件<br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;criteria.add(Expression.eq("name","caterpillar"));<br />
<span style="color: #339966">************************************************************************************<br />
</span><span style="color: #3366ff">Expression.eq(String s1,String s2)----------&gt;相等s1=s2<br />
Expression.allEq(Map map)&nbsp;&nbsp;&nbsp; ---------------&gt;多个属性-值对应关系，多个Expression.eq叠加<br />
Expression.gt(String s1,String s2)-----------&gt;大于s1&gt;s2<br />
Expression.ge(String s1,String s2)-----------&gt;大于等于s1&gt;=s2<br />
Expression.lt(String s1,String s2)------------&gt;小于s1&lt;s2<br />
Expression.le(String s1,String s2)------------&gt;小于等于s1&lt;=s2<br />
Expression.between(String s1,int s2,int s3)---&gt;s2&lt;s1&lt;s3<br />
Expression.like(String s1,String s2)------------&gt;s1 like s2<br />
比较2个属性<br />
Expression.eqProperty(String s1,String s2)---&gt;s1=s2<br />
Expression.gtProperty(String s1,String s2)----&gt;s1&gt;s2<br />
Expression.geProperty(String s1,String s2)----&gt;s1&gt;=s2<br />
Expression.ltProperty(String s1,String s2)-----&gt;s1&lt;s2<br />
Expression.leProperty(String s1,String s2)-----&gt;s1&lt;=s2<br />
Expression.and()-----&gt;Expression.and(Expression.eq("String s1,String s2"),Expression.eq(String s3,String s4))<br />
Expression.or()<br />
</span><span style="color: #339966">************************************************************************************<br />
</span>(2)高级查询<br />
一、可以使用Criteria进行查询，并用order对结果进行排序。<br />
<span style="color: #3366ff">//设置从第几条开始取的记录<br />
criteria.setFirstResult(100);<br />
//最多取的几条记录<br />
criteria.setMaxResults(20);<br />
//对结果进行排序<br />
criteria.addOrder(Order.asc(String s1));<br />
criteria.addOrder(Order.desc(String s2));<br />
<br />
<span style="color: #800080">二、可以对查询结果进行统计操作，使用Projections的rowCount(),count(),max(),min</span>(),countDistinct()等方法：<br />
例如：criteria.setProjection(Projections.max("age"));<br />
<br />
<span style="color: #800080">三、还可以用Projections的groupProperty()来对结果进行分组</span><br />
例如：criteria.setProjection(Projections.groupProperty("age"));<br />
<br />
<span style="color: #800080">(***)四、结合统计与分组的功能，可以用ProjectionList</span><br />
例如：ProjectionList projectionList =Projections.projectionList();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;projectionList.add(Projections.groupProperty("age"));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;projectionList.add(Projections.rowCount());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;criteria.setProjection(projectionList);<br />
</span><span style="color: #339966">^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^<br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #339966">//查询所有记录<br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;List users=criteria.list();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Iterator iterator=users.iterator();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while(iterator.hasNext()){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;User user=(User)iterator.next();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(user.getId()+"\t"+user.getName()+"/"+user.getAge());<br />
}<br />
3、criteria的增、删、改（还不完善）<br />
在用到增、删、改时，必须先声明事务<br />
增加：<br />
&nbsp;&nbsp;<span style="color: #3366ff">Transaction tx = session.beginTransaction();//Transaction表示一组会话操作<br />
&nbsp;&nbsp;session.save(user);//将事物映射到数据库进行存储<br />
&nbsp;&nbsp;tx.commit();<br />
&nbsp;&nbsp;session.close();<br />
</span>删除：<br />
&nbsp;&nbsp;<span style="color: #3366ff">Session session=this.getSession();<br />
&nbsp;&nbsp;User user=(User)session.get(User.class, new Integer(1));<br />
&nbsp;&nbsp;Transaction tx = session.beginTransaction();//Transaction表示一组会话操作<br />
&nbsp;&nbsp;session.delete(user);//将事物映射到数据库进行存储<br />
&nbsp;&nbsp;tx.commit();<br />
&nbsp;&nbsp;session.close();</span><br />
修改：<br />
&nbsp;&nbsp;<span style="color: #3366ff">Session session=this.getSession();<br />
&nbsp;&nbsp;User user =(User)session.get(User.class,new Integer(2));//创建持久化的事物<br />
&nbsp;&nbsp;user.setName("wyqqqqqqqqqq");<br />
&nbsp;&nbsp;user.setAge(new Integer(30));<br />
&nbsp;&nbsp;Transaction tx = session.beginTransaction();//Transaction表示一组会话操作<br />
</span>&nbsp;&nbsp;<span style="color: #3366ff">session.update(user);//将事物映射到数据库进行存储<br />
&nbsp;&nbsp;tx.commit();<br />
&nbsp;&nbsp;session.close();<br />
</span></span>----------------------------------------------------------------------------------------------------------------------<br />
<div class="postTitle"><a class="postTitle2" id="viewpost1_TitleUrl" href="http://www.cnblogs.com/wyqtomorrow/archive/2007/05/14/745487.html"><font color="#6faf30">hibernate学习笔记(三)----------使用Query进行查询</font></a> </div>
<span style="color: #993300">一、Query查询可以先设定查询参数，之后通过set等方法，将指定的参数值添入．</span><span style="color: #3366ff">还可以使用命名参数<br />
</span><span style="color: #800080">Session session = sessionFactory.openSession();<br />
Query query = session.createQuery("select user.name from User as user where user.age&gt;?(</span> <span style="color: #3366ff">:minAge</span> <span style="color: #800080">)");<br />
</span><span style="color: #800080">query.setInteger(0,25);<br />
<span style="color: #3366ff">query.setInteger("minAge",25);</span><br />
</span><span style="color: #800080">List names=query.list();<br />
Iterator iterator = names.iterator();<br />
while(iterator.hasNext()){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(iterator.next());<br />
}<br />
session.close();<br />
<br />
<span style="color: #993300">二、如果查询整个表直接使用from User如果针对某个属性使用<strong><font style="color: #993300" color="#000000" size="2">select user.name from User as user<br />
使用hql可以更接近我们平时的jdbc编程，和把sql语句写在程序中差不多，另外，也可以将sql语句写在配置文件中。</font></strong></span></span> <br />
<br />
<br />
--------------------------------------------------------------------------------------------------------------------------<br />
<font color="#6faf30">&nbsp;&nbsp; 多表关联</font> <br />
<span style="color: #993300">一、多对一进行关联(多个学生对应同一间宿舍)---学生是主体，宿舍是附体，关联关系&lt;many-to-one&gt;在主体学生中设置，在学生类中设置宿舍类，由于宿舍类只有一个可以直接用类来设置,在映射学生类(User)中包含宿舍这个类(Room),在映射配置文件(User.hbm.xml)中定义<br />
<br />
<span style="color: #008080">&lt;many-to-one name="room" column="room_id" cascade="save-update" class="com.wyq.hibernate2.Room"&gt;&lt;/many-to-one&gt;<br />
<br />
</span>哪个是主体类就在哪个配置文件定义关联关系．<br />
<br />
<span style="color: #800080">cascade属性：表示关联对象的持久化，该属性也要设置在主体中，作用就是当主控方执行操作时，关联对象(被动方)是否同步执行同一操作．<br />
cascade的值：all:表示所有情况下都进行级联操作．<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;none:所有情况下都不进行级联操作<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;save-update:在执行save-update时进行级联操作．<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delete:在执行delete时进行级联操作．</span><br />
注意：使用cascade自動持久化時，會先檢查被關聯物件的id屬性，未被持久化的物件之id屬性是由unsaved-value決定，預設是null，如果您使用long這樣的原生型態（primitive type）時，則必須自行指定預設值．<br />
<br />
<span style="color: #008080">例如：&lt;id name="id" column="ROOM_ID" unsaved-value="0"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;generator class="increment"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/id&gt;<br />
</span><br />
如果您不想額外設定unsaved-value資訊，則可以將long改為Long，這可以符合預設的unsaved-value為null的設定&nbsp;．<br />
<br />
二、一对多进行关联(一间宿舍对应多个学生)---宿舍是主体，学生是附体，关联关系&lt;one-to-many&gt;在主体宿舍中设置,由于要在宿舍类中设置学生类，一个宿舍包含多个学生，所以在宿舍类中要用Set类来进行设置，用set类(private Set users = new HashSet();)来存储多个学生类，在映射宿舍类(Room)中要包含&lt;set&gt;这个节点，用来与user相关联<br />
<br />
<span style="color: #008080">例如：&lt;set name="users" table="USER"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;key column="ROOM_ID"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;one-to-many class="onlyfun.caterpillar.User"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/set&gt;<br />
</span><br />
<span style="color: #800080">name:表示属性，table:表示关联的表名，key:表示通过什么字段进行关联，&lt;one-to-many&gt;:表示关联类。这里也可以使用cascade属性。<br />
</span><br />
三、在表关联的设计中，不论是一对多还是多对一，都要将关联字段设置在多的那一方。<br />
例如：user表格和room表格，要将关联字段room_id设置在user表格中。<br />
<br />
四、一对一进行关联(一个人只有一个房间，一个房间也只有一个人)。<br />
可以通过２中方式进行关联：<br />
<br />
(1)、通过外键进行关联：在多对一的例子中就是通过外键进行关联的.<br />
在user-room的设置中(user.hbm.xml):<br />
<span style="color: #008080">&lt;many-to-one name="room"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; column="ROOM_ID"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class="onlyfun.caterpillar.Room" <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cascade="all"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unique="true"/&gt;</span> <br />
其中unique表示限制一個User有一獨有的 Room，这只是单向的，说明一个user只有一个room.<br />
在room-user的设置中(room.hbm.xml):<br />
&lt;one-to-one name="user"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class="onlyfun.caterpillar.User"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; property-ref="room"/&gt;<br />
这样就完成了双向的一对一关联，property-ref告诉hibernate,查询出user并将其参考至room。<br />
(2)、通过主键进行关联：限制兩個資料表的主鍵使用相同的值，如此一個User與Room就是一對一關係<br />
<span style="color: #008080">user.hbm.xml:<br />
&lt;one-to-one name="room"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class="onlyfun.caterpillar.Room"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cascade="all"/&gt; <br />
room.hbm.xml:<br />
&lt;one-to-one name="user"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class="onlyfun.caterpillar.User"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; constrained="true"/&gt;</span><br />
使用constrained="true"告訴Hibernate參考至User的主鍵<br />
<br />
五、双向关联，就是将一和二结合起来，<font color="#000000"><span style="color: #993300">如果將關聯的維護交給User的話會比較容易，因為每個User都對應至一個Room，在儲存時並用像Room一樣必須對Set中的每個物件作檢查，為了將關聯的維護交給User，我們可以在Room.hbm.xml中的&lt;set&gt;修改，加上inverse="true"，表示將關聯的維護「反過來」交給User作</span></font><font style="color: #993300"><br />
<br />
&nbsp;<span style="color: #008080">例如：&lt;set name="users" table="users" iinverse="true" cascade="all"&gt;<br />
</span></font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #008080">&lt;key&nbsp; column="room_id"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;one-to-many class="onlyfun.caterpillar.User"/&gt;<br />
<br />
<font color="#993300">在設立雙向關聯時，關聯由多對一中「多」的哪一方維護，會比由「一」的哪一方維護來的方便，在Hibernate可以藉由inverse來設定，不設定inverse基本上也可以運行，但是效能會較差。</font><br />
</span></span><br />
<br />
------------------------------------------------------------------------------------------------------------------------<br />
<div class="postTitle"><a class="postTitle2" id="viewpost1_TitleUrl" href="http://www.cnblogs.com/wyqtomorrow/archive/2007/05/21/754039.html"><font color="#6faf30">hibernate学习笔记(五)-----延遲初始 Lazy Initialization </font></a></div>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #993300">在Hibernate中，集合類的映射可以延遲初始（Lazy Initialization），在多对一或者一对多中，都可以使用延遲初始，例如：一个用户(user对应user表)有多个email地址(address对应address表)，也就是在真正索取該物件的資料時，才向資料庫查詢，就上次例子來說，就是我們在讀取User時，先不取得其中的 addrs屬性中之物件資料，由於只需要讀取User的name屬性，此時我們只要執行一次select即可，真正需要addrs的資料時，才向資料庫要求。在含有集合类的user.hbm.xml中要如下设置：<br />
</span><br />
　　<span style="color: #008080">&lt;set name="addrs" table="ADDRS" lazy="true"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;key column="USER_ID"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;element type="string" column="ADDRESS" not-null="true"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/set&gt;</span> <br />
--------------------------------------------------------------------------------------------------------------------------<br />
<div class="postTitle"><a class="postTitle2" id="viewpost1_TitleUrl" href="http://www.cnblogs.com/wyqtomorrow/archive/2007/05/21/754207.html"><font color="#6faf30">hibernate学习笔记(六)-----session的管理</font></a> </div>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #993300">session是hibernate运做的核心，是有SessionFactory所创建，sessionFactory是线程安全的，你可以让多个线程同时存取SessionFactory,而不会有资源共用的问题，然而session不是设计为线程安全的，所以让多个线程共用一个session，将发生资料共用而发生混乱的问题．下面是一个标准类．</span><br />
<br />
<span style="color: #008000">
<pre class="code-java" style="color: #800080"><span class="code-keyword">import</span> java.io.Serializable;
<span class="code-keyword">import</span> net.sf.hibernate.HibernateException;
<span class="code-keyword">import</span> net.sf.hibernate.Session;
<span class="code-keyword">import</span> net.sf.hibernate.SessionFactory;
<span class="code-keyword">import</span> net.sf.hibernate.Transaction;
<span class="code-keyword">public</span> class HibernateSessionUtil <span class="code-keyword">implements</span> Serializable
{</pre>
<pre class="code-java" style="color: #800080">&nbsp;&nbsp;&nbsp;　&nbsp;<span style="color: #008000">//创建线程局部变量　tLocalsess</span> </pre>
<pre class="code-java" style="color: #800080">    <span class="code-keyword">public</span> <span class="code-keyword">static</span> <span class="code-keyword">final</span> ThreadLocal tLocalsess = <span class="code-keyword">new</span> ThreadLocal();</pre>
<pre class="code-java" style="color: #800080">　　　<span style="color: #008000">//创建线程局部变量　tLocaltx</span>
<span class="code-keyword">public</span> <span class="code-keyword">static</span> <span class="code-keyword">final</span> ThreadLocal tLocaltx = <span class="code-keyword">new</span> ThreadLocal();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000">//取得session</span></pre>
<pre class="code-java" style="color: #800080">    <span class="code-keyword">public</span> <span class="code-keyword">static</span> Session currentSession(){</pre>
<pre class="code-java" style="color: #800080">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000">//从线程变量tLocalsess中，取得当前session</span>
Session session = (Session) tLocalsess.get();
<span style="color: #008000">//判断session是否为空，如果为空，将创建一个session,并付给线程变量tLocalsess</span></pre>
<pre class="code-java" style="color: #800080"><span class="code-keyword">&nbsp;&nbsp;&nbsp;&nbsp;try</span>{
<span class="code-keyword">if</span> (session == <span class="code-keyword">null</span>){
session = openSession();
tLocalsess.set(session);
}
}<span class="code-keyword">catch</span> (HibernateException e){
<span class="code-keyword">throw</span> <span class="code-keyword">new</span> InfrastructureException(e);
}
<span class="code-keyword">return</span> session;
}
<span style="color: #008000">//关闭当前session</span></pre>
<pre class="code-java" style="color: #800080">    <span class="code-keyword">public</span> <span class="code-keyword">static</span> void closeSession(){
</pre>
<pre class="code-java" style="color: #800080">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000">//从线程变量tLocalsess中，取得当前session</span>
Session session = (Session) tLocalsess.get();</pre>
<pre class="code-java" style="color: #800080">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000">//设置线程变量tLocalsess为空</span>
tLocalsess.set(<span class="code-keyword">null</span>);
<span class="code-keyword">try</span>{</pre>
<pre class="code-java" style="color: #800080">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000">//关闭session</span>
<span class="code-keyword">if</span> (session != <span class="code-keyword">null</span> &amp;&amp; session.isOpen()){
session.close();
}
}<span class="code-keyword">catch</span> (HibernateException e){
<span class="code-keyword">throw</span> <span class="code-keyword">new</span> InfrastructureException(e);
}
}
<span style="color: #008000">//事物处理</span></pre>
<pre class="code-java" style="color: #800080">    <span class="code-keyword">public</span> <span class="code-keyword">static</span> void beginTransaction(){</pre>
<pre class="code-java" style="color: #800080">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000">//从线程变量tLocaltx中取得事物管理对象Transaction</span></pre>
<pre class="code-java" style="color: #800080">        Transaction tx = (Transaction) tLocaltx.get();
<span class="code-keyword">try</span>{</pre>
<pre class="code-java" style="color: #800080">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000">//如果为空就从session中创建一个tx</span>
<span class="code-keyword">if</span> (tx == <span class="code-keyword">null</span>){
tx = currentSession().beginTransaction();
tLocaltx.set(tx);
}
}<span class="code-keyword">catch</span> (HibernateException e){
<span class="code-keyword">throw</span> <span class="code-keyword">new</span> InfrastructureException(e);
}
}
<span style="color: #008000">//提交事物</span></pre>
<pre class="code-java" style="color: #800080">    <span class="code-keyword">public</span> <span class="code-keyword">static</span> void commitTransaction(){</pre>
<pre class="code-java" style="color: #800080">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000">//取得事物</span>
Transaction tx = (Transaction) tLocaltx.get();
<span class="code-keyword">try</span>{</pre>
<pre class="code-java" style="color: #800080">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000">//如果不为空就提交</span>
<span class="code-keyword">if</span> (tx != <span class="code-keyword">null</span> &amp;&amp; !tx.wasCommitted() &amp;&amp; !tx.wasRolledBack())
tx.commit();
tLocaltx.set(<span class="code-keyword">null</span>);
}<span class="code-keyword">catch</span> (HibernateException e){
<span class="code-keyword">throw</span> <span class="code-keyword">new</span> InfrastructureException(e);
}
}
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000">//事物回滚</span>    </pre>
<pre class="code-java" style="color: #800080">    <span class="code-keyword">public</span> <span class="code-keyword">static</span> void rollbackTransaction(){</pre>
<pre class="code-java" style="color: #800080">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000">//取得tx事物</span>
Transaction tx = (Transaction) tLocaltx.get();
<span class="code-keyword">try</span>{</pre>
<pre class="code-java" style="color: #800080">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000">//将变量清空</span>
tLocaltx.set(<span class="code-keyword">null</span>);
<span class="code-keyword">if</span> (tx != <span class="code-keyword">null</span> &amp;&amp; !tx.wasCommitted() &amp;&amp; !tx.wasRolledBack()){</pre>
<pre class="code-java" style="color: #800080">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000">//事物回滚</span>
tx.rollback();
}
}<span class="code-keyword">catch</span> (HibernateException e){
<span class="code-keyword">throw</span> <span class="code-keyword">new</span> InfrastructureException(e);
}
}
</pre>
<pre class="code-java" style="color: #800080">&nbsp;&nbsp;&nbsp;<span style="color: #008000">//取得session</span>
<span class="code-keyword">private</span> <span class="code-keyword">static</span> Session openSession() <span class="code-keyword">throws</span> HibernateException{
<span class="code-keyword">return</span> getSessionFactory().openSession();
}
</pre>
<pre class="code-java" style="color: #800080">&nbsp;&nbsp;&nbsp;<span style="color: #008000">//取得sessionFactory</span>
<span class="code-keyword">private</span> <span class="code-keyword">static</span> SessionFactory getSessionFactory() <span class="code-keyword">throws</span> HibernateException{
<span class="code-keyword">return</span> SingletonSessionFactory.getInstance();
}
}</pre>
<pre class="code-java" style="color: #800080">filter的代码：</pre>
<pre class="code-java" style="color: #800080"><span class="code-keyword">public</span> class HibernateSessionCloser <span class="code-keyword">implements</span> Filter{
<span class="code-keyword">protected</span> FilterConfig filterConfig = <span class="code-keyword">null</span>;
<span class="code-keyword">public</span> void init(FilterConfig filterConfig)<span class="code-keyword">throws</span> ServletException{
<span class="code-keyword">this</span>.filterConfig = filterConfig;
}
<span class="code-keyword">public</span> void destroy(){
<span class="code-keyword">this</span>.filterConfig = <span class="code-keyword">null</span>;
}
<span class="code-keyword">public</span> void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain)
<span class="code-keyword">throws</span> IOException, ServletException {
<span class="code-keyword">try</span>{
chain.doFilter(request, response);
}
<span class="code-keyword">finally</span>{
<span class="code-keyword">try</span>{
HibernateSessionUtil.commitTransaction();
}<span class="code-keyword">catch</span> (InfrastructureException e){
HibernateSessionUtil.rollbackTransaction();
}<span class="code-keyword">finally</span>{
HibernateSessionUtil.closeSession();
}
}
}
}</pre>
<pre class="code-java" style="color: #800080">---------------------------------------------------------------------------------------</pre>
<pre class="code-java" style="color: #800080">
<div class="postTitle"><a class="postTitle2" id="viewpost1_TitleUrl" href="http://www.cnblogs.com/wyqtomorrow/archive/2007/05/21/754269.html"><font color="#6faf30">hibernate学习笔记(七)-----悲观锁和乐观锁</font></a> </div>
<font size="2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #993300">&nbsp;(1)、悲觀鎖定（Pessimistic Locking）一如其名稱所示，悲觀的認定每次資料存取時，其它的客戶端也會存取同一筆資料，因此對該筆資料進行鎖定，直到自己操作完成後解除鎖定。&nbsp;</span></font><br />
<br />
<font size="2"><span style="color: #993300">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;悲觀鎖定通常透過系統或資料庫本身的功能來實現，依賴系統或資料庫本身提供的鎖定機制，Hibernate即是如此，可以利用Query或 Criteria的setLockMode()方法來設定要鎖定的表或列（Row）及其鎖定模式，可設定的鎖定模式有以下的幾個：<br />
</span>
<li><span style="color: #993300">LockMode.WRITE：在insert或update時進行鎖定，Hibernate會在save()方法時自動獲得鎖定。 </span>
<li><span style="color: #993300">LockMode.UPGRADE：利用SELECT ... FOR UPDATE進行鎖定。 </span>
<li><span style="color: #993300">LockMode.UPGRADE_NOWAIT：利用SELECT ... FOR UPDATE NOWAIT進行鎖定，在Oracle環境下使用。 </span>
<li><span style="color: #993300">LockMode.READ：在讀取記錄時Hibernate會自動獲得鎖定。 </span>
<li><span style="color: #993300">LockMode.NONE：沒有鎖定。</span>
<p style="color: #993300">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(2)、樂觀鎖定（Optimistic locking）則樂觀的認為資料的存取很少發生同時存取的問題，因而不作資料庫層次上的鎖定，為了維護正確的資料，樂觀鎖定使用應用程式上的邏輯實現版本控制的解決。&nbsp;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;在不實行悲觀鎖定策略的情況下，資料不一致的情況一但發生，有幾個解決的方法，一種是先更新為主，一種是後更新的為主，比較複雜的就是檢查發生變動的資料來實現，或是檢查所有屬性來實現樂觀鎖定。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;要注意的是，由於樂觀鎖定是使用系統中的程式來控制，而不是使用資料庫中的鎖定機制，因而如果有人特意自行更新版本訊息來越過檢查，則鎖定機制就會無效，例如在上例中自行更改userV2的version屬性，使之與資料庫中的版本號相同的話就不會有錯誤，像這樣版本號被更改，或是由於資料是由外部系統而來，因而版本資訊不受控制時，鎖定機制將會有問題，設計時必須注意。</p>
</font></span></li>
</pre>
<img src ="http://www.blogjava.net/human2008/aggbug/174226.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/human2008/" target="_blank">灵!</a> 2008-01-10 11:40 <a href="http://www.blogjava.net/human2008/archive/2008/01/10/174226.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>持久层的组成(转) </title><link>http://www.blogjava.net/human2008/archive/2008/01/10/174225.html</link><dc:creator>灵!</dc:creator><author>灵!</author><pubDate>Thu, 10 Jan 2008 03:39:00 GMT</pubDate><guid>http://www.blogjava.net/human2008/archive/2008/01/10/174225.html</guid><wfw:comment>http://www.blogjava.net/human2008/comments/174225.html</wfw:comment><comments>http://www.blogjava.net/human2008/archive/2008/01/10/174225.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/human2008/comments/commentRss/174225.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/human2008/services/trackbacks/174225.html</trackback:ping><description><![CDATA[<strong>持久层的组成<br />
</strong>&nbsp;&nbsp;&nbsp;&nbsp;这一节的名字应该换成&#8220;基于Hibernate的持久层的组成&#8221;更合适一点，可是它太长了。既然Hibernate是用来开发持久层，那么我先介绍一下这个持久层中的各个元素。<br />
1.&nbsp;&nbsp;&nbsp;&nbsp;POJO：Plain&nbsp;Old&nbsp;Java&nbsp;Object，你可以把它看作是简单的JavaBean。一般说来，一张数据库表对应一个POJO，也就是对象/关系的一一映射。<br />
2.&nbsp;&nbsp;&nbsp;&nbsp;DAO：对于每一个POJO，一般都有一个DAO与之对应，承担所有关于该POJO的访问控制。实际上也就是控制了对数据库中一张表的访问控制。<br />
3.&nbsp;&nbsp;&nbsp;&nbsp;*.hbm.xml文件：这个文件定义了POJO和数据库中的表是如何映射的，比如POJO中的字段对应数据库表中的哪个字段等等。一般每个映射都用单独的文件来描述，也就是有一个POJO就有一个*.hbm.xml文件。<br />
4.&nbsp;&nbsp;&nbsp;&nbsp;*.cfg.xml文件：这个文件定义了Hibernate的基本信息，比如数据库驱动，用户名，密码等等连接信息，也包括了所有要用的*.hbm.xml文件，在初始化的时候，Hibernate会读取这个文件来找相应的映射文件完成对象/关系。<br />
我们还是以上文的例子来详细描述一下这里提到的各个元素的内容。<br />
1.&nbsp;&nbsp;&nbsp;&nbsp;Student.java：<br />
代码片段4：<br />
<div class="codeStyle">
<ol>
    <li>
    <li><strong><font color="#0000ff">public</font></strong>&nbsp;<strong><font color="#0000ff">class</font></strong>&nbsp;Student&nbsp;&nbsp;<strong><font color="#0000ff">implements</font></strong>&nbsp;java.io.<strong><a href="http://www.javaresearch.org/source/jdk142/java/io/Serializable.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>Serializable</u></font></a></strong>&nbsp;
    <li>{
    <li>&nbsp;&nbsp;&nbsp;&nbsp;<strong><font color="#0000ff">private</font></strong>&nbsp;<strong><a href="http://www.javaresearch.org/source/jdk142/java/lang/String.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>String</u></font></a></strong>&nbsp;id;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;<strong><font color="#0000ff">private</font></strong>&nbsp;<strong><a href="http://www.javaresearch.org/source/jdk142/java/lang/String.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>String</u></font></a></strong>&nbsp;name;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;<strong><font color="#0000ff">private</font></strong>&nbsp;<font color="#ff0000">Set</font>&nbsp;courseSelections&nbsp;=&nbsp;<strong><font color="#0000ff">new</font></strong>&nbsp;<font color="#ff0000">HashSet</font>(0);
    <li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;<strong><font color="#0000ff">public</font></strong>&nbsp;Student()&nbsp;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;{
    <li>&nbsp;&nbsp;&nbsp;&nbsp;}
    <li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;<strong><font color="#0000ff">public</font></strong>&nbsp;<strong><a href="http://www.javaresearch.org/source/jdk142/java/lang/String.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>String</u></font></a></strong>&nbsp;getId()&nbsp;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;{
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong><font color="#0000ff">return</font></strong>&nbsp;<strong><font color="#0000ff">this</font></strong>.id;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;}
    <li>&nbsp;&nbsp;&nbsp;&nbsp;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;<strong><font color="#0000ff">public</font></strong>&nbsp;<strong><font color="#0000ff">void</font></strong>&nbsp;setId(<strong><a href="http://www.javaresearch.org/source/jdk142/java/lang/String.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>String</u></font></a></strong>&nbsp;id)&nbsp;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;{
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong><font color="#0000ff">this</font></strong>.id&nbsp;=&nbsp;id;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;}
    <li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;<strong><font color="#0000ff">public</font></strong>&nbsp;<strong><a href="http://www.javaresearch.org/source/jdk142/java/lang/String.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>String</u></font></a></strong>&nbsp;getName()&nbsp;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;{
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong><font color="#0000ff">return</font></strong>&nbsp;<strong><font color="#0000ff">this</font></strong>.name;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;}
    <li>&nbsp;&nbsp;&nbsp;&nbsp;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;<strong><font color="#0000ff">public</font></strong>&nbsp;<strong><font color="#0000ff">void</font></strong>&nbsp;setName(<strong><a href="http://www.javaresearch.org/source/jdk142/java/lang/String.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>String</u></font></a></strong>&nbsp;name)&nbsp;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;{
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong><font color="#0000ff">this</font></strong>.name&nbsp;=&nbsp;name;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;}
    <li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;<strong><font color="#0000ff">public</font></strong>&nbsp;<font color="#ff0000">Set</font>&nbsp;getCourseSelections()&nbsp;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;{
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong><font color="#0000ff">return</font></strong>&nbsp;<strong><font color="#0000ff">this</font></strong>.courseSelections;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;}
    <li>&nbsp;&nbsp;&nbsp;&nbsp;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;<strong><font color="#0000ff">public</font></strong>&nbsp;<strong><font color="#0000ff">void</font></strong>&nbsp;setCourseSelections(<font color="#ff0000">Set</font>&nbsp;courseSelections)&nbsp;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;{
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong><font color="#0000ff">this</font></strong>.courseSelections&nbsp;=&nbsp;courseSelections;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;}
    <li>} </li>
</ol>
</div>
<br />
这个类就是一个POJO，你可以很明显的看出来它就是一个JavaBean。我想解释它的courseSelection字段。很显然，在数据库表student中，没有这个字段。这里的这个字段是因为一个外键引用，course_selection的student_id是一个外键，引用了student表中的id字段。那么在Student类中courseSelection来记录这样的外键关系，也就是说，当我们获取了Student对象以后，就可以直接获取他的选课记录，这样就为上层的调用提供了很大的方便。这里有点模糊没关系，我在介绍映射定义文件（*.hbm.xml）的时候还会提到这个问题。<br />
2.&nbsp;&nbsp;&nbsp;&nbsp;StudentDAO.java<br />
代码片段5：<br />
<div class="codeStyle">
<ol>
    <li>
    <li><strong><font color="#0000ff">public</font></strong>&nbsp;<strong><font color="#0000ff">class</font></strong>&nbsp;StudentDAO&nbsp;
    <li>{
    <li>&nbsp;&nbsp;&nbsp;&nbsp;Session&nbsp;session;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;<strong><font color="#0000ff">public</font></strong>&nbsp;StudentDAO()
    <li>&nbsp;&nbsp;&nbsp;&nbsp;{
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff0000">Configuration</font>&nbsp;cfg&nbsp;=&nbsp;<strong><font color="#0000ff">new</font></strong>&nbsp;<font color="#ff0000">Configuration</font>();
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cfg.configure(<font color="#ff33ff">"/hibernate.cfg.xml"</font>);
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SessionFactory&nbsp;sessionFactory&nbsp;=&nbsp;cfg.buildSessionFactory();
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;session&nbsp;=&nbsp;sessionFactory.openSession();
    <li>&nbsp;&nbsp;&nbsp;&nbsp;}
    <li>&nbsp;&nbsp;&nbsp;&nbsp;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;<strong><font color="#0000ff">public</font></strong>&nbsp;<strong><font color="#0000ff">void</font></strong>&nbsp;save(Student&nbsp;transientInstance)&nbsp;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;{
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;session.save(transientInstance);
    <li>&nbsp;&nbsp;&nbsp;&nbsp;}
    <li>&nbsp;&nbsp;&nbsp;&nbsp;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;<strong><font color="#0000ff">public</font></strong>&nbsp;<strong><font color="#0000ff">void</font></strong>&nbsp;delete(Student&nbsp;persistentInstance)&nbsp;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;{
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;session.delete(persistentInstance);
    <li>&nbsp;&nbsp;&nbsp;&nbsp;}
    <li>&nbsp;&nbsp;&nbsp;&nbsp;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;<strong><font color="#0000ff">public</font></strong>&nbsp;Student&nbsp;findById(java.lang.<strong><a href="http://www.javaresearch.org/source/jdk142/java/lang/String.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>String</u></font></a></strong>&nbsp;id)&nbsp;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;{
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff0000">List</font>&nbsp;list&nbsp;=&nbsp;session.createCriteria(Student.<strong><font color="#0000ff">class</font></strong>).add(
    <li><font color="#ff0000">Expression</font>.eq(<font color="#ff33ff">"id"</font>,&nbsp;id)).list();
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong><font color="#0000ff">if</font></strong>&nbsp;(list.size()&nbsp;&gt;&nbsp;0)&nbsp;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong><font color="#0000ff">return</font></strong>&nbsp;(Student)list.get(0);
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong><font color="#0000ff">return</font></strong>&nbsp;<strong><font color="#0000ff">null</font></strong>;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;}
    <li>} </li>
</ol>
</div>
<br />
这里的构造函数是用来启动Hibernate，并获取session。打开一个session就相当于打开了一个数据库连接，然后我们就可以对这个session进行操作，完成数据库操作，完全不用写SQL语句。我这里Hibernate的启动方式写的很不规范，系统应该只需要完成一次Hibernate启动就可以在不同的DAO中使用，我把它写在构造函数里面纯粹是为了简化演示代码。<br />
你可以看到save和delete方法都很简单直接对对象操作，而findById就有些麻烦，因为这里有一个查询过程在里面。Hibernate里面查询可以用Criteria这个类来完成，我们也常用Hibernate独有的HQL（Hibernate&nbsp;Query&nbsp;Language）来完成查询。当然Hibernate也是支持原生SQL的。关于查询的详细信息请参考其他文章或书籍，我只是演示一个流程，介绍一些概念。<br />
3.&nbsp;&nbsp;&nbsp;&nbsp;Student.hbm.xml<br />
代码片段6：<br />
<div class="codeStyle">
<ol>
    <li>
    <li>&lt;hibernate-mapping&gt;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&lt;<strong><font color="#0000ff">class</font></strong>&nbsp;name=<font color="#ff33ff">"Student"</font>&nbsp;table=<font color="#ff33ff">"STUDENT"</font>&gt;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;id&nbsp;name=<font color="#ff33ff">"id"</font>&nbsp;type=<font color="#ff33ff">"string"</font>&gt;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;column&nbsp;name=<font color="#ff33ff">"ID"</font>&nbsp;<strong><font color="#0000ff">length</font></strong>=<font color="#ff33ff">"10"</font>&nbsp;/&gt;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;generator&nbsp;<strong><font color="#0000ff">class</font></strong>=<font color="#ff33ff">"assigned"</font>&nbsp;/&gt;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/id&gt;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;property&nbsp;name=<font color="#ff33ff">"name"</font>&nbsp;type=<font color="#ff33ff">"string"</font>&gt;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;column&nbsp;name=<font color="#ff33ff">"NAME"</font>&nbsp;not-<strong><font color="#0000ff">null</font></strong>=<font color="#ff33ff">"true"</font>&nbsp;/&gt;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/property&gt;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;set&nbsp;name=<font color="#ff33ff">"courseSelections"</font>&nbsp;inverse=<font color="#ff33ff">"true"</font>&gt;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;key&gt;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;column&nbsp;name=<font color="#ff33ff">"STUDENT_ID"</font>&nbsp;<strong><font color="#0000ff">length</font></strong>=<font color="#ff33ff">"10"</font>&nbsp;
    <li>not-<strong><font color="#0000ff">null</font></strong>=<font color="#ff33ff">"true"</font>&nbsp;/&gt;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/key&gt;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;one-to-many&nbsp;<strong><font color="#0000ff">class</font></strong>=<font color="#ff33ff">"CourseSelection"</font>&nbsp;/&gt;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/set&gt;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&lt;/<strong><font color="#0000ff">class</font></strong>&gt;
    <li>&lt;/hibernate-mapping&gt; </li>
</ol>
</div>
<br />
这个文件定义了Student类和Student表是如何映射的。class元素定义了Sudent类和STUDENT表映射，然后就定义了各个属性是如何映射的。如果一个属性是数据库的key，那么会用id标签来定义，column定义了当前类的属性和数据库中的哪个字段对应，generator是id特有的。一般来说id是自增的，由于我的数据库是用的Oracle，它没有自增字段，要实现自增必须用Sequence，这超出了本文的范围，所以我就用assigned来简化示例代码。assigned表示id是用户给定的。<br />
有一个比较特别的标签是set，它对应着数据库中的外键关系，上文我提到的通过Student对象可以获得所有相关的选课记录就是通过这里的定义实现的。name属性对应了Student类中的字段名，key表示哪个字段是外键，one-to-many表示Student和CourseSelection是一对多关系，这和事实相符。类似的还有many-to-one，many-to-many，不过这些都不常用，我不介绍了。Hibernate根据这个映射定义文件，在实例化一个POJO（比如Student）的时候，会自动的把定义过映射的属性用数据库中的数据填充，set也包括在内。<br />
4.&nbsp;&nbsp;&nbsp;&nbsp;hibernate.cfg.xml<br />
代码片段7：<br />
<div class="codeStyle">
<ol>
    <li>
    <li>&lt;hibernate-configuration&gt;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&lt;session-factory&gt;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;property&nbsp;name=<font color="#ff33ff">"connection.username"</font>&gt;test&lt;/property&gt;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;property&nbsp;name=<font color="#ff33ff">"connection.url"</font>&gt;
    <li>jdbc:oracle:thin:@10.85.33.199:1521:glee&lt;/property&gt;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;property&nbsp;name=<font color="#ff33ff">"dialect"</font>&gt;
    <li>org.hibernate.dialect.Oracle9Dialect&lt;/property&gt;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;property&nbsp;name=<font color="#ff33ff">"connection.password"</font>&gt;test&lt;/property&gt;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;property&nbsp;name=<font color="#ff33ff">"connection.driver_class"</font>&gt;
    <li>oracle.jdbc.OracleDriver&lt;/property&gt;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;mapping&nbsp;resource=<font color="#ff33ff">"Student.hbm.xml"</font>&gt;&lt;/mapping&gt;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;mapping&nbsp;resource=<font color="#ff33ff">"CourseSelection.hbm.xml"</font>&gt;&lt;/mapping&gt;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;mapping&nbsp;resource=<font color="#ff33ff">"Course.hbm.xml"</font>&gt;&lt;/mapping&gt;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&lt;/session-factory&gt;
    <li>&lt;/hibernate-configuration&gt; </li>
</ol>
</div>
<br />
这个文件我不解释了，自己看吧。结合上文StudentDAO的例子，我想你应该能看明白。<br />
看了这么多，或许你会有点头皮发麻，POJO，DAO，配置文件...好像要写的东西还是很多。值得庆幸的是现在Hibernate已经发展的比较成熟了，有很多工具来帮助我们完成这些工作，比如MiddleGen，Hibernate&nbsp;Synchronizer等等。我使用的开发工具是Eclipse+MyEclipse，我所要做的只是把数据库表建好，然后MyEclipse提供的工具会自动根据数据库表生成POJO，DAO，*.hbm.xml，甚至hibernate.cfg.xml都是自动完成的（前提是MyEclipse知道你的数据库连接信息）。我并不打算介绍如何用IDE来开发Hibernate，你可以参考IDE的帮助文档。<br />
到这里为止，使用Hibernate进行开发的基本组成元素我都介绍好了，强烈建议你马上实践一遍，即使有些不理解，也先依葫芦画瓢一个。对了，别忘了把Hibernate的包down下来放到classpath里面。<br />
<br />
三、Session与SessionFactory<br />
Session可以说是Hibernate的核心，Hibernate对外暴露的接口就是Session。所以我这里讲一下有关Session的常用函数和特性。<br />
在讲Session之前，我想先提一下SessionFactory，这个东西不复杂，只要配置好就行了。顾名思义，SessionFactory就是用来创建Session的。SessionFactory是线程安全的，也就是说对于同一个数据库的所有操作共享一个SessionFactory就行了。回头看代码片段5，我们可以看到SessionFactory的常用配置方式。<br />
代码片段8：<br />
<div class="codeStyle">
<ol>
    <li>
    <li><font color="#ff0000">Configuration</font>&nbsp;cfg&nbsp;=&nbsp;<strong><font color="#0000ff">new</font></strong>&nbsp;<font color="#ff0000">Configuration</font>();
    <li>cfg.configure(<font color="#ff33ff">"/hibernate.cfg.xml"</font>);
    <li>SessionFactory&nbsp;sessionFactory&nbsp;=&nbsp;cfg.buildSessionFactory(); </li>
</ol>
</div>
<br />
我们通过Configuration来读取配置文件，然后就可以创建SessionFactory，这段代码在&nbsp;&nbsp;&nbsp;&nbsp;所有系统中都大同小异，一般就是xml配置文件的名字不一样，所以也没什么好说的。<br />
当我们有了SessionFactory以后就可以获取Session了。调用SessionFactory.openSession()就会返回一个Session实例，然后我们操作这个Session来访问数据库。值得一提的是Session并不是线程安全的，也就是每一个线程都必须有自己的Session。所以我们一般通过以下方法来获取和关闭Session：<br />
代码片段9：<br />
<div class="codeStyle">
<ol>
    <li>
    <li><strong><font color="#0000ff">public</font></strong>&nbsp;<strong><font color="#0000ff">static</font></strong>&nbsp;Session&nbsp;currentSession()&nbsp;<strong><font color="#0000ff">throws</font></strong>&nbsp;HibernateException&nbsp;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;{
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Session&nbsp;session&nbsp;=&nbsp;(Session)&nbsp;threadLocal.get();
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong><font color="#0000ff">if</font></strong>&nbsp;(session&nbsp;==&nbsp;<strong><font color="#0000ff">null</font></strong>&nbsp;||&nbsp;!session.isOpen())&nbsp;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong><font color="#0000ff">if</font></strong>&nbsp;(sessionFactory&nbsp;==&nbsp;<strong><font color="#0000ff">null</font></strong>)&nbsp;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong><font color="#0000ff">try</font></strong>&nbsp;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cfg.configure(CONFIG_FILE_LOCATION);
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sessionFactory&nbsp;=&nbsp;cfg.buildSessionFactory();
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong><font color="#0000ff">catch</font></strong>&nbsp;(<strong><a href="http://www.javaresearch.org/source/jdk142/java/lang/Exception.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>Exception</u></font></a></strong>&nbsp;e)&nbsp;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;session&nbsp;=&nbsp;(sessionFactory&nbsp;!=&nbsp;<strong><font color="#0000ff">null</font></strong>)&nbsp;?
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sessionFactory.openSession():&nbsp;<strong><font color="#0000ff">null</font></strong>;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;threadLocal.set(session);
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong><font color="#0000ff">return</font></strong>&nbsp;session;
    <li>}
    <li>
    <li><strong><font color="#0000ff">public</font></strong>&nbsp;<strong><font color="#0000ff">static</font></strong>&nbsp;<strong><font color="#0000ff">void</font></strong>&nbsp;closeSession()&nbsp;<strong><font color="#0000ff">throws</font></strong>&nbsp;HibernateException&nbsp;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;{
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Session&nbsp;session&nbsp;=&nbsp;(Session)&nbsp;threadLocal.get();
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;threadLocal.set(<strong><font color="#0000ff">null</font></strong>);
    <li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong><font color="#0000ff">if</font></strong>&nbsp;(session&nbsp;!=&nbsp;<strong><font color="#0000ff">null</font></strong>)&nbsp;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;session.close();
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
    <li>} </li>
</ol>
</div>
<br />
可以看到，我们通过threadLocal来保存每个线程的session，这样就保证了各个线程之&nbsp;&nbsp;&nbsp;&nbsp;间的互不干扰，也保证了系统只有一个SessionFactory实例（对于大多数应用来说已经&nbsp;&nbsp;&nbsp;&nbsp;足够了）。如果你使用MyEclipse进行开发的话，它会自动生成一个&nbsp;&nbsp;&nbsp;&nbsp;HibernateSessionFactory.java，其中就包含了以上代码。<br />
好了，现在我们已经获得了Session，下面我来介绍以下Session的常用函数，这些函数都有很多重载函数，我只介绍以下大概是干嘛的，不一一解释，详细信息你可以查看Hibernate的API。<br />
1．Session.get()，获取某个类的实例，一般都是通过id来获取比如<br />
Session.get(Student.class,&nbsp;"0361095");<br />
这句话的意思就是获取id（primary&nbsp;key）为&#8220;0361095&#8221;的Student对象。这里要注&nbsp;&nbsp;&nbsp;&nbsp;意的是第二个参数必须是Object，也就是说，如果是long类型的1，那么必须转换&nbsp;&nbsp;&nbsp;&nbsp;成new&nbsp;Long(1)再传入。<br />
2．Session.load()，用法和意义都和get一样，不过它们还是有点区别，我稍后解释。<br />
3．Session.save()，将某个实例保存到数据库中去（往往在数据库中形成一条新的记录）。<br />
4．Session.update()，更新某个实例，这个实例必须和数据库中有对应，否则会报错。<br />
5．Session.delete()，删除某个实例，也就是删除这个实例对应的数据表中的数据。<br />
6．Session.saveOrUpdate()，保存或者更新某个实例，调用这个方法你就不用去关心到&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;底是save还是update了，它会自己判断，然后调用相应的函数。其实save和update&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;涉及到实体对象生命周期中的三种状态，这个比较重要，我在后面会单独讲的。<br />
对于get和load的区别，很难讲清楚，这里涉及到Hibernate的缓存机制，是一个非常&nbsp;&nbsp;&nbsp;&nbsp;复杂的话题，我不打算深入讨论这个内容。简单的来讲，Session实现了Hibernate的一&nbsp;&nbsp;&nbsp;&nbsp;级缓存，SessionFactory实现了Hibernate的二级缓存。load方法会先查找一级缓存再查&nbsp;&nbsp;&nbsp;&nbsp;找二级缓存，最后再去数据库中找，而get只会查找一级缓存，然后就去数据库中找了。&nbsp;&nbsp;&nbsp;&nbsp;这只是是get和load的一个区别，另外的区别如果你有兴趣的话自己去google吧。关于Hibernate的缓存机制，如果你只是一般用用Hibernate的话没有必要深入研究，就当它不存在好了，get和load到底用哪个也不用非常讲究，如果你用工具生成DAO的话，&nbsp;&nbsp;&nbsp;&nbsp;生成的代码用什么就用什么吧。<br />
<br />
<strong>四、关键概念的理解</strong><br />
在使用Hibernate进行开发的时候有几个概念在我看来是必须理解的，否则在开发的时候会遇到很多问题而摸不着头脑。<br />
1．Lazy&nbsp;loading，懒加载（延迟加载）<br />
这个技术在很多地方被应用，比如Eclipse的插件管理也是用的延迟加载。在Hibernate中，所谓延迟加载就是返回一个POJO但是某些数据（往往是实体类型或者Set类型）并没有被真正的被填充，直到POJO的某个字段真正被引用的时候才从数据库中读取相应的数据来填充POJO中的字段。这样就能有效的避免很多不必要的数据库操作，因为POJO的有些数据我们并不需要，而且数据库操作是很费时间的。在Hibernate2中，默认是非延迟加载的，而在Hibernate3中，默认就是延迟加载了。<br />
如果使用了延迟加载，那么在读取数据的时候有一个问题必须注意，那就是在数据真正被加载之前，Session不能被关闭。你可以回头看一下代码片段5，我在构造函数里面open了session以后就没有关闭这个session，所以我在使用的时候没有什么问题，但这样总占着数据库连接也不好，用好了应该及时关闭给别人用。我上文给的例子中没有关闭Session的代码，要加的话给DAO加一个方法调用Session.close()，然后在代码片段1中的return之前调用这个方法就行了。<br />
Hibernate的延迟加载机制远不是这么简单，但是普通的应用没有必要去深究这些东西，了解这么多就够了。<br />
<br />
2．&nbsp;Object&nbsp;lifecycle，对象生命周期<br />
在Hibernate中，对象分为三种状态，Transient（自由状态）、Persistent（持久状态），Detached（游离状态），下面我分别解释一下。<br />
1、自由状态：所谓自由状态就是说这个对象是自由的，与Hibernate无关，比&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;如：<br />
Student&nbsp;student&nbsp;=&nbsp;new&nbsp;Student();<br />
&nbsp;&nbsp;&nbsp;&nbsp;student.setId("0361095");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;这里的student就是一个普通的对象与hibernate无关，称为自由状态。<br />
<br />
2、持久状态：所谓持久状态就是指对象和数据库中的数据（持久状态的数据）&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;有关联，也就是说对象被Hibernate所管理了，比如：<br />
session.save(student);<br />
&nbsp;&nbsp;&nbsp;这样student对象就从自由状态变为持久状态了。持久状态的对象在Session&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;与数据库中的数据进行同步时（比如commit）会把数据更新到数据库。而&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;其他状态的则不会。我觉得可以这样来理解持久状态，可以看成Hibernate&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;也拥有一份对象的引用，那么如果你对持久状态对象的属性进行更改的话，&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Hibernate看到的对象的状态也更改了，而Hibernate所看到的对象和数据&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;库中的数据是等价的。也正是这样，Hibernate才实现了Object/Relation&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;的映射。类似的，load和get方法也一样会获取Persistent状态的对象。<br />
<br />
3、游离状态：每次调用Session.close以后，所有跟这个session有关的处于<br />
Persistant的对象就变成了游离状态。也许你要问Detached和Transient有什么区别。其实从我给的例子来说看不出什么区别，因为我这里ID是给定的，而真正开发的时候ID往往是自增的，那么Transient的对象是没有ID&nbsp;&nbsp;&nbsp;&nbsp;的，当save了以后就有了，显而易见Detached的对象也是有ID，只不过这个对象已经和Hibernate脱离了关系。但是游离状态的对象仍然和数据库&nbsp;&nbsp;&nbsp;&nbsp;中的记录有一定联系，至少游离状态的对象知道数据库中有条记录的ID为xxx。从这一点上来讲，游离状态是可以自己创造出来的，只要你知道数据库中的主键信息。<br />
在使用Hibernate开发的时候要分清楚这三种状态，否则很容易出错。比如不能去save一个游离状态的对象，不能去update一个自由状态的对象等等。<br />
<br />
<strong>五、结束语</strong><br />
我要讲的就这么多，这篇文章不是详细介绍Hibernate，我只是总结了自己学习和使用Hibernate的一些感受和经验，希望能给没有用过Hibernate的开发者一个上手的指引。如果你看完了这篇文章仍然满头雾水，无从下手的话，我只能向你表示歉意，浪费你的时间了。不管怎样，我强烈推荐一本书《深入浅出Hibernate》，这本书既能作为学习的教程，也能作为日后的查询用书，相当实用。
<img src ="http://www.blogjava.net/human2008/aggbug/174225.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/human2008/" target="_blank">灵!</a> 2008-01-10 11:39 <a href="http://www.blogjava.net/human2008/archive/2008/01/10/174225.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>