﻿<?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-thinking-随笔分类-Hibernate</title><link>http://www.blogjava.net/alinglau36/category/40192.html</link><description>one platform thousands thinking</description><language>zh-cn</language><lastBuildDate>Fri, 10 Jul 2009 10:14:08 GMT</lastBuildDate><pubDate>Fri, 10 Jul 2009 10:14:08 GMT</pubDate><ttl>60</ttl><item><title>unsaved-value</title><link>http://www.blogjava.net/alinglau36/archive/2009/07/10/286297.html</link><dc:creator>lau</dc:creator><author>lau</author><pubDate>Fri, 10 Jul 2009 09:38:00 GMT</pubDate><guid>http://www.blogjava.net/alinglau36/archive/2009/07/10/286297.html</guid><wfw:comment>http://www.blogjava.net/alinglau36/comments/286297.html</wfw:comment><comments>http://www.blogjava.net/alinglau36/archive/2009/07/10/286297.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/alinglau36/comments/commentRss/286297.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/alinglau36/services/trackbacks/286297.html</trackback:ping><description><![CDATA[当你显式的使用session.save()或者session.update()操作一个对象的时候，实际上是用不到<span class="hilite1">unsaved-value</span>的。某些情况下(父子表关联保存)，当你在程序中并没有显式的使用save或者update一个持久对象，那么Hibernate需要判断被操作的对象究竟是一个已经持久化过的持久对象，是一个尚未被持久化过的内存临时对象。例如：
<br />
<br />
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <embed src="http://www.javaeye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=Session%20session%20%3D%20...%3B%0ATransaction%20tx%20%3D%20...%3B%0A%0AParent%20parent%20%3D%20(Parent)%3B%20session.load(Parent.class%2C%20id)%3B%3B%0A%0AChild%20child%20%3D%20new%20Child()%3B%3B%0Achild.setParent(parent)%3B%3B%0Achild.setName(%22sun%22)%3B%3B%0A%0Aparent.addChild(child)%3B%3B%0As.update(parent)%3B%3B%0A%0As.flush()%3B%3B%0Atx.commit()%3B%3B%0As.close()%3B%3B" quality="high" allowscriptaccess="always" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" width="14" height="15"></div>
</div>
<ol class="dp-j" start="1">
    <li><span><span>Session&nbsp;session&nbsp;=&nbsp;...;&nbsp;&nbsp;</span></span></li>
    <li><span>Transaction&nbsp;tx&nbsp;=&nbsp;...;&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>Parent&nbsp;parent&nbsp;=&nbsp;(Parent);&nbsp;session.load(Parent.<span class="keyword">class</span><span>,&nbsp;id);;&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>Child&nbsp;child&nbsp;=&nbsp;<span class="keyword">new</span><span>&nbsp;Child();;&nbsp;&nbsp;</span></span></li>
    <li><span>child.setParent(parent);;&nbsp;&nbsp;</span></li>
    <li><span>child.setName(<span class="string">"sun"</span><span>);;&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>parent.addChild(child);;&nbsp;&nbsp;</span></li>
    <li><span>s.update(parent);;&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>s.flush();;&nbsp;&nbsp;</span></li>
    <li><span>tx.commit();;&nbsp;&nbsp;</span></li>
    <li><span>s.close();;&nbsp;&nbsp;</span></li>
</ol>
</div>
<pre style="display: none;" name="code" class="java">Session session = ...;
Transaction tx = ...;
Parent parent = (Parent); session.load(Parent.class, id);;
Child child = new Child();;
child.setParent(parent);;
child.setName("sun");;
parent.addChild(child);;
s.update(parent);;
s.flush();;
tx.commit();;
s.close();;</pre>
<br />
<br />
在上例中，程序并没有显式的session.save(child);
那么Hibernate需要知道child究竟是一个临时对象，还是已经在数据库中有的持久对象。如果child是一个新创建的临时对象(本例中就是这种
情况)，那么Hibernate应该自动产生session.save(child)这样的操作，如果child是已经在数据库中有的持久对象，那么
Hibernate应该自动产生session.update(child)这样的操作。
<br />
<br />
因此我们需要暗示一下Hibernate，究竟child对象应该对它自动save还是update。在上例中，显然我们应该暗示
Hibernate对child自动save，而不是自动update。那么Hibernate如何判断究竟对child是save还是update呢？
它会取一下child的主键属性 child.getId() ，这里假设id是
java.lang.Integer类型的。如果取到的Id值和hbm映射文件中指定的unsave-value相等，那么Hibernate认为
child是新的内存临时对象，发送save，如果不相等，那么Hibernate认为child是已经持久过的对象，发送update。
<br />
<br />
<span class="hilite1">unsaved-value</span>="null" (默认情况，适用于大多数对象类型主键 Integer/Long/String/...)
<br />
<br />
当Hibernate取一下child的Id，取出来的是null(在上例中肯定取出来的是null)，和<span class="hilite1">unsaved-value</span>设定值相等，发送save(child)
<br />
<br />
当Hibernate取一下child的id，取出来的不是null，那么和<span class="hilite1">unsaved-value</span>设定值不相等，发送update(child)
<br />
<br />
例如下面的情况：
<br />
<br />
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <embed src="http://www.javaeye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=Session%20session%20%3D%20...%3B%0ATransaction%20tx%20%3D%20...%3B%0A%0AParent%20parent%20%3D%20(Parent)%3B%20session.load(Parent.class%2C%20id)%3B%3B%0AChild%20child%20%3D%20(Child)%3B%20session.load(Child.class%2C%20childId)%3B%3B%0A%0Achild.setParent(parent)%3B%3B%0Achild.setName(%22sun%22)%3B%3B%0A%0Aparent.addChild(child)%3B%3B%0As.update(parent)%3B%3B%0A%0As.flush()%3B%3B%0Atx.commit()%3B%3B%0As.close()%3B%3B" quality="high" allowscriptaccess="always" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" width="14" height="15"></div>
</div>
<ol class="dp-j" start="1">
    <li><span><span>Session&nbsp;session&nbsp;=&nbsp;...;&nbsp;&nbsp;</span></span></li>
    <li><span>Transaction&nbsp;tx&nbsp;=&nbsp;...;&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>Parent&nbsp;parent&nbsp;=&nbsp;(Parent);&nbsp;session.load(Parent.<span class="keyword">class</span><span>,&nbsp;id);;&nbsp;&nbsp;</span></span></li>
    <li><span>Child&nbsp;child&nbsp;=&nbsp;(Child);&nbsp;session.load(Child.<span class="keyword">class</span><span>,&nbsp;childId);;&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>child.setParent(parent);;&nbsp;&nbsp;</span></li>
    <li><span>child.setName(<span class="string">"sun"</span><span>);;&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>parent.addChild(child);;&nbsp;&nbsp;</span></li>
    <li><span>s.update(parent);;&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>s.flush();;&nbsp;&nbsp;</span></li>
    <li><span>tx.commit();;&nbsp;&nbsp;</span></li>
    <li><span>s.close();;&nbsp;&nbsp;</span></li>
</ol>
</div>
<pre style="display: none;" name="code" class="java">Session session = ...;
Transaction tx = ...;
Parent parent = (Parent); session.load(Parent.class, id);;
Child child = (Child); session.load(Child.class, childId);;
child.setParent(parent);;
child.setName("sun");;
parent.addChild(child);;
s.update(parent);;
s.flush();;
tx.commit();;
s.close();;</pre>
<br />
<br />
child已经在数据库中有了，是一个持久化的对象，不是新创建的，因此我们希望Hibernate发送update(child)，在该例
中，Hibernate取一下child.getId()，和unsave-value指定的null比对一下，发现不相等，那么发送
update(child)。
<br />
<br />
BTW: parent对象不需要操心，因为程序显式的对parent有load操作和update的操作，不需要Hibernate自己来判断究竟是save还是update了。我们要注意的只是child对象的操作。另外<span class="hilite1">unsaved-value</span>是定义在Child类的主键属性中的。
<br />
<br />
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <embed src="http://www.javaeye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=%3Cclass%20name%3D%22Child%22%20table%3D%22child%22%3E%0A%3Cid%20column%3D%22id%22%20name%3D%22id%22%20type%3D%22integer%22%20unsaved-value%3D%22null%22%3E%0A%20%20%3Cgenerator%20class%3D%22identity%22%2F%3E%0A%3C%2Fid%3E%0A...%0A%3C%2Fclass%3E" quality="high" allowscriptaccess="always" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" width="14" height="15"></div>
</div>
<ol class="dp-j" start="1">
    <li><span><span>&lt;</span><span class="keyword">class</span><span>&nbsp;name=</span><span class="string">"Child"</span><span>&nbsp;table=</span><span class="string">"child"</span><span>&gt;&nbsp;&nbsp;</span></span></li>
    <li><span>&lt;id&nbsp;column=<span class="string">"id"</span><span>&nbsp;name=</span><span class="string">"id"</span><span>&nbsp;type=</span><span class="string">"integer"</span><span>&nbsp;<span class="hilite1">unsaved-value</span>=</span><span class="string">"null"</span><span>&gt;&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&lt;generator&nbsp;<span class="keyword">class</span><span>=</span><span class="string">"identity"</span><span>/&gt;&nbsp;&nbsp;</span></span></li>
    <li><span>&lt;/id&gt;&nbsp;&nbsp;</span></li>
    <li><span>...&nbsp;&nbsp;</span></li>
    <li><span>&lt;/<span class="keyword">class</span><span>&gt;&nbsp;&nbsp;</span></span></li>
</ol>
</div>
<pre style="display: none;" name="code" class="java">&lt;class name="Child" table="child"&gt;
&lt;id column="id" name="id" type="integer" <span class="hilite1">unsaved-value</span>="null"&gt;
&lt;generator class="identity"/&gt;
&lt;/id&gt;
...
&lt;/class&gt;</pre>
<br />
<br />
如果主键属性不是对象型，而是基本类型，如int/long/double/...，那么你需要指定一个数值型的<span class="hilite1">unsaved-value</span>，例如：
<br />
<br />
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <embed src="http://www.javaeye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=unsaved-null%3D%220%22" quality="high" allowscriptaccess="always" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" width="14" height="15"></div>
</div>
<ol class="dp-j" start="1">
    <li><span><span>unsaved-</span><span class="keyword">null</span><span>=</span><span class="string">"0"</span><span>&nbsp;&nbsp;</span></span></li>
</ol>
</div>
<pre style="display: none;" name="code" class="java">unsaved-null="0"</pre>
<br />
<br />
在此提醒大家，很多人以为对主键属性定义为int/long，比定义为Integer/Long运行效率来得高，认为基本类型不需要进行对象的封
装和解构操作，因此喜欢把主键定义为int/long的。但实际上，Hibernate内部总是把主键转换为对象型进行操作的，就算你定义为int
/long型的，Hibernate内部也要进行一次对象构造操作，返回给你的时候，还要进行解构操作，效率可能反而低也说不定。因此大家一定要扭转一个
观点，在Hibernate中，主键属性定义为基本类型，并不能够比定义为对象型效率来的高，而且也多了很多麻烦，因此建议大家使用对象型的
Integer/Long定义主键。
<br />
<br />
<span class="hilite1">unsaved-value</span>="none"和
<br />
<span class="hilite1">unsaved-value</span>="any"
<br />
<br />
主主要用在主键属性不是通过Hibernate生成，而是程序自己setId()的时候。
<br />
<br />
在这里多说一句，强烈建议使用Hibernate的id generator，或者你可以自己扩展Hibernate的id
generator，特别注意不要使用有实际含义的字段当做主键来用！例如用户类User，很多人喜欢用用户登陆名称做为主键，这是一个很不好的习惯，当
用户类和其他实体类有关联关系的时候，万一你需要修改用户登陆名称，一改就需要改好几张表中的数据。偶合性太高，而如果你使用无业务意义的id
generator，那么修改用户名称，就只修改user表就行了。
<br />
<br />
由这个问题引申出来，如果你严格按照这个原则来设计数据库，那么你基本上是用不到手工来setId()的，你用Hibernate的id generator就OK了。因此你也不需要了解当
<br />
<br />
<span class="hilite1">unsaved-value</span>="none"和
<br />
<span class="hilite1">unsaved-value</span>="any"
<br />
<br />
究竟有什么含义了。如果你非要用assigned不可，那么继续解释一下：
<br />
<br />
<span class="hilite1">unsaved-value</span>="none" 的时候，由于不论主键属性为任何值，都不可能为none，因此Hibernate总是对child对象发送update(child)
<br />
<br />
<span class="hilite1">unsaved-value</span>="any" 的时候，由于不论主键属性为任何值，都肯定为any，因此Hibernate总是对child对象发送save(child)
<br />
<br />
大多数情况下，你可以避免使用assigned，只有当你使用复合主键的时候不得不手工setId()，这时候需要你自己考虑究竟怎么设置<span class="hilite1">unsaved-value</span>了，根据你自己的需要来定。
<br />
<br />
BTW: Gavin King强烈不建议使用composite-id，强烈建议使用UserType。
<br />
<br />
因此，如果你在系统设计的时候，遵循如下原则：
<br />
<br />
<span style="color: red;">1、使用Hibernate的id generator来生成无业务意义的主键，不使用有业务含义的字段做主键，不使用assigned。
<br />
<br />
2、使用对象类型(String/Integer/Long/...)来做主键，而不使用基础类型(int/long/...)做主键
<br />
<br />
3、不使用composite-id来处理复合主键的情况，而使用UserType来处理该种情况。</span>
<br />
<br />
那么你永远用的是<span class="hilite1">unsaved-value</span>="null" ，不可能用到any/none/..了。
<img src ="http://www.blogjava.net/alinglau36/aggbug/286297.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/alinglau36/" target="_blank">lau</a> 2009-07-10 17:38 <a href="http://www.blogjava.net/alinglau36/archive/2009/07/10/286297.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>many-to-one/one-to-many/many-to-many关系映射</title><link>http://www.blogjava.net/alinglau36/archive/2009/06/11/281493.html</link><dc:creator>lau</dc:creator><author>lau</author><pubDate>Thu, 11 Jun 2009 07:51:00 GMT</pubDate><guid>http://www.blogjava.net/alinglau36/archive/2009/06/11/281493.html</guid><wfw:comment>http://www.blogjava.net/alinglau36/comments/281493.html</wfw:comment><comments>http://www.blogjava.net/alinglau36/archive/2009/06/11/281493.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/alinglau36/comments/commentRss/281493.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/alinglau36/services/trackbacks/281493.html</trackback:ping><description><![CDATA[<strong>本文的内容：</strong><br />
介绍NH如何处理对象间many-to-one，one-to-many和many-to-many的双向映射关系（本文主要介绍了映射文件，对于类的生成可以跟据前两篇描述的方法生成）；<br />
<br />
<strong>经验教训：</strong><br />
<br />
<strong>相关类图：</strong>（下面的类图包含一对一，多对一，一对多和多对多）<img src="http://images.cnblogs.com/cnblogs_com/jailu/img3.JPG" border="0"  alt="" /><br />
<strong>many-to-one：</strong>描
述多对一的一种数据模型，它指定many一方是不能独立存在的，我个人认为many-to-one是NHB中保证数据有效性的最有用的一种映射，通过使用
many-to-one能有效的防治孤儿记录被写入到数据表中。在本文描述的例子中，Student类和Classes类之间是多对一关系．<br />
<br />
通过many-to-one元素,可以定义一种常见的与另一个持久化类的关联。这种关系模型是多对一关联。（实际上是一个对象引用。）在映射文件中用many-to-one标签描述此种关系．
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: #eeeeee;"><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">many-to-one<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #ff0000;">name</span><span style="color: #0000ff;">="propertyName"</span><span style="color: #ff0000;">(1)<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;column</span><span style="color: #0000ff;">="column_name"</span><span style="color: #ff0000;">(2)<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;class</span><span style="color: #0000ff;">="ClassName"</span><span style="color: #ff0000;">(3)<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cascade</span><span style="color: #0000ff;">="all|none|save-update|delete"</span><span style="color: #ff0000;">(4)<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;outer-join</span><span style="color: #0000ff;">="true|false|auto"</span><span style="color: #ff0000;">(5)<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;update</span><span style="color: #0000ff;">="true|false"</span><span style="color: #ff0000;">(6)<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;insert</span><span style="color: #0000ff;">="true|false"</span><span style="color: #ff0000;">(7)<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;property-ref</span><span style="color: #0000ff;">="propertyNameFromAssociatedClass"</span><span style="color: #ff0000;">&nbsp;(8)<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;access</span><span style="color: #0000ff;">="field|property|ClassName"</span><span style="color: #ff0000;">(9)<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unique</span><span style="color: #0000ff;">="true|false"</span><span style="color: #ff0000;">&nbsp;(10)<br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff;">/&gt;</span></div>
<p>１．name：属性名。指出many一方的类用哪个属性和one一方的类关联．<br />
２．column：字段名（可选）．指出many一方的类对应的数据表用哪个列和one一方的类对应的数据表关联（两表之间存在外键关联）；<br />
３．class：关联的类的名字（可选 - 默认是通过反射得到属性类型）；<br />
４．cascade：指明哪些操作会从父对象级联到关联的对象（可选）．<font face="Courier New">cascade</font>属性允许下列值：: <code>all</code>, <code>save-update</code>, <code>delete</code>, <code>none</code>. 设置除了<code>none</code>以外的其它值会传播特定的操作到关联的（子）对象中。<br />
５．outer-join：当设置<code>hibernate.use_outer_join</code>的时候，对这个关联允许外连接抓取（可选 - 默认为 <code>auto</code>）．<font face="Courier New">outer-join</font>参数允许下列三个不同值： auto（使用外连接抓取关联（对象），如果被关联的对象没有代理(proxy) ），true（一直使用外连接来抓取关联），false（永远不使用外连接来抓取关联）；<br />
６．update,insert：指定对应的字段是否在用于<code>UPDATE</code> 和/或 <code>INSERT</code>的SQL语句中包含。如果二者都是<code>false</code>,则这是一个纯粹的&#8220;外源性（derived）&#8221;关联，它的值是通过映射到同一个（或多个）字段的某些其他属性得到的，或者通过trigger(除法器），或者是其他程序（可选 - 默认为 <code>true</code>）<br />
７．property-
ref：指定关联类的一个属性，这个属性将会和本外键相对应。如果没有指定，会使用对方关联类的主键（可选）．property-ref属性只应该用来对
付老旧的数据库系统，可能出现外键指向对方关联表的是个非主键字段（但是应该是一个惟一关键字）的情况。这是一种十分丑陋的关系模型。比如说，假设
Product类有一个惟一的序列号，它并不是主键；<br />
８．access：NHibernate 用来访问属性的策略（可选 - 默认为<code>property</code>）<br />
９．unique：允许产生外键列唯一约束的数据库定义语言（DDL）（可选）<br />
<br />
那么关于Student的映射可能是：</p>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: #eeeeee;"><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">many-to-one&nbsp;</span><span style="color: #ff0000;">name</span><span style="color: #0000ff;">="Classes"</span><span style="color: #ff0000;">&nbsp;column</span><span style="color: #0000ff;">="cID"</span><span style="color: #ff0000;">&nbsp;unique&nbsp;</span><span style="color: #0000ff;">="true"</span><span style="color: #0000ff;">/&gt;</span></div>
<p>只要在原Student.hbm.xml映射文件中添加many-to-one标签就可以了．<br />
<br />
对于Sturent类得添加一个属性Classes:Classes<br />
<strong><br />
one-to-many：</strong>一对多也是一种常见的数据模型，在按范式设计的数据库中随处可见。在NHB中通过one-to-many可以非常方便的处理这种模型，同时NHB还提供了级联更新和删除的功能，以保证数据完整性。在本文描述的例子中，Classes类和Student类是一对多的关系．<br />
<br />
Classes类的映射文件：Classes.hbm.xml</p>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: #eeeeee;"><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #0000ff;">&lt;?</span><span style="color: #ff00ff;">xml&nbsp;version="1.0"&nbsp;encoding="utf-8"&nbsp;</span><span style="color: #0000ff;">?&gt;</span><span style="color: #000000;"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">hibernate-mapping&nbsp;</span><span style="color: #ff0000;">xmlns</span><span style="color: #0000ff;">="urn:nhibernate-mapping-2.0"</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">class&nbsp;</span><span style="color: #ff0000;">name</span><span style="color: #0000ff;">="NHibernateTest.Classes,NHibernateTest"</span><span style="color: #ff0000;">&nbsp;table</span><span style="color: #0000ff;">="Classes"</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">id&nbsp;</span><span style="color: #ff0000;">name</span><span style="color: #0000ff;">="ClassesID"</span><span style="color: #ff0000;">&nbsp;column</span><span style="color: #0000ff;">="ID"</span><span style="color: #ff0000;">&nbsp;type</span><span style="color: #0000ff;">="Int32"</span><span style="color: #ff0000;">&nbsp;unsaved-value</span><span style="color: #0000ff;">="0"</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">generator&nbsp;</span><span style="color: #ff0000;">class</span><span style="color: #0000ff;">="identity"</span><span style="color: #0000ff;">/&gt;</span><span style="color: #000000;"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">id</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">property&nbsp;</span><span style="color: #ff0000;">name</span><span style="color: #0000ff;">="ClassesName"</span><span style="color: #ff0000;">&nbsp;column</span><span style="color: #0000ff;">="ClassName"</span><span style="color: #ff0000;">&nbsp;type</span><span style="color: #0000ff;">="String"</span><span style="color: #ff0000;">&nbsp;length</span><span style="color: #0000ff;">="50"</span><span style="color: #0000ff;">/&gt;</span><span style="color: #000000;"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">bag&nbsp;</span><span style="color: #ff0000;">name</span><span style="color: #0000ff;">="StudentList"</span><span style="color: #ff0000;">&nbsp;cascade</span><span style="color: #0000ff;">="all"</span><span style="color: #ff0000;">&nbsp;&nbsp;inverse</span><span style="color: #0000ff;">="true"</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">key&nbsp;</span><span style="color: #ff0000;">column</span><span style="color: #0000ff;">="ID"</span>&nbsp;<span style="color: #0000ff;">/&gt;</span><span style="color: #000000;"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">one-to-many&nbsp;</span><span style="color: #ff0000;">class</span><span style="color: #0000ff;">="NHibernateTest.Student,NHibernateTest"</span>&nbsp;<span style="color: #0000ff;">/&gt;</span><span style="color: #000000;"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">bag</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">class</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">hibernate-mapping</span><span style="color: #0000ff;">&gt;</span></div>
<p>　　如映射文件所示，one-to-many标签必须包含在标签bag中（个人理解：多嘛，就用一个包装起来～）<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bag标签的name属性指出Address对象用哪个属性和Student对象关联，inverse属性使collection不更新连接（总之，这个属性提高了性能，具体的情况请参考NHibernate的帮助文档）．<br />
key标签的column属性指出了Address对象对应的数据表用哪个字段和Student对象对应的数据表关联<br />
one-to-many标签的class属性指出了Address和哪个对象关联．<br />
<br />
对于Classes类得创建一个StudentList : Student的属性，用来描述与Student对象的关系．<br />
<br />
<strong>many-to-many：</strong>多对多在数据库中也是常见的数据模型，像用户与组，用户与权限等。多对多关系需要通过一个中间表实现，element的就是读取这个中间表中某列的值。在本文的例子中，Student类和Subject类是多对多的关系．<br />
<br />
Student的映射可能是：</p>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: #eeeeee;"><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">bag&nbsp;</span><span style="color: #ff0000;">name</span><span style="color: #0000ff;">="SubjectList"</span><span style="color: #ff0000;">&nbsp;table</span><span style="color: #0000ff;">="r_Student_Subject"</span><span style="color: #ff0000;">&nbsp;inverse</span><span style="color: #0000ff;">="true"</span><span style="color: #ff0000;">&nbsp;cascade</span><span style="color: #0000ff;">="save-update"</span><span style="color: #ff0000;">&nbsp;lazy</span><span style="color: #0000ff;">="false"</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">key&nbsp;</span><span style="color: #ff0000;">column</span><span style="color: #0000ff;">="StudentID"</span>&nbsp;<span style="color: #0000ff;">/&gt;</span><span style="color: #000000;"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">many-to-many&nbsp;</span><span style="color: #ff0000;">class</span><span style="color: #0000ff;">="NHibernateTest.Subject,NHibernateTest"</span><span style="color: #ff0000;">&nbsp;column</span><span style="color: #0000ff;">="ID"</span><span style="color: #ff0000;">&nbsp;outer-join</span><span style="color: #0000ff;">="auto"</span>&nbsp;<span style="color: #0000ff;">/&gt;</span><span style="color: #000000;"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">bag</span><span style="color: #0000ff;">&gt;</span></div>
<p>　　在bag标签中，加入了一个table属性，它指定一个实现多对多的中间表<br />
<br />
完整的Student.hbm.xml源码如下：</p>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: #eeeeee;"><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #0000ff;">&lt;?</span><span style="color: #ff00ff;">xml&nbsp;version="1.0"&nbsp;encoding="utf-8"&nbsp;</span><span style="color: #0000ff;">?&gt;</span><span style="color: #000000;"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">hibernate-mapping&nbsp;</span><span style="color: #ff0000;">xmlns</span><span style="color: #0000ff;">="urn:nhibernate-mapping-2.0"</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">class&nbsp;</span><span style="color: #ff0000;">name</span><span style="color: #0000ff;">="NHibernateTest.Student,NHibernateTest"</span><span style="color: #ff0000;">&nbsp;table</span><span style="color: #0000ff;">="Users"</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">id&nbsp;</span><span style="color: #ff0000;">name</span><span style="color: #0000ff;">="UserID"</span><span style="color: #ff0000;">&nbsp;column</span><span style="color: #0000ff;">="ID"</span><span style="color: #ff0000;">&nbsp;type</span><span style="color: #0000ff;">="Int32"</span><span style="color: #ff0000;">&nbsp;unsaved-value</span><span style="color: #0000ff;">="0"</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">generator&nbsp;</span><span style="color: #ff0000;">class</span><span style="color: #0000ff;">="identity"</span><span style="color: #0000ff;">/&gt;</span><span style="color: #000000;"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">id</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">property&nbsp;</span><span style="color: #ff0000;">name</span><span style="color: #0000ff;">="UserName"</span><span style="color: #ff0000;">&nbsp;column</span><span style="color: #0000ff;">="UserName"</span><span style="color: #ff0000;">&nbsp;type</span><span style="color: #0000ff;">="String"</span><span style="color: #ff0000;">&nbsp;length</span><span style="color: #0000ff;">="20"</span><span style="color: #0000ff;">/&gt;</span><span style="color: #000000;"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">property&nbsp;</span><span style="color: #ff0000;">name</span><span style="color: #0000ff;">="Password"</span><span style="color: #ff0000;">&nbsp;column</span><span style="color: #0000ff;">="Password"</span><span style="color: #ff0000;">&nbsp;type</span><span style="color: #0000ff;">="String"</span><span style="color: #ff0000;">&nbsp;length</span><span style="color: #0000ff;">="20"</span><span style="color: #0000ff;">/&gt;</span><span style="color: #000000;"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">&lt;!--</span><span style="color: #008000;">Student类和NativePlace类是一对一的关系</span><span style="color: #008000;">--&gt;</span><span style="color: #000000;"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">one-to-one&nbsp;</span><span style="color: #ff0000;">name</span><span style="color: #0000ff;">="NativePlace"</span><span style="color: #ff0000;">&nbsp;class</span><span style="color: #0000ff;">="NHibernateTest.NativePlace,NHibernateTest"</span><span style="color: #ff0000;">&nbsp;cascade</span><span style="color: #0000ff;">="all"</span>&nbsp;<span style="color: #0000ff;">/&gt;</span><span style="color: #000000;"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">&lt;!--</span><span style="color: #008000;">Student类和Classes类是多对一的关系</span><span style="color: #008000;">--&gt;</span><span style="color: #000000;"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">many-to-one&nbsp;</span><span style="color: #ff0000;">name</span><span style="color: #0000ff;">="Classes"</span><span style="color: #ff0000;">&nbsp;column</span><span style="color: #0000ff;">="cID"</span><span style="color: #ff0000;">&nbsp;unique&nbsp;</span><span style="color: #0000ff;">="true"</span><span style="color: #0000ff;">/&gt;</span><span style="color: #000000;"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">&lt;!--</span><span style="color: #008000;">Student类和Address类是一对多的关系</span><span style="color: #008000;">--&gt;</span><span style="color: #000000;"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">bag&nbsp;</span><span style="color: #ff0000;">name</span><span style="color: #0000ff;">="AddressList"</span><span style="color: #ff0000;">&nbsp;cascade</span><span style="color: #0000ff;">="all"</span><span style="color: #ff0000;">&nbsp;&nbsp;inverse</span><span style="color: #0000ff;">="true"</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">key&nbsp;</span><span style="color: #ff0000;">column</span><span style="color: #0000ff;">="ID"</span>&nbsp;<span style="color: #0000ff;">/&gt;</span><span style="color: #000000;"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">one-to-many&nbsp;</span><span style="color: #ff0000;">class</span><span style="color: #0000ff;">="NHibernateTest.Address,NHibernateTest"</span>&nbsp;<span style="color: #0000ff;">/&gt;</span><span style="color: #000000;"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">bag</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">&lt;!--</span><span style="color: #008000;">Student类和Subject类是多对多的关系</span><span style="color: #008000;">--&gt;</span><span style="color: #000000;"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">bag&nbsp;</span><span style="color: #ff0000;">name</span><span style="color: #0000ff;">="SubjectList"</span><span style="color: #ff0000;">&nbsp;table</span><span style="color: #0000ff;">="r_Student_Subject"</span><span style="color: #ff0000;">&nbsp;inverse</span><span style="color: #0000ff;">="true"</span><span style="color: #ff0000;">&nbsp;cascade</span><span style="color: #0000ff;">="save-update"</span><span style="color: #ff0000;">&nbsp;lazy</span><span style="color: #0000ff;">="false"</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">key&nbsp;</span><span style="color: #ff0000;">column</span><span style="color: #0000ff;">="StudentID"</span>&nbsp;<span style="color: #0000ff;">/&gt;</span><span style="color: #000000;"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">many-to-many&nbsp;</span><span style="color: #ff0000;">class</span><span style="color: #0000ff;">="NHibernateTest.Subject,NHibernateTest"</span><span style="color: #ff0000;">&nbsp;column</span><span style="color: #0000ff;">="ID"</span><span style="color: #ff0000;">&nbsp;outer-join</span><span style="color: #0000ff;">="auto"</span>&nbsp;<span style="color: #0000ff;">/&gt;</span><span style="color: #000000;"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">bag</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">class</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">hibernate-mapping</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top"  alt="" /></span></div>
Student类得添加类型为IList的属性SubjectList表示与类Subject的关系．<br />
<br />
由于Student的映射关系比较复杂，本文就再熬述它的CRUD操作，具体的操作方法请参考本文附带的代码．
<img src ="http://www.blogjava.net/alinglau36/aggbug/281493.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/alinglau36/" target="_blank">lau</a> 2009-06-11 15:51 <a href="http://www.blogjava.net/alinglau36/archive/2009/06/11/281493.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>