﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-西部村里人-文章分类-Hibernate</title><link>http://www.blogjava.net/jdyao/category/8354.html</link><description /><language>zh-cn</language><lastBuildDate>Tue, 27 Feb 2007 12:18:57 GMT</lastBuildDate><pubDate>Tue, 27 Feb 2007 12:18:57 GMT</pubDate><ttl>60</ttl><item><title>Hibernate Cache相关资料收集</title><link>http://www.blogjava.net/jdyao/articles/37177.html</link><dc:creator>西部村里人</dc:creator><author>西部村里人</author><pubDate>Fri, 24 Mar 2006 03:48:00 GMT</pubDate><guid>http://www.blogjava.net/jdyao/articles/37177.html</guid><wfw:comment>http://www.blogjava.net/jdyao/comments/37177.html</wfw:comment><comments>http://www.blogjava.net/jdyao/articles/37177.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jdyao/comments/commentRss/37177.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jdyao/services/trackbacks/37177.html</trackback:ping><description><![CDATA[1、<a href="http://www.informit.com/articles/printerfriendly.asp?p=353736">Improving Hibernate's Performance</a><br />
   This chapter describes how to gather performance metrics
for the use of Hibernate in the field. Specific attention is giving to
key areas like collections and lazy loading of data.<br /><br />
2、<a href="http://wiki.tangosol.com/display/COH31UG/Using+Coherence+and+Hibernate">Using Coherence and Hibernate</a><br /><br />
3、<a href="http://ehcache.sourceforge.net/">Ehcache</a><br /><br />
4、<a href="http://swik.net/cache">http://swik.net/cache</a><br /><br />
5、<a href="http://www.devx.com/dbzone/Article/29685/1954?pf=true">Speed Up Your Hibernate Applications with Second-Level Caching</a><br /><br /><img src ="http://www.blogjava.net/jdyao/aggbug/37177.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jdyao/" target="_blank">西部村里人</a> 2006-03-24 11:48 <a href="http://www.blogjava.net/jdyao/articles/37177.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Hibernate对象关联--UML基础知识、XDoclet---- 5 XDoclet Template In Eclipse</title><link>http://www.blogjava.net/jdyao/articles/34910.html</link><dc:creator>西部村里人</dc:creator><author>西部村里人</author><pubDate>Sun, 12 Mar 2006 07:13:00 GMT</pubDate><guid>http://www.blogjava.net/jdyao/articles/34910.html</guid><wfw:comment>http://www.blogjava.net/jdyao/comments/34910.html</wfw:comment><comments>http://www.blogjava.net/jdyao/articles/34910.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jdyao/comments/commentRss/34910.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jdyao/services/trackbacks/34910.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; 在随笔中发了一篇XDoclet Template In Eclipse的内容，在实际使用过程中，我又按照个人习惯，进行了分类编辑，以便于更快捷的使用。<br>&nbsp;<br><font color="#0000ff">&lt;?xml version="1.0" encoding="UTF-8"?&gt;<br>&lt;templates&gt;&lt;template name="@hib-blob-byte" description="blob to byte" context="javadoc" enabled="true" deleted="false" autoinsert="true"&gt;@hibernate.property column="${enclosing_method}"&nbsp; type="org.springframework.orm.hibernate3.support.BlobByteArrayType" lazy="true"&amp;#13;&nbsp;&nbsp;&nbsp; &nbsp;&amp;#13;&nbsp;&nbsp;&nbsp; &nbsp;&amp;#13;&nbsp;&nbsp;&nbsp; &nbsp;&lt;/template&gt;&lt;template name="@hib-class" description="@hibernate.class" context="javadoc" enabled="true" deleted="false" autoinsert="true"&gt;@hibernate.class table="${enclosing_type}" dynamic-update="true"&lt;/template&gt;&lt;template name="@hib-class-disc" description="@hibernate.discriminator" context="javadoc" enabled="true" deleted="false" autoinsert="true"&gt;@hibernate.discriminator column="type" type="character" not-null="true" force="false"&lt;/template&gt;&lt;template name="@hib-class-join" description="hibernate join subclass" context="javadoc" enabled="true" deleted="false" autoinsert="true"&gt;@hibernate.joined-subclass table="${primary_type_name}" lazy="true" dynamic-update="true"&amp;#13;<br>*@hibernate.joined-subclass-key column="${primary_type_name}Guid"&amp;#13;*&amp;#13;*请修改子类的表名，对应表的主键，该主键不需要定义在类的属性中，它对应父类的主键&amp;#13;<br>&nbsp;&lt;/template&gt;&lt;template name="@hib-class-sub" description="@hibernate.subclass" context="javadoc" enabled="true" deleted="false" autoinsert="true"&gt;@hibernate.subclass name="${file}" discriminator-value=""&lt;/template&gt;&lt;template name="@hib-id-assign" description="id is assign" context="javadoc" enabled="true" deleted="false" autoinsert="true"&gt;@hibernate.id generator-class="assigned" length="20" column="请修改"&amp;#13;&lt;/template&gt;&lt;template name="@hib-id-guid" description="id is guid" context="javadoc" enabled="true" deleted="false" autoinsert="true"&gt;@hibernate.id generator-class="uuid" type="java.lang.String" &amp;#13;<br>&nbsp;&nbsp;&nbsp; * @hibernate.column name="guid" sql-type="VARCHAR(38)" not-null="true"&amp;#13;&nbsp;&nbsp;&nbsp; *&amp;#13;<br>&nbsp;&nbsp;&nbsp; * 请修改name of column的值&lt;/template&gt;&lt;template name="@hib-rel-many-to-many-list" description="many to many list" context="javadoc" enabled="true" deleted="false" autoinsert="true"&gt;@hibernate.list name="方法名（无Get）" inverse="true" cascade="save-update"&amp;#13;<br>&nbsp;&nbsp;&nbsp; &nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lazy="true"&amp;#13;<br>&nbsp;&nbsp;&nbsp; &nbsp;* @hibernate.collection-key column="外键"&amp;#13;<br>&nbsp;&nbsp;&nbsp; &nbsp;* @hibernate.collection-index column="tabIndex" type="int"&amp;#13;<br>&nbsp;&nbsp;&nbsp; &nbsp;* @hibernate.collection-one-to-many class="关联的类"&amp;#13;<br>&nbsp;&nbsp;&nbsp; &nbsp;* &amp;#13;<br>&nbsp;&nbsp;&nbsp; &nbsp;* 请修改外键，并且指定完整的关联类的类名（包+类名）&lt;/template&gt;&lt;template name="@hib-rel-many-to-many-set" description="many 2 many set" context="javadoc" enabled="true" deleted="false" autoinsert="true"&gt;@hibernate.set name="${enclosing_method}" table="关联表" cascade="save-update" inverse="true" lazy="true"&amp;#13;&nbsp;&nbsp;&nbsp; &nbsp;* @hibernate.collection-key column="自己的主键"&amp;#13;&nbsp;&nbsp;&nbsp; &nbsp;* @hibernate.collection-many-to-many class="关联类" column="关联类的主键"&amp;#13;&nbsp;&nbsp;&nbsp;&nbsp; *&amp;#13;&nbsp;&nbsp;&nbsp;&nbsp; * 两个类的主键构成关联表的属性，关联类请写完整的类名&amp;#13;&nbsp;&nbsp;&nbsp;&nbsp; * 多对多时，只能指定一个多的方向断子为true，即inverse="true"&amp;#13;&nbsp;&nbsp;&nbsp;&nbsp; * 多对多时，无法指定index顺序，因为你无法确定从两个方向看上去都具有顺序，所以使用List不可靠&amp;#13;&lt;/template&gt;&lt;template name="@hib-rel-many-to-one" description="@hibernate.many-to-one" context="javadoc" enabled="true" deleted="false" autoinsert="true"&gt;@hibernate.many-to-one column="${enclosing_method}_ID" class="${return_type}" cascade="none" outer-join="auto" not-null="false" lazy="true"<br>&nbsp;&nbsp;&nbsp; &nbsp;*&amp;#13;&nbsp;&nbsp;&nbsp;&nbsp; * 请给class指定完整的包名+类名<br>&nbsp;&nbsp;&nbsp; &nbsp;* @return ${return_type}<br>&nbsp;&nbsp;&nbsp; &nbsp;*&lt;/template&gt;&lt;template name="@hib-rel-one-to-many-list" description="@hibernate.one-to-many relationship" context="javadoc" enabled="true" deleted="false" autoinsert="true"&gt;@hibernate.list name="${enclosing_method}" inverse="true"&nbsp;&nbsp;&nbsp; cascade="save-update" lazy="true"&amp;#13;&nbsp;&nbsp;&nbsp; &nbsp;* @hibernate.collection-key column="外键"&amp;#13;&nbsp;&nbsp;&nbsp; &nbsp;* @hibernate.collection-index column="TABINDEX" type="int"&amp;#13;&nbsp;&nbsp;&nbsp; &nbsp;* @hibernate.collection-one-to-many class="关联的类"&amp;#13;&nbsp;&nbsp;&nbsp;&nbsp; *&amp;#13;&nbsp;&nbsp;&nbsp;&nbsp; * 请修改外键，并且指定完整的关联类的类名（包+类名）&amp;#13;&lt;/template&gt;&lt;template name="@hib-rel-one-to-many-set" description="one 2 many set" context="javadoc" enabled="true" deleted="false" autoinsert="true"&gt;@hibernate.set name="${enclosing_method}" inverse="true"&nbsp;&nbsp;&nbsp; cascade="save-update" lazy="true"&amp;#13;<br>&nbsp;&nbsp;&nbsp; &nbsp;* @hibernate.collection-key column="外键"&amp;#13;<br>&nbsp;&nbsp;&nbsp; &nbsp;* @hibernate.collection-one-to-many class="关联的类"&amp;#13;<br>&nbsp;&nbsp;&nbsp;&nbsp; *&amp;#13;<br>&nbsp;&nbsp;&nbsp;&nbsp; * 请修改外键，并且指定完整的关联类的类名（包+类名）&amp;#13;<br>&lt;/template&gt;&lt;template name="@hib-rel-parent-child-list" description="one to mang [construct a tree]" context="javadoc" enabled="true" deleted="false" autoinsert="true"&gt;@hibernate.list lazy="true" inverse="true" cascade="all"&amp;#13;<br>&nbsp;&nbsp;&nbsp; &nbsp;* @hibernate.collection-key column="parentGuid"&amp;#13;<br>&nbsp;&nbsp;&nbsp; &nbsp;* @hibernate.collection-index column="tabIndex"&amp;#13;<br>&nbsp;&nbsp;&nbsp; &nbsp;* @hibernate.collection-one-to-many class="${enclosing_package}.${primary_type_name}"&amp;#13;<br>&nbsp;&nbsp;&nbsp;&nbsp; *&amp;#13;<br>&nbsp;&nbsp;&nbsp;&nbsp; * 请修改collection-key，它是many方的外键&amp;#13;<br>&nbsp;&nbsp;&nbsp;&nbsp; * tabIndex可以修改，也可以不修改，而且类中不必要一定有这个属性存在，因为它是Hib在操作List时需要的一个属性，只需数据库中定义了即可。&amp;#13;<br>&amp;#13;<br>&lt;/template&gt;&lt;template name="@hib-string-clob" description="hibernate string to clob" context="javadoc" enabled="true" deleted="false" autoinsert="true"&gt;@hibernate.property name="${enclosing_method}" column="ORG_Description" type="org.springframework.orm.hibernate3.support.ClobStringType" not-null="false" unique="false" length="4000"&amp;#13;&lt;/template&gt;&lt;/templates&gt;<br><br>&nbsp;&nbsp;&nbsp;&nbsp; <font color="#000000">如何倒入参考随笔。<br>&nbsp;&nbsp;&nbsp;&nbsp; 代码实例：<br>&nbsp;&nbsp;&nbsp; /**<br>&nbsp;&nbsp;&nbsp; &nbsp;* @hibernate.id generator-class="uuid" type="java.lang.String"<br>&nbsp;&nbsp;&nbsp; &nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; name="guid" column="A_GUID" length="38"<br>&nbsp;&nbsp;&nbsp; &nbsp;* <br>&nbsp;&nbsp;&nbsp; &nbsp;*/<br>&nbsp;&nbsp;&nbsp; public java.lang.String getGuid() {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return orgGuid;<br>&nbsp;&nbsp;&nbsp; }<br><br>&nbsp;&nbsp;&nbsp;&nbsp; private Set childDepartment;<br><br>&nbsp;&nbsp;&nbsp; /**<br>&nbsp;&nbsp;&nbsp; &nbsp;* @hibernate.set lazy="false" cascade="all" lazy="true"<br>&nbsp;&nbsp;&nbsp; &nbsp;* @hibernate.collection-key column="Superior_GUID"<br>&nbsp;&nbsp;&nbsp; &nbsp;* @hibernate.collection-one-to-many class="model.Department"<br>&nbsp;&nbsp;&nbsp; &nbsp;* <br>&nbsp;&nbsp;&nbsp; &nbsp;* @return Set<br>&nbsp;&nbsp;&nbsp; &nbsp;*/<br>&nbsp;&nbsp;&nbsp; public Set getChildDepartment() {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return childDepartment;<br>&nbsp;&nbsp;&nbsp; }<br><br>&nbsp;&nbsp;&nbsp; public void setChildDepartment(Set childDepartment) {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; this.childDepartment = childDepartment;<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; private Set roles;<br>&nbsp;&nbsp;&nbsp; /**<br>&nbsp;&nbsp;&nbsp; &nbsp;* many to may<br>&nbsp;&nbsp;&nbsp; &nbsp;* <br>&nbsp;&nbsp;&nbsp; &nbsp;* @hibernate.set name="roles" table="ORG_DEPT_REF_ROLE"<br>&nbsp;&nbsp;&nbsp; &nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cascade="save-update" inverse="true" lazy="true"<br>&nbsp;&nbsp;&nbsp; &nbsp;* @hibernate.collection-key column="DEPT_GUID"<br>&nbsp;&nbsp;&nbsp; &nbsp;* @hibernate.collection-many-to-many class="model.Role"<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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; column="ROLE_GUID"<br>&nbsp;&nbsp;&nbsp; &nbsp;* @return Set<br>&nbsp;&nbsp;&nbsp; &nbsp;*/<br>&nbsp;&nbsp;&nbsp; public Set getRoles() {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return roles;<br>&nbsp;&nbsp;&nbsp; }<br><br>&nbsp;&nbsp;&nbsp; public void setRoles(Set roles) {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; this.roles = roles;<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; private List positions;<br><br>&nbsp;&nbsp;&nbsp; /**<br>&nbsp;&nbsp;&nbsp; &nbsp;* <br>&nbsp;&nbsp;&nbsp; &nbsp;* @hibernate.list name="positions" inverse="true" cascade="save-update"<br>&nbsp;&nbsp;&nbsp; &nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lazy="true"<br>&nbsp;&nbsp;&nbsp; &nbsp;* @hibernate.collection-key column="DEPT_GUID"<br>&nbsp;&nbsp;&nbsp; &nbsp;* @hibernate.collection-index column="POSITION_TABINDEX" type="int"<br>&nbsp;&nbsp;&nbsp; &nbsp;* @hibernate.collection-one-to-many class="model.Position"<br>&nbsp;&nbsp;&nbsp; &nbsp;* <br>&nbsp;&nbsp;&nbsp; &nbsp;* 请修改外键，并且指定完整的关联类的类名（包+类名）<br>&nbsp;&nbsp;&nbsp; &nbsp;*/<br>&nbsp;&nbsp;&nbsp; public List getPositions() {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return positions;<br>&nbsp;&nbsp;&nbsp; }<br><br>&nbsp;&nbsp;&nbsp; public void setPositions(List positions) {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; this.positions = positions;<br>&nbsp;&nbsp;&nbsp; }<br></font></font><img src ="http://www.blogjava.net/jdyao/aggbug/34910.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jdyao/" target="_blank">西部村里人</a> 2006-03-12 15:13 <a href="http://www.blogjava.net/jdyao/articles/34910.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Hibernate对象关联--UML基础知识、XDoclet---- 4 inverse And Cascading</title><link>http://www.blogjava.net/jdyao/articles/34899.html</link><dc:creator>西部村里人</dc:creator><author>西部村里人</author><pubDate>Sun, 12 Mar 2006 03:16:00 GMT</pubDate><guid>http://www.blogjava.net/jdyao/articles/34899.html</guid><wfw:comment>http://www.blogjava.net/jdyao/comments/34899.html</wfw:comment><comments>http://www.blogjava.net/jdyao/articles/34899.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jdyao/comments/commentRss/34899.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jdyao/services/trackbacks/34899.html</trackback:ping><description><![CDATA[&nbsp;&nbsp; inverse 和 Cascading 在对象关联时，非常重要，官方文档把它分散在几个地方讲解。<br>&nbsp;&nbsp; 下面搜集了多方文章，集中讨论这个问题：<br>&nbsp;&nbsp; 重点是理解：UML中的多向性、导向性与inverse ，cascading之间的关系；以及inverse,cascading对集合行为的影响力。<br>&nbsp; <br><b>一、引用Huihoo翻译Hibernate官方文档</b><br>&nbsp;&nbsp;&nbsp; <font color="#808080"></font><br><h2 class="title" style="clear: both;"><font color="#808080">2.3.&nbsp;
		第二部分 － 关联映射
	</font></h2><p><font color="#808080">
		我们已经映射了一个持久化实体类到一个表上。让我们在这个基础上增加一些类之间的关联性。
		首先我们往我们程序里面增加人（people）的概念，并存储他们所参与的一个Event列表。
		（译者注：与Event一样，我们在后面的教程中将直接使用person来表示“人”而不是它的中文翻译）
        </font></p><div class="sect2" lang="zh-cn"><div class="titlepage"><div><div><h3 class="title"><font color="#808080"><a name="tutorial-associations-mappinguser"></a>2.3.1.&nbsp;
		映射Person类
		</font></h3></div></div></div><p><font color="#808080">
		最初的<tt class="literal">Person</tt>类是简单的：
            </font></p><pre class="programlisting"><font color="#808080">public class Person {<br><br>    private Long id;<br>    private int age;<br>    private String firstname;<br>    private String lastname;<br><br>    Person() {}<br><br>    // Accessor methods for all properties, private setter for 'id'<br><br>}</font></pre><p><font color="#808080">
                Create a new mapping file called <tt class="literal">Person.hbm.xml</tt>:
            </font></p><pre class="programlisting"><font color="#808080">&lt;hibernate-mapping&gt;<br><br>    &lt;class name="Person" table="PERSON"&gt;<br>        &lt;id name="id" column="PERSON_ID"&gt;<br>            &lt;generator class="increment"/&gt;<br>        &lt;/id&gt;<br>        &lt;property name="age"/&gt;<br>        &lt;property name="firstname"/&gt;<br>        &lt;property name="lastname"/&gt;<br>    &lt;/class&gt;<br><br>&lt;/hibernate-mapping&gt;</font></pre><p><font color="#808080">
                Finally, add the new mapping to Hibernate's configuration:
            </font></p><pre class="programlisting"><font color="#808080">        &lt;mapping resource="Event.hbm.xml"/&gt;<br>        &lt;mapping resource="Person.hbm.xml"/&gt;<br></font></pre><p><font color="#808080">
		我们现在将在这两个实体类之间创建一个关联。显然，person可以参与一系列Event，而Event也有不同的参加者（person）。
		设计上面我们需要考虑的问题是关联的方向（directionality），阶数（multiplicity）和集合（collection）的行为。
            </font></p></div><div class="sect2" lang="zh-cn"><div class="titlepage"><div><div><h3 class="title"><font color="#808080"><a name="tutorial-associations-unidirset"></a>2.3.2.&nbsp;
		一个单向的Set-based关联
		</font></h3></div></div></div><p><font color="#808080">
		我们将向<tt class="literal">Person</tt>类增加一组Event。这样我们可以轻松的通过调用<tt class="literal">aPerson.getEvents()</tt>
		得到一个Person所参与的Event列表，而不必执行一个显式的查询。我们使用一个Java的集合类：一个<tt class="literal">Set</tt>，因为Set
		不允许包括重复的元素而且排序和我们无关。
            </font></p><p><font color="#808080">
		 目前为止我们设计了一个单向的，在一端有许多值与之对应的关联，通过<tt class="literal">Set</tt>来实现。
		让我们为这个在Java类里编码并映射这个关联：
            </font></p><pre class="programlisting"><font color="#808080">public class Person {<br><br>    private Set events = new HashSet();<br><br>    public Set getEvents() {<br>        return events;<br>    }<br><br>    public void setEvents(Set events) {<br>        this.events = events;<br>    }<br>}</font></pre><p><font color="#808080">
		在我们映射这个关联之前，先考虑这个关联另外一端。很显然的，我们可以保持这个关联是单向的。如果我们希望这个关联是双向的，
		我们可以在<tt class="literal">Event</tt>里创建另外一个集合，例如：<tt class="literal">anEvent.getParticipants()</tt>。
		这是留给你的一个设计选项，但是从这个讨论中我们可以很清楚的了解什么是关联的阶数（multiplicity）：在这个关联的两端都是“多”。
		我们叫这个为：<span class="emphasis"><em>多对多（many-to-many）</em></span>关联。因此，我们使用Hibernate的many-to-many映射：
            </font></p><pre class="programlisting"><font color="#808080">&lt;class name="Person" table="PERSON"&gt;<br>    &lt;id name="id" column="PERSON_ID"&gt;<br>        &lt;generator class="increment"/&gt;<br>    &lt;/id&gt;<br>    &lt;property name="age"/&gt;<br>    &lt;property name="firstname"/&gt;<br>    &lt;property name="lastname"/&gt;<br><br>    &lt;set name="events" table="PERSON_EVENT"&gt;<br>        &lt;key column="PERSON_ID"/&gt;<br>        &lt;many-to-many column="EVENT_ID" class="Event"/&gt;<br>    &lt;/set&gt;<br><br>&lt;/class&gt;</font></pre><p><font color="#808080">
		 Hibernate支持所有种类的集合映射，<tt class="literal">&lt;set&gt;</tt>是最普遍被使用的。对于多对多（many-to-many）关联(或者叫<span class="emphasis"><em>n:m</em></span>实体关系), 
		需要一个用来储存关联的表（association table）。<tt class="literal">表</tt>里面的每一行代表从一个person到一个event的一个关联。
		表名是由<tt class="literal">set</tt>元素的<tt class="literal">table</tt>属性值配置的。关联里面的标识字段名，person的一端，是
		由<tt class="literal">&lt;key&gt;</tt>元素定义，event一端的字段名是由<tt class="literal">&lt;many-to-many&gt;</tt>元素的
		<tt class="literal">column</tt>属性定义的。你也必须告诉Hibernate集合中对象的类（也就是位于这个集合所代表的关联另外一端的类）。
            </font></p><p><font color="#808080">
		 这个映射的数据库表定义如下：
            </font></p><pre class="programlisting"><font color="#808080">    _____________        __________________<br>   |             |      |                  |       _____________<br>   |   EVENTS    |      |   PERSON_EVENT   |      |             |<br>   |_____________|      |__________________|      |    PERSON   |<br>   |             |      |                  |      |_____________|<br>   | *EVENT_ID   | &lt;--&gt; | *EVENT_ID        |      |             |<br>   |  EVENT_DATE |      | *PERSON_ID       | &lt;--&gt; | *PERSON_ID  |<br>   |  TITLE      |      |__________________|      |  AGE        |<br>   |_____________|                                |  FIRSTNAME  |<br>                                                  |  LASTNAME   |<br>                                                  |_____________|<br> </font></pre></div><div class="sect2" lang="zh-cn"><div class="titlepage"><div><div><h3 class="title"><font color="#808080"><a name="tutorial-associations-working"></a>2.3.3.&nbsp;
		使关联工作
		</font></h3></div></div></div><p><font color="#808080">
		让我们把一些people和event放到<tt class="literal">EventManager</tt>的一个新方法中：
            </font></p><pre class="programlisting"><font color="#808080">private void addPersonToEvent(Long personId, Long eventId) {<br>    Session session = HibernateUtil.currentSession();<br>    Transaction tx = session.beginTransaction();<br><br>    Person aPerson = (Person) session.load(Person.class, personId);<br>    Event anEvent = (Event) session.load(Event.class, eventId);<br><br>    aPerson.getEvents().add(anEvent);<br><br>    tx.commit();<br>    HibernateUtil.closeSession();<br>}</font></pre><p><font color="#808080">
		在加载一个<tt class="literal">Person</tt>和一个<tt class="literal">Event</tt>之后，简单的使用普通的方法修改集合。
		如你所见，没有显式的<tt class="literal">update()</tt>或者<tt class="literal">save()</tt>, Hibernate自动检测到集合已经被修改
		并需要保存。这个叫做<span class="emphasis"><em>automatic dirty checking</em></span>，你也可以尝试修改任何对象的name或者date的参数。
		只要他们处于<span class="emphasis"><em>persistent</em></span>状态，也就是被绑定在某个Hibernate <tt class="literal">Session</tt>上（例如：他们
		刚刚在一个单元操作从被加载或者保存），Hibernate监视任何改变并在后台隐式执行SQL。同步内存状态和数据库的过程，通常只在
		一个单元操作结束的时候发生，这个过程被叫做<span class="emphasis"><em>flushing</em></span>。
            </font></p><p><font color="#808080">
		你当然也可以在不同的单元操作里面加载person和event。或者在一个<tt class="literal">Session</tt>以外修改一个
		不是处在持久化（persistent）状态下的对象（如果该对象以前曾经被持久化，我们称这个状态为<span class="emphasis"><em>脱管（detached）</em></span>）。
		在程序里，看起来像下面这样：
            </font></p><pre class="programlisting"><font color="#808080">    private void addPersonToEvent(Long personId, Long eventId) {<br><br>        Session session = HibernateUtil.currentSession();<br>        Transaction tx = session.beginTransaction();<br><br>        Person aPerson = (Person) session.load(Person.class, personId);<br>        Event anEvent = (Event) session.load(Event.class, eventId);<br><br>        tx.commit();<br>        HibernateUtil.closeSession();<br><br>        aPerson.getEvents().add(anEvent); // aPerson is detached<br><br>        Session session2 = HibernateUtil.currentSession();<br>        Transaction tx2 = session.beginTransaction();<br><br>        session2.update(aPerson); // Reattachment of aPerson<br><br>        tx2.commit();<br>        HibernateUtil.closeSession();<br>    }<br></font></pre><p><font color="#808080">
		对<tt class="literal">update</tt>的调用使一个脱管对象（detached object）重新持久化，你可以说它被绑定到
		一个新的单元操作上，所以任何你对它在脱管（detached）状态下所做的修改都会被保存到数据库里。
            </font></p><p><font color="#808080">
		这个对我们当前的情形不是很有用，但是它是非常重要的概念，你可以把它设计进你自己的程序中。现在，加进一个新的
		选项到<tt class="literal">EventManager</tt>的main方法中，并从命令行运行它来完成这个练习。如果你需要一个person和
		一个event的标识符 － <tt class="literal">save()</tt>返回它。*******这最后一句看不明白
            </font></p><p><font color="#808080">
		上面是一个关于两个同等地位的类间关联的例子，这是在两个实体之间。像前面所提到的那样，也存在其它的特别的类和类型，这些类和类型通常是“次要的”。
		其中一些你已经看到过，好像<tt class="literal">int</tt>或者<tt class="literal">String</tt>。我们称呼这些类为<span class="emphasis"><em>值类型（value type）</em></span>, 
		它们的实例<span class="emphasis"><em>依赖（depend）</em></span>在某个特定的实体上。这些类型的实例没有自己的身份（identity），也不能在实体间共享
		（比如两个person不能引用同一个<tt class="literal">firstname</tt>对象，即使他们有相同的名字）。当然，value types并不仅仅在JDK中存在
		（事实上，在一个Hibernate程序中，所有的JDK类都被视为值类型），你也可以写你自己的依赖类，例如<tt class="literal">Address</tt>，
		<tt class="literal">MonetaryAmount</tt>。
            </font></p><p><font color="#808080">
		你也可以设计一个值类型的集合（collection of value types），这个在概念上与实体的集合有很大的不同，但是在Java里面看起来几乎是一样的。
            </font></p></div><div class="sect2" lang="zh-cn"><div class="titlepage"><div><div><h3 class="title"><font color="#808080"><a name="tutorial-associations-valuecollections"></a>2.3.4.&nbsp;
		值类型的集合
		</font></h3></div></div></div><p><font color="#808080">
		我们把一个值类型对象的集合加入<tt class="literal">Person</tt>。我们希望保存email地址，所以我们使用<tt class="literal">String</tt>，
		而这次的集合类型又是<tt class="literal">Set</tt>：
            </font></p><pre class="programlisting"><font color="#808080">private Set emailAddresses = new HashSet();<br><br>public Set getEmailAddresses() {<br>    return emailAddresses;<br>}<br><br>public void setEmailAddresses(Set emailAddresses) {<br>    this.emailAddresses = emailAddresses;<br>}</font></pre><p>
		<font color="#808080"><tt class="literal">Set</tt>的映射
            </font></p><pre class="programlisting"><font color="#808080">&lt;set name="emailAddresses" table="PERSON_EMAIL_ADDR"&gt;<br>    &lt;key column="PERSON_ID"/&gt;<br>    &lt;element type="string" column="EMAIL_ADDR"/&gt;<br>&lt;/set&gt;</font></pre><p><font color="#808080">
		比较这次和较早先的映射，差别主要在<tt class="literal">element</tt>部分这次并没有包括对其它实体类型的引用，而是使用一个元素类型是
		<tt class="literal">String</tt>的集合（这里使用小写的名字是向你表明它是一个Hibernate的映射类型或者类型转换器）。
		和以前一样，<tt class="literal">set</tt>的<tt class="literal">table</tt>参数决定用于集合的数据库表名。<tt class="literal">key</tt>元素
		定义了在集合表中使用的外键。<tt class="literal">element</tt>元素的<tt class="literal">column</tt>参数定义实际保存<tt class="literal">String</tt>值
		的字段名。
            </font></p><p><font color="#808080">
		看一下修改后的数据库表定义。
            </font></p><pre class="programlisting"><font color="#808080">  _____________        __________________<br> |             |      |                  |       _____________<br> |   EVENTS    |      |   PERSON_EVENT   |      |             |       ___________________<br> |_____________|      |__________________|      |    PERSON   |      |                   |<br> |             |      |                  |      |_____________|      | PERSON_EMAIL_ADDR |<br> | *EVENT_ID   | &lt;--&gt; | *EVENT_ID        |      |             |      |___________________|<br> |  EVENT_DATE |      | *PERSON_ID       | &lt;--&gt; | *PERSON_ID  | &lt;--&gt; |  *PERSON_ID       |<br> |  TITLE      |      |__________________|      |  AGE        |      |  *EMAIL_ADDR      |<br> |_____________|                                |  FIRSTNAME  |      |___________________|<br>                                                |  LASTNAME   |<br>                                                |_____________|<br> </font></pre><p><font color="#808080">
		你可以看到集合表（collection table）的主键实际上是个复合主键，同时使用了2个字段。这也暗示了对于同一个
		person不能有重复的email地址，这正是Java里面使用Set时候所需要的语义（Set里元素不能重复）。
            </font></p><p><font color="#808080">
		  你现在可以试着把元素加入这个集合，就像我们在之前关联person和event的那样。Java里面的代码是相同的。
            </font></p></div><div class="sect2" lang="zh-cn"><div class="titlepage"><div><div><h3 class="title"><font color="#808080"><a name="tutorial-associations-bidirectional"></a>2.3.5.&nbsp;
		双向关联
		</font></h3></div></div></div><p><font color="#808080">
		下面我们将映射一个双向关联（bi-directional association）－ 在Java里面让person和event可以从关联的
		任何一端访问另一端。当然，数据库表定义没有改变，我们仍然需要多对多（many-to-many）的阶数（multiplicity）。一个关系型数据库要比网络编程语言
		更加灵活，所以它并不需要任何像导航方向（navigation direction）的东西 － 数据可以用任何可能的方式进行查看和获取。
            </font></p><p><font color="#808080">
		首先，把一个参与者（person）的集合加入<tt class="literal">Event</tt>类中：
            </font></p><pre class="programlisting"><font color="#808080">private Set participants = new HashSet();<br><br>public Set getParticipants() {<br>    return participants;<br>}<br><br>public void setParticipants(Set participants) {<br>    this.participants = participants;<br>}</font></pre><p><font color="#808080">
		在<tt class="literal">Event.hbm.xml</tt>里面也映射这个关联。
            </font></p><pre class="programlisting"><font color="#808080">&lt;set name="participants" table="PERSON_EVENT" inverse="true"&gt;<br>    &lt;key column="EVENT_ID"/&gt;<br>    &lt;many-to-many column="PERSON_ID" class="Person"/&gt;<br>&lt;/set&gt;</font></pre><p><font color="#808080">
		如你所见，2个映射文件里都有通常的<tt class="literal">set</tt>映射。注意<tt class="literal">key</tt>和<tt class="literal">many-to-many</tt>
		里面的字段名在两个映射文件中是交换的。这里最重要的不同是<tt class="literal">Event</tt>映射文件里<tt class="literal">set</tt>元素的
		<tt class="literal">inverse="true"</tt>参数。
            </font></p><p><font color="#808080">
		这个表示Hibernate需要在两个实体间查找关联信息的时候，应该使用关联的另外一端 － <tt class="literal">Person</tt>类。
		这将会极大的帮助你理解双向关联是如何在我们的两个实体间创建的。
            </font></p></div><div class="sect2" lang="zh-cn"><div class="titlepage"><div><div><h3 class="title"><font color="#808080"><a name="tutorial-associations-usingbidir"></a>2.3.6.&nbsp;
		使双向关联工作
		</font></h3></div></div></div><p><font color="#808080">
		首先，请牢记在心，Hibernate并不影响通常的Java语义。
		在单向关联中，我们是怎样在一个<tt class="literal">Person</tt>和一个<tt class="literal">Event</tt>之间创建联系的？
		我们把一个<tt class="literal">Event</tt>的实例加到一个<tt class="literal">Person</tt>类内的Event集合里。所以，显然如果我们要让这个关联可以双向工作，
		我们需要在另外一端做同样的事情 － 把<tt class="literal">Person</tt>加到一个<tt class="literal">Event</tt>类内的Person集合中。
		这“在关联的两端设置联系”是绝对必要的而且你永远不应该忘记做它。
            </font></p><p><font color="#808080">
		许多开发者通过创建管理关联的方法来保证正确的设置了关联的两端，比如在<tt class="literal">Person</tt>里：
            </font></p><pre class="programlisting"><font color="#808080">protected Set getEvents() {<br>    return events;<br>}<br><br>protected void setEvents(Set events) {<br>    this.events = events;<br>}<br><br>public void addToEvent(Event event) {<br>    this.getEvents().add(event);<br>    event.getParticipants().add(this);<br>}<br><br>public void removeFromEvent(Event event) {<br>    this.getEvents().remove(event);<br>    event.getParticipants().remove(this);<br>}</font></pre><p><font color="#808080">
		注意现在对于集合的get和set方法的访问控制级别是protected - 这允许在位于同一个包（package）中的类以及继承自这个类的子类
		可以访问这些方法，但是禁止其它的直接外部访问，避免了集合的内容出现混乱。你应该尽可能的在集合所对应的另外一端也这样做。
            </font></p><p>
		<font color="#808080"><tt class="literal">inverse</tt>映射参数究竟表示什么呢？对于你和对于Java来说，一个双向关联仅仅是在两端简单的设置引用。然而仅仅这样
		Hibernate并没有足够的信息去正确的产生<tt class="literal">INSERT</tt>和<tt class="literal">UPDATE</tt>语句（以避免违反数据库约束），
		所以Hibernate需要一些帮助来正确的处理双向关联。把关联的一端设置为<tt class="literal">inverse</tt>将告诉Hibernate忽略关联的
		这一端，把这端看成是另外一端的一个<span class="emphasis"><em>镜子（mirror）</em></span>。这就是Hibernate所需的信息，Hibernate用它来处理如何把把
		一个数据导航模型映射到关系数据库表定义。
		你仅仅需要记住下面这个直观的规则：所有的双向关联需要有一端被设置为<tt class="literal">inverse</tt>。在一个一对多（one-to-many）关联中
		它必须是代表多（many）的那端。而在多对多（many-to-many）关联中，你可以任意选取一端，两端之间并没有差别。</font>
            </p></div>&nbsp;&nbsp; <b>二、引用Huihoo翻译Hibernate官方文档<br><br></b><h2 class="title" style="clear: both;"><font color="#808080">22.1.&nbsp;关于collections需要注意的一点</font></h2><p><font color="#808080">    
        Hibernate collections被当作其所属实体而不是其包含实体的一个逻辑部分。这非常重要！它主要体现为以下几点：
    </font></p><div class="itemizedlist"><ul type="disc"><li><p><font color="#808080">
            当删除或增加collection中对象的时候，collection所属者的版本值会递增。
        </font></p></li><li><p><font color="#808080">
如果一个从collection中移除的对象是一个值类型(value type)的实例，比如composite
element，那么这个对象的持久化状态将会终止，其在数据库中对应的记录会被删除。同样的，向collection增加一个value
type的实例将会使之立即被持久化。 </font></p></li><li><p><font color="#808080">
另一方面，如果从一对多或多对多关联的collection中移除一个实体，在缺省情况下这个对象并不会被删除。这个行为是完全合乎逻辑的－－改变一个实
体的内部状态不应该使与它关联的实体消失掉！同样的，向collection增加一个实体不会使之被持久化。 </font></p></li></ul></div><p><font color="#808080">
        实际上，向Collection增加一个实体的缺省动作只是在两个实体之间创建一个连接而已，同样移除的时候也只是删除连接。这种处理对于所有的情况都是合适的。对于父子关系则是完全不适合的，在这种关系下，子对象的生存绑定于父对象的生存周期。
    </font></p><div class="sect1" lang="zh-cn"><div class="titlepage"><div><div><h2 class="title" style="clear: both;"><font color="#808080"><a name="example-parentchild-bidir"></a>22.2.&nbsp;双向的一对多关系(Bidirectional one-to-many)</font></h2></div></div></div><p><font color="#808080">
        假设我们要实现一个简单的从Parent到Child的&lt;one-to-many&gt;关联。
    </font></p><pre class="programlisting"><font color="#808080">&lt;set name="children"&gt;<br>    &lt;key column="parent_id"/&gt;<br>    &lt;one-to-many class="Child"/&gt;<br>&lt;/set&gt;</font></pre><p><font color="#808080">
        如果我们运行下面的代码
    </font></p><pre class="programlisting"><font color="#808080">Parent p = .....;<br>Child c = new Child();<br>p.getChildren().add(c);<br>session.save(c);<br>session.flush();</font></pre><p><font color="#808080">
        Hibernate会产生两条SQL语句：
    </font></p><div class="itemizedlist"><ul type="disc"><li><p><font color="#808080">一条<tt class="literal">INSERT</tt>语句，为<tt class="literal">c</tt>创建一条记录</font></p></li><li><p><font color="#808080">
	    一条<tt class="literal">UPDATE</tt>语句，创建从<tt class="literal">p</tt>到<tt class="literal">c</tt>的连接
        </font></p></li></ul></div><p><font color="#808080">
        这样做不仅效率低，而且违反了列<tt class="literal">parent_id</tt>非空的限制。我们可以通过在集合类映射上指定<tt class="literal">not-null="true"</tt>来解决违反非空约束的问题：
    </font></p><pre class="programlisting"><font color="#808080">&lt;set name="children"&gt;<br>    &lt;key column="parent_id" not-null="true"/&gt;<br>    &lt;one-to-many class="Child"/&gt;<br>&lt;/set&gt;</font></pre><p><font color="#808080">
    	然而，这并非是推荐的解决方法。
   	</font></p><p><font color="#808080">        这种现象的根本原因是从<tt class="literal">p</tt>到<tt class="literal">c</tt>的连接（外键parent_id）没有被当作<tt class="literal">Child</tt>对象状态的一部分，因而没有在INSERT语句中被创建。因此解决的办法就是把这个连接添加到Child的映射中。
    </font></p><pre class="programlisting"><font color="#808080">&lt;many-to-one name="parent" column="parent_id" not-null="true"/&gt;</font></pre><p><font color="#808080">
        （我们还需要为类<tt class="literal">Child</tt>添加<tt class="literal">parent</tt>属性）
    </font></p><p><font color="#808080">
        现在实体<tt class="literal">Child</tt>在管理连接的状态，为了使collection不更新连接，我们使用<tt class="literal">inverse</tt>属性。
    </font></p><pre class="programlisting"><font color="#808080">&lt;set name="children" inverse="true"&gt;<br>    &lt;key column="parent_id"/&gt;<br>    &lt;one-to-many class="Child"/&gt;<br>&lt;/set&gt;</font></pre><p><font color="#808080">
        下面的代码是用来添加一个新的<tt class="literal">Child</tt></font>
    </p><pre class="programlisting"><font color="#808080">Parent p = (Parent) session.load(Parent.class, pid);<br>Child c = new Child();<br>c.setParent(p);<br>p.getChildren().add(c);<br>session.save(c);<br>session.flush();</font></pre><p><font color="#808080">
        现在，只会有一条<tt class="literal">INSERT</tt>语句被执行！
    </font></p><p><font color="#808080">
        为了让事情变得井井有条，可以为<tt class="literal">Parent</tt>加一个<tt class="literal">addChild()</tt>方法。
    </font></p><pre class="programlisting"><font color="#808080">public void addChild(Child c) {<br>    c.setParent(this);<br>    children.add(c);<br>}</font></pre><p><font color="#808080">
        现在，添加<tt class="literal">Child</tt>的代码就是这样
    </font></p><pre class="programlisting"><font color="#808080">Parent p = (Parent) session.load(Parent.class, pid);<br>Child c = new Child();<br>p.addChild(c);<br>session.save(c);<br>session.flush();</font></pre></div><div class="sect1" lang="zh-cn"><div class="titlepage"><div><div><h2 class="title" style="clear: both;"><font color="#808080"><a name="example-parentchild-cascades"></a>22.3.&nbsp;级联生命周期（Cascading lifecycle）</font></h2></div></div></div><p><font color="#808080">
	需要显式调用<tt class="literal">save()</tt>仍然很麻烦，我们可以用级联来解决这个问题。
     </font></p><pre class="programlisting"><font color="#808080">&lt;set name="children" inverse="true" cascade="all"&gt;<br>    &lt;key column="parent_id"/&gt;<br>    &lt;one-to-many class="Child"/&gt;<br>&lt;/set&gt;</font></pre><p><font color="#808080">
         这样上面的代码可以简化为：
     </font></p><pre class="programlisting"><font color="#808080">Parent p = (Parent) session.load(Parent.class, pid);<br>Child c = new Child();<br>p.addChild(c);<br>session.flush();</font></pre><p><font color="#808080">
         同样的，保存或删除<tt class="literal">Parent</tt>对象的时候并不需要遍历其子对象。
         下面的代码会删除对象<tt class="literal">p</tt>及其所有子对象对应的数据库记录。
     </font></p><pre class="programlisting"><font color="#808080">Parent p = (Parent) session.load(Parent.class, pid);<br>session.delete(p);<br>session.flush();</font></pre><p><font color="#808080">
         然而，这段代码
     </font></p><pre class="programlisting"><font color="#808080">Parent p = (Parent) session.load(Parent.class, pid);<br>Child c = (Child) p.getChildren().iterator().next();<br>p.getChildren().remove(c);<br>c.setParent(null);<br>session.flush();</font></pre><p><font color="#808080">
         不会从数据库删除<tt class="literal">c</tt>；它只会删除与<tt class="literal">p</tt>之间的连接（并且会导致违反<tt class="literal">NOT NULL</tt>约束，在这个例子中）。你需要显式调用<tt class="literal">delete()</tt>来删除<tt class="literal">Child</tt>。 
     </font></p><pre class="programlisting"><font color="#808080">Parent p = (Parent) session.load(Parent.class, pid);<br>Child c = (Child) p.getChildren().iterator().next();<br>p.getChildren().remove(c);<br>session.delete(c);<br>session.flush();</font></pre><p><font color="#808080">
         在我们的例子中，如果没有父对象，子对象就不应该存在，如果将子对象从collection中移除，实际上我们是想删除它。要实现这种要求，就必须使用<tt class="literal">cascade="all-delete-orphan"</tt>。
     </font></p><pre class="programlisting"><font color="#808080">&lt;set name="children" inverse="true" cascade="all-delete-orphan"&gt;<br>    &lt;key column="parent_id"/&gt;<br>    &lt;one-to-many class="Child"/&gt;<br>&lt;/set&gt;</font></pre><p><font color="#808080">
         注意：即使在collection一方的映射中指定<tt class="literal">inverse="true"</tt>，级联仍然是通过遍历collection中的元素来处理的。如果你想要通过级联进行子对象的插入、删除、更新操作，就必须把它加到collection中，只调用<tt class="literal">setParent()</tt>是不够的。
     </font></p></div><div class="sect1" lang="zh-cn"><div class="titlepage"><div><div><h2 class="title" style="clear: both;"><font color="#808080"><a name="example-parentchild-update"></a>22.4.&nbsp;级联与<tt class="literal">未保存值</tt>（Cascades and <tt class="literal">unsaved-value</tt>）</font></h2></div></div></div><p><font color="#808080">
         假设我们从<tt class="literal">Session</tt>中装入了一个<tt class="literal">Parent</tt>对象，用户界面对其进行了修改，然后希望在一个新的Session里面调用<tt class="literal">update()</tt>来保存这些修改。对象<tt class="literal">Parent</tt>包含了子对象的集合，由于打开了级联更新，Hibernate需要知道哪些Child对象是新实例化的，哪些代表数据库中已经存在的记录。我们假设<tt class="literal">Parent</tt>和<tt class="literal">Child</tt>对象的标识属性都是自动生成的，类型为<tt class="literal">java.lang.Long</tt>。Hibernate会使用标识属性的值，和version 或 timestamp 属性，来判断哪些子对象是新的。(参见<a href="http://www.huihoo.com/framework/hibernate/reference-v3_zh-cn/objectstate.html#objectstate-saveorupdate" tppabs="http://www.hibernate.org/hib_docs/v3/reference/zh-cn/html/objectstate.html#objectstate-saveorupdate" title="11.7.&nbsp;自动状态检测">第&nbsp;11.7&nbsp;节 “自动状态检测”</a>.) <span class="emphasis"><em>在 Hibernate3 中,显式指定<tt class="literal">unsaved-value</tt>不再是必须的了。</em></span></font>
     </p><p><font color="#808080">
         下面的代码会更新<tt class="literal">parent</tt>和<tt class="literal">child</tt>对象，并且插入<tt class="literal">newChild</tt>对象。
     </font></p><pre class="programlisting"><font color="#808080">//parent and child were both loaded in a previous session<br>parent.addChild(child);<br>Child newChild = new Child();<br>parent.addChild(newChild);<br>session.update(parent);</font><br><br><br><font color="#808080">session.flush();</font></pre><p><font color="#808080">
             Well, that's all very well for the case of a generated identifier, but what about assigned identifiers
             and composite identifiers? This is more difficult, since Hibernate can't use the identifier property to
             distinguish between a newly instantiated object (with an identifier assigned by the user) and an 
             object loaded in a previous session. In this case, Hibernate will either use the timestamp or version 
             property, or will actually query the second-level cache or, worst case, the database, to see if the 
             row exists.
         </font></p><p><font color="#808080">
这对于自动生成标识的情况是非常好的，但是自分配的标识和复合标识怎么办呢？这是有点麻烦，因为Hibernate没有办法区分新实例化的对象（标识被用
户指定了）和前一个Session装入的对象。在这种情况下，Hibernate会使用timestamp或version属性，或者查询第二级缓存，或
者最坏的情况，查询数据库，来确认是否此行存在。</font></p></div>&nbsp;&nbsp; 三、实战总结<br>&nbsp;&nbsp; 1、inverse类似UML图中的导向性.one-many时，如果你设计的类是先整体，后部分，那么整体一端应该inverse为true。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; many-many时，如果其中一端是业务语义的根，另一端的存在依附于根，那么根这一端的inverse为true，否则配置为false.如果两端都配置为true，关联表中就无法写入数据；如果两端都配置为false，你就不能同时a.addB(b),b.addA(a)的方式互相放入对方的集合中，否则会发生冲突。<br>&nbsp;&nbsp; <br>&nbsp;&nbsp; 2、Cascading配置了类之间的行为影响程度。本文引用的第二大节讲的很清楚。在实际使用时，还是要注意其用法与业务的关联：<br>&nbsp;&nbsp;&nbsp; 如果只删除关联关系，通常配置save-update / none<br>&nbsp;&nbsp;&nbsp; 如果把子端全部删除，配置为all。<br>&nbsp;&nbsp; <br>&nbsp; 3、Set在使用时。many-one,删除one时，cascading必须为all。如果是save-update,none都会出现“违反完整约束条件”的错误。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; many-many（A-B)时，A方cascading为all时，删除A类，B、AB关联信息都会被删除。<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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; A方cascading为save-update时，删除A类，AB关联信息会被删除，B保留。<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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; A方cascading为none时,删除A类，B、AB关联信息都会保留。<br>&nbsp; 4、List使用时，首先必须确保index的值必须设置，否则违背了List顺序位置的概念，无法完成删除逻辑的正确性，且会throw“违反完整约束条件”的错误。<br>&nbsp;&nbsp;&nbsp;&nbsp; 在正确给定了index后，其行为与Set相同。<br><img src ="http://www.blogjava.net/jdyao/aggbug/34899.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jdyao/" target="_blank">西部村里人</a> 2006-03-12 11:16 <a href="http://www.blogjava.net/jdyao/articles/34899.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Hibernate对象关联--UML基础知识、XDoclet----2 Hibernate 关联(摘自Huihoo网站)</title><link>http://www.blogjava.net/jdyao/articles/34872.html</link><dc:creator>西部村里人</dc:creator><author>西部村里人</author><pubDate>Sat, 11 Mar 2006 14:22:00 GMT</pubDate><guid>http://www.blogjava.net/jdyao/articles/34872.html</guid><wfw:comment>http://www.blogjava.net/jdyao/comments/34872.html</wfw:comment><comments>http://www.blogjava.net/jdyao/articles/34872.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jdyao/comments/commentRss/34872.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jdyao/services/trackbacks/34872.html</trackback:ping><description><![CDATA[

<p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><a href="http://www.huihoo.com/framework/hibernate/reference-v3_zh-cn/mapping.html">6.
<span lang="EN-US"><span lang="EN-US">对象/</span></span><span lang="EN-US"><span lang="EN-US">关系数据库映射基础(Basic O/R Mapping)</span></span></a><o:p></o:p></span></p>

<p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><a href="http://www.huihoo.com/framework/hibernate/reference-v3_zh-cn/mapping.html#mapping-declaration-manytoone">6.1.10.
<span lang="EN-US"><span lang="EN-US">多对一（many-to-one</span></span><span lang="EN-US"><span lang="EN-US">）</span></span></a><o:p></o:p></span></p>

<p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><a href="http://www.huihoo.com/framework/hibernate/reference-v3_zh-cn/mapping.html#mapping-declaration-onetoone">6.1.11.
<span lang="EN-US"><span lang="EN-US">一对一</span></span></a><o:p></o:p></span></p><p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><a href="http://www.huihoo.com/framework/hibernate/reference-v3_zh-cn/mapping.html#mapping-annotations"><span lang="EN-US"><span lang="EN-US"></span></span></a><o:p></o:p></span></p>

<p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><a href="http://www.huihoo.com/framework/hibernate/reference-v3_zh-cn/collections.html">7.
<span lang="EN-US"><span lang="EN-US">集合类(Collections)</span></span><span lang="EN-US"><span lang="EN-US">映射</span></span></a><o:p></o:p></span></p>

<p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><a href="http://www.huihoo.com/framework/hibernate/reference-v3_zh-cn/collections.html#collections-persistent">7.1.
<span lang="EN-US"><span lang="EN-US">持久化集合类(Persistent collections)</span></span></a><o:p></o:p></span></p>

<p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><a href="http://www.huihoo.com/framework/hibernate/reference-v3_zh-cn/collections.html#collections-mapping">7.2.
<span lang="EN-US"><span lang="EN-US">集合映射（ Collection mappings </span></span><span lang="EN-US"><span lang="EN-US">）</span></span></a><o:p></o:p></span></p>

<p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><a href="http://www.huihoo.com/framework/hibernate/reference-v3_zh-cn/collections.html#collections-foreignkeys">7.2.1.
<span lang="EN-US"><span lang="EN-US">集合外键(Collection foreign keys)</span></span></a><o:p></o:p></span></p>

<p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><a href="http://www.huihoo.com/framework/hibernate/reference-v3_zh-cn/collections.html#collections-elements">7.2.2.
<span lang="EN-US"><span lang="EN-US">集合元<span lang="EN-US">素（Collection elements</span></span></span><span lang="EN-US"><span lang="EN-US">）</span></span></a><o:p></o:p></span></p>

<p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><a href="http://www.huihoo.com/framework/hibernate/reference-v3_zh-cn/collections.html#collections-indexed">7.2.3.
<span lang="EN-US"><span lang="EN-US">索引集合类(Indexed collections)</span></span></a><o:p></o:p></span></p>

<p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><a href="http://www.huihoo.com/framework/hibernate/reference-v3_zh-cn/collections.html#collections-ofvalues">7.2.4.
<span lang="EN-US"><span lang="EN-US">值集合于多对多关联(Collections of values and
many-to-many associations)</span></span></a><o:p></o:p></span></p>

<p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><a href="http://www.huihoo.com/framework/hibernate/reference-v3_zh-cn/collections.html#collections-onetomany">7.2.5.
<span lang="EN-US"><span lang="EN-US">一对多关联（One-to-many Associations</span></span><span lang="EN-US"><span lang="EN-US">）</span></span></a><o:p></o:p></span></p>

<p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><a href="http://www.huihoo.com/framework/hibernate/reference-v3_zh-cn/collections.html#collections-advancedmappings">7.3.
<span lang="EN-US"><span lang="EN-US">高级集合映射（Advanced collection mappings</span></span><span lang="EN-US"><span lang="EN-US">）</span></span></a><o:p></o:p></span></p>

<p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><a href="http://www.huihoo.com/framework/hibernate/reference-v3_zh-cn/collections.html#collections-sorted">7.3.1.
<span lang="EN-US"><span lang="EN-US">有序集合（Sorted collections</span></span><span lang="EN-US"><span lang="EN-US">）</span></span></a><o:p></o:p></span></p>

<p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><a href="http://www.huihoo.com/framework/hibernate/reference-v3_zh-cn/collections.html#collections-bidirectional">7.3.2.
<span lang="EN-US"><span lang="EN-US">双向关联（Bidirectional associations</span></span><span lang="EN-US"><span lang="EN-US">）</span></span></a><o:p></o:p></span></p>

<p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><a href="http://www.huihoo.com/framework/hibernate/reference-v3_zh-cn/collections.html#collections-ternary">7.3.3.
<span lang="EN-US"><span lang="EN-US">三重关联（Ternary associations</span></span><span lang="EN-US"><span lang="EN-US">）</span></span></a><o:p></o:p></span></p>

<p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><a href="http://www.huihoo.com/framework/hibernate/reference-v3_zh-cn/collections.html#collections-idbag">7.3.4.
<span lang="EN-US"><span lang="EN-US">使用&lt;idbag&gt;</span></span></a><o:p></o:p></span></p>

<p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><a href="http://www.huihoo.com/framework/hibernate/reference-v3_zh-cn/collections.html#collections-example">7.4.
<span lang="EN-US"><span lang="EN-US">集合例子（Collection example</span></span><span lang="EN-US"><span lang="EN-US">）</span></span></a><o:p></o:p></span></p>

<p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><a href="http://www.huihoo.com/framework/hibernate/reference-v3_zh-cn/associations.html">8.
<span lang="EN-US"><span lang="EN-US">关联关系映射</span></span></a><o:p></o:p></span></p>

<p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><a href="http://www.huihoo.com/framework/hibernate/reference-v3_zh-cn/associations.html#assoc-intro">8.1.
<span lang="EN-US"><span lang="EN-US">介绍</span></span></a><o:p></o:p></span></p>

<p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><a href="http://www.huihoo.com/framework/hibernate/reference-v3_zh-cn/associations.html#assoc-unidirectional">8.2.
<span lang="EN-US"><span lang="EN-US">单向关联（Unidirectional associations</span></span><span lang="EN-US"><span lang="EN-US">）</span></span></a><o:p></o:p></span></p>

<p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><a href="http://www.huihoo.com/framework/hibernate/reference-v3_zh-cn/associations.html#assoc-unidirectional-m21">8.2.1.
<span lang="EN-US"><span lang="EN-US">多对一(many to one)</span></span></a><o:p></o:p></span></p>

<p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><a href="http://www.huihoo.com/framework/hibernate/reference-v3_zh-cn/associations.html#assoc-unidirectional-121">8.2.2.
<span lang="EN-US"><span lang="EN-US">一对一（one to one</span></span><span lang="EN-US"><span lang="EN-US">）</span></span></a><o:p></o:p></span></p>

<p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><a href="http://www.huihoo.com/framework/hibernate/reference-v3_zh-cn/associations.html#assoc-unidirectional-12m">8.2.3.
<span lang="EN-US"><span lang="EN-US">一对多（one to many</span></span><span lang="EN-US"><span lang="EN-US">）</span></span></a><o:p></o:p></span></p>

<p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><a href="http://www.huihoo.com/framework/hibernate/reference-v3_zh-cn/associations.html#assoc-unidirectional-join">8.3.
<span lang="EN-US"><span lang="EN-US">使用连接表的单向关联（Unidirectional associations with
join tables</span></span><span lang="EN-US"><span lang="EN-US">）</span></span></a><o:p></o:p></span></p>

<p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><a href="http://www.huihoo.com/framework/hibernate/reference-v3_zh-cn/associations.html#assoc-unidirectional-join-12m">8.3.1.
<span lang="EN-US"><span lang="EN-US">一对多(one to many)</span></span></a><o:p></o:p></span></p>

<p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><a href="http://www.huihoo.com/framework/hibernate/reference-v3_zh-cn/associations.html#assoc-unidirectional-join-m21">8.3.2.
<span lang="EN-US"><span lang="EN-US">多对一（many to one</span></span><span lang="EN-US"><span lang="EN-US">）</span></span></a><o:p></o:p></span></p>

<p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><a href="http://www.huihoo.com/framework/hibernate/reference-v3_zh-cn/associations.html#assoc-unidirectional-join-121">8.3.3.
<span lang="EN-US"><span lang="EN-US">一对一（one to one</span></span><span lang="EN-US"><span lang="EN-US">）</span></span></a><o:p></o:p></span></p>

<p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><a href="http://www.huihoo.com/framework/hibernate/reference-v3_zh-cn/associations.html#assoc-unidirectional-join-m2m">8.3.4.
<span lang="EN-US"><span lang="EN-US">多对多（many to many</span></span><span lang="EN-US"><span lang="EN-US">）</span></span></a><o:p></o:p></span></p>

<p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><a href="http://www.huihoo.com/framework/hibernate/reference-v3_zh-cn/associations.html#assoc-bidirectional">8.4.
<span lang="EN-US"><span lang="EN-US">双向关联（Bidirectional associations</span></span><span lang="EN-US"><span lang="EN-US">）</span></span></a><o:p></o:p></span></p>

<p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><a href="http://www.huihoo.com/framework/hibernate/reference-v3_zh-cn/associations.html#assoc-bidirectional-m21">8.4.1.
<span lang="EN-US"><span lang="EN-US">一对多（one to many) / </span></span><span lang="EN-US"><span lang="EN-US">多对一（many to one</span></span><span lang="EN-US"><span lang="EN-US">）</span></span></a><o:p></o:p></span></p>

<p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><a href="http://www.huihoo.com/framework/hibernate/reference-v3_zh-cn/associations.html#assoc-bidirectional-121">8.4.2.
<span lang="EN-US"><span lang="EN-US">一对一（one to one</span></span><span lang="EN-US"><span lang="EN-US">）</span></span></a><o:p></o:p></span></p>

<p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><a href="http://www.huihoo.com/framework/hibernate/reference-v3_zh-cn/associations.html#assoc-bidirectional-join">8.5.
<span lang="EN-US"><span lang="EN-US">使用连接表的双向关联（Bidirectional associations with
join tables</span></span><span lang="EN-US"><span lang="EN-US">）</span></span></a><o:p></o:p></span></p>

<p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><a href="http://www.huihoo.com/framework/hibernate/reference-v3_zh-cn/associations.html#assoc-bidirectional-join-12m">8.5.1.
<span lang="EN-US"><span lang="EN-US">一对多（one to many</span></span><span lang="EN-US"><span lang="EN-US">） /</span></span><span lang="EN-US"><span lang="EN-US">多对一（
many to one</span></span><span lang="EN-US"><span lang="EN-US">）</span></span></a><o:p></o:p></span></p>

<p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><a href="http://www.huihoo.com/framework/hibernate/reference-v3_zh-cn/associations.html#assoc-bidirectional-join-121">8.5.2.
<span lang="EN-US"><span lang="EN-US">一对一（one to one</span></span><span lang="EN-US"><span lang="EN-US">）</span></span></a><o:p></o:p></span></p>

<p class="MsoNormal" style="margin-left: 36pt; text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><a href="http://www.huihoo.com/framework/hibernate/reference-v3_zh-cn/associations.html#assoc-bidirectional-join-m2m">8.5.3.
<span lang="EN-US"><span lang="EN-US">多对多（many to many</span></span><span lang="EN-US"><span lang="EN-US">）</span></span></a><o:p></o:p></span></p>

<img src ="http://www.blogjava.net/jdyao/aggbug/34872.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jdyao/" target="_blank">西部村里人</a> 2006-03-11 22:22 <a href="http://www.blogjava.net/jdyao/articles/34872.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Hibernate对象关联--UML基础知识、XDoclet--- 1 UML基础部分（来自UMLchina网站）</title><link>http://www.blogjava.net/jdyao/articles/34871.html</link><dc:creator>西部村里人</dc:creator><author>西部村里人</author><pubDate>Sat, 11 Mar 2006 14:17:00 GMT</pubDate><guid>http://www.blogjava.net/jdyao/articles/34871.html</guid><wfw:comment>http://www.blogjava.net/jdyao/comments/34871.html</wfw:comment><comments>http://www.blogjava.net/jdyao/articles/34871.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jdyao/comments/commentRss/34871.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jdyao/services/trackbacks/34871.html</trackback:ping><description><![CDATA[<table align="center" border="0" cellpadding="0" cellspacing="0" height="38" width="760">
<tbody>
<tr>
<td align="center" width="129">
<object codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" height="71" width="100"><param name="_cx" value="2646"><param name="_cy" value="1879"><param name="FlashVars" value=""><param name="Movie" value="../images/logo.swf"><param name="Src" value="../images/logo.swf"><param name="WMode" value="Window"><param name="Play" value="-1"><param name="Loop" value="-1"><param name="Quality" value="High"><param name="SAlign" value=""><param name="Menu" value="-1"><param name="Base" value=""><param name="AllowScriptAccess" value=""><param name="Scale" value="ShowAll"><param name="DeviceFont" value="0"><param name="EmbedMovie" value="0"><param name="BGColor" value=""><param name="SWRemote" value=""><param name="MovieData" value=""><param name="SeamlessTabbing" value="1"><param name="Profile" value="0"><param name="ProfileAddress" value=""><param name="ProfilePort" value="0">
                              <embed src="../images/logo.swf" quality="high" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" height="71" width="100"></object><br></td>
<td width="631"><b><font color="#008080" size="6">UML</font><font color="#008080"><font color="#008080" face="方正姚体" size="6">软件工程</font><font face="方正姚体" size="6">组织</font></font></b> 
<table align="right" border="0" width="60%">
<tbody>
<tr>
<td>
<div align="center"><a class="content_a" href="http://www.uml.net.cn/" target="_blank">　　　　北京火龙果软件工程技术中心</a></div></td></tr></tbody></table></td></tr></tbody></table>
<hr noshade="noshade" size="1" width="760">

<table align="center" border="0" cellpadding="0" cellspacing="0" width="760">
<tbody>
<tr>
<td class="title" align="center" height="56" valign="center"><b><font color="#ff0000" size="3">UML 基础：类图 </font></b></td></tr>
<tr>
<td class="formtitle" align="center" height="40">选自：IBM</td></tr></tbody></table>
<table align="center" border="0" cellpadding="0" cellspacing="0" height="65" width="760">
<tbody>
<tr>
<td class="content" height="65">
<table class="content" align="center" border="0" width="85%">
<tbody>
<tr>
<td class="content" valign="top"><span class="content">这是关于统一建模语言、即UML 
里采用的基本图的一系列文章的一部分。在我 先前关于序列图的文章 里，我把重点从 UML 1.4 版，转移到 OMG的采用UML 2.0版草案规范（又称为UML 
2）。在这篇文章中，我将会讨论结构图，这是已经在 UML 2 
中提出的一种新图种类。由于本系列文章的目的是使人们了解记号元素及它们的含意，该文主要关注类图。你很快就会知道这样做的理由。随后的文章将会覆盖结构范畴中包含的其它图。 
</span>
<p class="content">我也想提醒读者，这一系列文章是关于 UML 
记号元素的，所以这些文章并不意味着为建模的最好方式提供指导方针，或是该如何决定哪些内容应该首先被建模。相反的，该文及本系列文章的目的主要是帮助大家对于记号元素 
-- 语法和含义有一个基本的理解。借由这些知识，你应该可以阅读图，并使用正确的记号元素创建你自己的图。</p>
<p class="content">这篇文章假定你对面向对象的设计已经有了基本的理解。你们当中如果有人需要一些面向对象概念的帮助，那么可以访问http://java.sun.com/docs/books/tutorial/java/concepts/，来获得Sun公司关于面向对象编程的简短指导。<i xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">阅读</i> “什么是类？”和 
什么是继承？” 章节，将提供给你足够的理解，并对该文的阅读会有所帮助。另外，David Taylor的书《 Object-Oriented 
Technologies: A Manager's Guide》提供了面向对象设计的优秀，高水平的说明，而无需对计算机编程有高深的理解。</p>
<p class="content"><a name="IDAATMUB">UML 2 中的阴和阳</a><br>在 UML 2 
中有二种基本的图范畴：结构图和行为图。每个 UML 
图都属于这二个图范畴。结构图的目的是显示建模系统的静态结构。它们包括类，组件和（或）对象图。另一方面，行为图显示系统中的对象的动态行为，包括如对象的方法，协作和活动之类的内容。行为图的实例是活动图，用例图和序列图。</p>
<p class="content"><a name="IDAITMUB">大体上的结构图</a><br>如同我所说的，结构图显示建模系统的静态结构。关注系统的元件，无需考虑时间。在系统内，静态结构通过显示类型和它们的实例进行传播。除了显示系统类型和它们的实例，结构图至少也显示了这些元素间的一些关系，可能的话，甚至也显示它们的内部结构。</p>
<p class="content">贯穿整个软件生命周期，结构图对于各种团队成员都是有用的。一般而言，这些图支持设计验证，和个体与团队间的设计交流。举例来说，业务分析师可以使用类或对象图，来为当前的资产和资源建模，例如分类账，产品或地理层次。架构师可以使用组件和部署图，来测试/确认他们的设计是否充分。开发者可以使用类图，来设计并为系统的代码（或即将成为代码的）类写文档。</p><span class="content"><b xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">特殊的类图</b> 
</span>
<p class="content">UML 2 
把结构图看成一个分类；这里并不存在称为“结构图”的图。然而，类图提供结构图类型的一个主要实例，并为我们提供一组记号元素的初始集，供所有其它结构图使用。由于类图是如此基本，本文的剩余部分将会把重点集中在类图记号集。在本文的结尾，你将对于如何画UML 
2类图有所了解，而且对于理解在后面文章中将涉及的其他结构图有一个稳固的基础。</p>
<p class="content"><a name="IDATTMUB">基础</a><br>如先前所提到的，类图的目的是显示建模系统的类型。在大多数的 UML 
模型中这些类型包括：</p>
<ul xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><li class="content">类<br><br>
</li><li class="content">接口<br><br>
</li><li class="content">数据类型<br><br>
</li><li class="content">组件 </li></ul>
<p class="content">UML 
为这些类型起了一个特别的名字：“分类器”。通常地，你可以把分类器当做类，但在技术上，分类器是更为普遍的术语，它还是引用上面的其它三种类型为好。</p>
<p class="content"><b xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">类名</b></p>
<p class="content">类的 UML 表示是一个长方形，垂直地分为三个区，如图 1 
所示。顶部区域显示类的名字。中间的区域列出类的属性。底部的区域列出类的操作。当在一个类图上画一个类元素时，你必须要有顶端的区域，下面的二个区域是可选择的（当图描述仅仅用于显示分类器间关系的高层细节时，下面的两个区域是不必要的）。图 
1 显示一个航线班机如何作为 UML 类建模。正如我们所能见到的，名字是 <i xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">Flight</i>，我们可以在中间区域看到Flight类的3个属性：flightNumber，departureTime 
和 flightDuration。在底部区域中我们可以看到Flight类有两个操作：delayFlight 和 getArrivalTime。</p><span class="content"><img alt="图 1: Flight类的类图" src="http://www.uml.org.cn/oobject/images/bell_fig1.jpg" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" border="0" height="128" width="288"> </span>
<p class="content"><b xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">图 1: 
Flight类的类图</b></p>
<p class="content">　</p>
<p class="content"><b xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">类属性列表</b></p>
<p class="content">类的属性节（中部区域）在分隔线上列出每一个类的属性。属性节是可选择的，要是一用它，就包含类的列表显示的每个属性。该线用如下格式：</p>
<blockquote xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<table bgcolor="#cccccc" border="1" cellpadding="5" cellspacing="0" width="400">
<tbody>
<tr>
<td><pre class="content"><code>name : attribute type</code></pre></td></tr></tbody></table></blockquote>
<blockquote xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<table bgcolor="#cccccc" border="1" cellpadding="5" cellspacing="0" width="400">
<tbody>
<tr>
<td><pre class="content"><code>flightNumber : Integer</code></pre></td></tr></tbody></table></blockquote>
<p class="content">继续我们的Flight类的例子，我们可以使用属性类型信息来描述类的属性，如表 1 所示。</p>
<p class="content"><b xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">表 
1：具有关联类型的Flight类的属性名字</b></p>
<table border="0" width="100%">
<tbody>
<tr>
<td bgcolor="#000000">
<table border="0" width="100%">
<tbody>
<tr bgcolor="#cccccc">
<td class="content">属性名称</td>
<td class="content">属性类型</td></tr>
<tr bgcolor="#ffff99">
<td class="content">flightNumber</td>
<td class="content">Integer</td></tr>
<tr bgcolor="#ffff99">
<td class="content">departureTime</td>
<td class="content">Date</td></tr>
<tr bgcolor="#ffff99">
<td class="content">flightDuration</td>
<td class="content">Minutes</td></tr></tbody></table></td></tr></tbody></table>
<p class="content">在业务类图中，属性类型通常与单位相符，这对于图的可能读者是有意义的（例如，分钟，美元，等等）。然而，用于生成代码的类图，要求类的属性类型必须限制在由程序语言提供的类型之中，或包含于在系统中实现的、模型的类型之中。</p>
<p class="content">在类图上显示具有默认值的特定属性，有时是有用的（例如，在银行账户应用程序中，一个新的银行账户会以零为初始值）。UML 
规范允许在属性列表节中，通过使用如下的记号作为默认值的标识：</p>
<blockquote xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<table bgcolor="#cccccc" border="1" cellpadding="5" cellspacing="0" width="400">
<tbody>
<tr>
<td><pre class="content"><code>name : attribute type = default value</code></pre></td></tr></tbody></table></blockquote>
<p class="content">举例来说：</p>
<blockquote xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<table bgcolor="#cccccc" border="1" cellpadding="5" cellspacing="0" width="400">
<tbody>
<tr>
<td><pre class="content"><code>balance : Dollars = 0</code></pre></td></tr></tbody></table></blockquote>
<p class="content">显示属性默认值是可选择的；图 2 显示一个银行账户类具有一个名为 <i xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">balance</i>的类型，它的默认值为0。</p><span class="content"><img alt="图 2：显示默认为0美元的balance属性值的银行账户类图。" src="http://www.uml.org.cn/oobject/images/bell_fig2.jpg" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" border="0" height="113" width="212"> </span>
<p class="content"><b xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">图 
2：显示默认为0美元的balance属性值的银行账户类图。</b></p>
<p class="content">　</p>
<p class="content"><b xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">类操作列表</b></p>
<p class="content">类操作记录在类图长方形的第三个（最低的）区域中，它也是可选择的。和属性一样，类的操作以列表格式显示，每个操作在它自己线上。操作使用下列记号表现：</p>
<blockquote xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<table bgcolor="#cccccc" border="1" cellpadding="5" cellspacing="0" width="400">
<tbody>
<tr>
<td><pre class="content"><code>	name(parameter list) : type of value returned</code></pre></td></tr></tbody></table></blockquote>
<p class="content">下面的表 2 中Flight类操作的映射。</p>
<p class="content"><b xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">表 2：从图 
2 映射的Flight类的操作</b></p>
<table border="0" width="100%">
<tbody>
<tr>
<td bgcolor="#000000">
<table border="0" width="100%">
<tbody>
<tr align="left" bgcolor="#cccccc" valign="top">
<td class="content"><b xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">操作名称</b></td>
<td class="content"><b xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">返回参数</b></td>
<td class="content"><b xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">值类型</b></td></tr>
<tr align="left" bgcolor="#ffff99" valign="top">
<td class="content">delayFlight</td>
<td>
<table border="0" cellpadding="5" cellspacing="2" width="100%">
<tbody>
<tr>
<td class="content"><b xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">Name</b></td>
<td class="content"><b xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">Type</b></td></tr>
<tr>
<td class="content">numberOfMinutes</td>
<td class="content">Minutes</td></tr></tbody></table></td>
<td class="content">N/A</td></tr>
<tr align="left" bgcolor="#ffff99" valign="top">
<td class="content">getArrivalTime</td>
<td class="content">N/A</td>
<td class="content">Date</td></tr></tbody></table></td></tr></tbody></table>
<p class="content">图3显示，delayFlight 操作有一个Minutes类型的输入参数 -- 
numberOfMinutes。然而，delayFlight 操作没有返回值。<a href="http://www.uml.org.cn/oobject/200503075.htm#notes" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><sup>1</sup></a> 
当一个操作有参数时，参数被放在操作的括号内；每个参数都使用这样的格式：“参数名：参数类型”。</p><span class="content"><img alt="图 3：Flight类操作参数，包括可选择的“in”标识。" src="http://www.uml.org.cn/oobject/images/bell_fig3.jpg" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" border="0" height="129" width="279"> </span>
<p class="content"><b xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">图 
3：Flight类操作参数，包括可选择的“in”标识。</b></p>
<p class="content">　</p>
<p class="content">当文档化操作参数时，你可能使用一个可选择的指示器，以显示参数到操作的输入参数、或输出参数。这个可选择的指示器以“in”或“out”出现，如图3中的操作区域所示。一般来说，除非将使用一种早期的程序编程语言，如Fortran 
，这些指示器可能会有所帮助，否则它们是不必要的。然而，在 
C++和Java中，所有的参数是“in”参数，而且按照UML规范，既然“in”是参数的默认类型，大多数人将会遗漏输入/输出指示器。</p>
<p class="content"><b xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">继承</b></p>
<p class="content">在面向对象的设计中一个非常重要的概念，<i xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">继承</i>，指的是一个类（子类）<i xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">继承</i>另外的一个类（超类）的同一功能，并增加它自己的新功能（一个非技术性的比喻，想象我继承了我母亲的一般的音乐能力，但是在我的家里，我是唯一一个玩电吉他的人）的能力。为了在一个类图上建模继承，从子类（要继承行为的类）拉出一条闭合的，单键头（或三角形）的实线指向超类。考虑银行账户的类型：图 
4 显示 CheckingAccount 和 SavingsAccount 类如何从 BankAccount 类继承而来。</p><span class="content"><img alt="图 4: 继承通过指向超类的一条闭合的，单箭头的实线表示。" src="http://www.uml.org.cn/oobject/images/bell_fig4.jpg" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" border="0" height="335" width="563"> </span>
<p class="content"><b xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">图 4: 
继承通过指向超类的一条闭合的，单箭头的实线表示。</b></p>
<p class="content">　</p>
<p class="content">在图 4 中，继承关系由每个超类的单独的线画出，这是在IBM Rational Rose和IBM Rational 
XDE中使用的方法。然而，有一种称为 <i xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">树标记</i>的备选方法可以画出继承关系。当存在两个或更多子类时，如图 
4 中所示，除了继承线象树枝一样混在一起外，你可以使用树形记号。图 5 是重绘的与图 4 一样的继承，但是这次使用了树形记号。</p><span class="content"><img alt="图 5: 一个使用树形记号的继承实例" src="http://www.uml.org.cn/oobject/images/bell_fig5.jpg" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" border="0" height="335" width="563"> </span>
<p class="content"><b xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">图 5: 
一个使用树形记号的继承实例</b></p>
<p class="content">　</p>
<p class="content"><b xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">抽象类及操作</b><br xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">细心的读者会注意到，在图 4 和 图5 
中的图中,类名BankAccount和withdrawal操作使用斜体。这表示，BankAccount 
类是一个抽象类，而withdrawal方法是抽象的操作。换句话说，BankAccount 
类使用withdrawal规定抽象操作，并且CheckingAccount 和 SavingsAccount 两个子类都分别地执行它们各自版本的操作。</p>
<p class="content">然而，超类（父类）不一定要是抽象类。标准类作为超类是正常的。</p>
<p class="content"><b xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">关联</b><br xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">当你系统建模时，特定的对象间将会彼此关联，而且这些关联本身需要被清晰地建模。有五种关联。在这一部分中，我将会讨论它们中的两个 
-- 双向的关联和单向的关联，而且我将会在<i xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">Beyond the 
basics</i>部分讨论剩下的三种关联类型。请注意，关于何时该使用每种类型关联的详细讨论，不属于本文的范围。相反的，我将会把重点集中在每种关联的用途，并说明如何在类图上画出关联。</p>
<p class="content"><b xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">双向（标准）的关联</b><br xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">关联是两个类间的联接。关联总是被假定是双向的；这意味着，两个类彼此知道它们间的联系，除非你限定一些其它类型的关联。回顾一下Flight 
的例子，图 6 显示了在Flight类和Plane类之间的一个标准类型的关联。</p><span class="content"><img alt="图 6：在一个Flight类和Plane类之间的双向关联的实例" src="http://www.uml.org.cn/oobject/images/bell_fig6.jpg" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" border="0" height="172" width="680"> </span>
<p class="content"><b xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">图 
6：在一个Flight类和Plane类之间的双向关联的实例</b></p>
<p class="content">　</p>
<p class="content">一个双向关联用两个类间的实线表示。在线的任一端，你放置一个角色名和多重值。图 6 
显示Flight与一个特定的Plane相关联，而且Flight类知道这个关联。因为角色名以Plane类表示，所以Plane承担关联中的“assignedPlane”角色。紧接于Plane类后面的多重值描述0...1表示，当一个Flight实体存在时，可以有一个或没有Plane与之关联（也就是，Plane可能还没有被分配）。图 
6 也显示Plane知道它与Flight类的关联。在这个关联中，Flight承担“assignedFlights”角色；图 6 
的图告诉我们，Plane实体可以不与flight关联（例如，它是一架全新的飞机）或与没有上限的flight（例如，一架已经服役5年的飞机）关联。</p>
<p class="content">由于对那些在关联尾部可能出现的多重值描述感到疑惑，下面的表3列出了一些多重值及它们含义的例子。</p>
<p class="content"><b xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">表 3: 
多重值和它们的表示</b></p>
<table border="0">
<tbody>
<tr>
<td bgcolor="#000000">
<table border="0" cellpadding="5" cellspacing="2" width="100%">
<tbody>
<tr bgcolor="#cccccc">
<td class="content" colspan="2">可能的多重值描述</td></tr>
<tr bgcolor="#ffff99">
<td class="content">表示</td>
<td class="content">含义</td></tr>
<tr bgcolor="#ffff99">
<td class="content">0..1</td>
<td class="content">0个或1个</td></tr>
<tr bgcolor="#cccccc">
<td class="content">1</td>
<td class="content">只能1个</td></tr>
<tr bgcolor="#cccccc">
<td class="content">0..*</td>
<td class="content">0个或多个</td></tr>
<tr bgcolor="#cccccc">
<td class="content">*</td>
<td class="content">0个或多个</td></tr>
<tr bgcolor="#cccccc">
<td class="content">1..*</td>
<td class="content">1个或我个</td></tr>
<tr bgcolor="#cccccc">
<td class="content">3</td>
<td class="content">只能3个</td></tr>
<tr bgcolor="#cccccc">
<td class="content">0..5</td>
<td class="content">0到5个</td></tr>
<tr bgcolor="#cccccc">
<td class="content">5..15</td>
<td class="content">5到15个</td></tr></tbody></table></td></tr></tbody></table>
<p class="content"><b xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">单向关联</b><br xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">在一个单向关联中，两个类是相关的，但是只有一个类知道这种联系的存在。图 
7 显示单向关联的透支财务报告的一个实例。</p><span class="content"><img alt="图 7: 单向关联一个实例：OverdrawnAccountsReport 类 BankAccount 类，而 BankAccount 类则对关联一无所知。" src="http://www.uml.org.cn/oobject/images/bell_fig7.jpg" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" border="0" height="113" width="600"> </span>
<p class="content"><b xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">图 7: 
单向关联一个实例：OverdrawnAccountsReport 类 BankAccount 类，而 BankAccount 
类则对关联一无所知。</b></p>
<p class="content">　</p>
<p class="content">一个单向的关联，表示为一条带有指向已知类的开放箭头（不关闭的箭头或三角形，用于标志继承）的实线。如同标准关联，单向关联包括一个角色名和一个多重值描述，但是与标准的双向关联不同的时，单向关联只包含已知类的角色名和多重值描述。在图 
7 中的例子中，OverdrawnAccountsReport 知道 BankAccount 类，而且知道 BankAccount 
类扮演“overdrawnAccounts”的角色。然而，和标准关联不同，BankAccount 类并不知道它与 OverdrawnAccountsReport 
相关联。<a href="http://www.uml.org.cn/oobject/200503075.htm#notes" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><sup>2</sup></a></p>
<p class="content"><b xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">软件包</b><br xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">不可避免，如果你正在为一个大的系统或大的业务领域建模，在你的模型中将会有许多不同的分类器。管理所有的类将是一件令人生畏的任务；所以，UML 
提供一个称为 <i xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">软件包</i>的组织元素。软件包使建模者能够组织模型分类器到名字空间中，这有些象文件系统中的文件夹。把一个系统分为多个软件包使系统变成容易理解，尤其是在每个软件包都表现系统的一个特定部分时。<a href="http://www.uml.org.cn/oobject/200503075.htm#notes" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><sup>3</sup></a></p>
<p class="content">在图中存在两种方法表示软件包。并没有规则要求使用哪种标记，除了用你个人的判断：哪种更便于阅读你画的类图。两种方法都是由一个较小的长方形（用于定位）嵌套在一个大的长方形中开始的，如图 
8 所示。但是建模者必须决定包的成员如何表示，如下：</p>
<ul xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><li class="content">如果建模者决定在大长方形中显示软件包的成员，则所有的那些成员<a href="http://www.uml.org.cn/oobject/200503075.htm#notes"><sup>4</sup></a> 
需要被放置在长方形里面。另外，所有软件包的名字需要放在软件包的较小长方形之内（如图 8 的显示）。<br><br>
</li><li class="content">如果建模者决定在大的长方形之外显示软件包成员，则所有将会在图上显示的成员都需要被置于长方形之外。为了显示属于软件包的分类器属于，从每个分类器画一条线到里面有加号的圆周，这些圆周粘附在软件包之上（图9）。 
</li></ul><span class="content"><img alt="图 8：在软件包的长方形内显示软件包成员的软件包元素例子" src="http://www.uml.org.cn/oobject/images/bell_fig8.jpg" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" border="0" height="410" width="576"> </span>
<p class="content"><b xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">图 
8：在软件包的长方形内显示软件包成员的软件包元素例子</b></p>
<p class="content">　</p><span class="content"><img alt="图 9：一个通过连接线表现软件包成员的软件包例子" src="http://www.uml.org.cn/oobject/images/bell_fig9.jpg" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" border="0" height="622" width="551"> </span>
<p class="content"><b xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">图 
9：一个通过连接线表现软件包成员的软件包例子</b></p>
<p class="content">　</p>
<p class="content"><b xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">了解基础重要性</b></p>
<p class="content">在 UML 2 
中，了解类图的基础更为重要。这是因为类图为所有的其他结构图提供基本的构建块。如组件或对象图（仅仅是举了些例子）。</p>
<p class="content"><a name="IDAQ4RUB">超过基础</a><br>到此为止，我已经介绍了类图的基础，但是请继续往下读！在下面的部分中，我将会引导你到你会使用的类图的更重要的方面。这些包括UML 
2 规范中的接口，其它的三种关联类型，可见性和其他补充。</p>
<p class="content"><b xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">接口</b><br xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">在本文的前面，我建议你以类来考虑<i xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">分类器</i>。事实上，分类器是一个更为一般的概念，它包括数据类型和接口。</p>
<p class="content">关于何时、以及如何高效地在系统结构图中使用数据类型和接口的完整讨论，不在本文的讨论范围之内。既然这样，我为什么要在这里提及数据类型和接口呢？你可能想在结构图上模仿这些分类器类型，在这个时候，使用正确的记号来表示，或者至少知道这些分类器类型是重要的。不正确地绘制这些分类器，很有可能将使你的结构图读者感到混乱，以后的系统将不能适应需求。</p>
<p class="content">一个类和一个接口不同：一个类可以有它形态的真实实例，然而一个接口必须至少有一个类来实现它。在 UML 2 
中，一个接口被认为是类建模元素的特殊化。因此，接口就象类那样绘制，但是长方形的顶部区域也有文本“interface”，如图 10 所示。<a href="http://www.uml.org.cn/oobject/200503075.htm#notes" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><sup>5</sup></a></p><span class="content"><img alt="图 10：Professor类和Student类实现Person接口的类图实例" src="http://www.uml.org.cn/oobject/images/bell_fig10.gif" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" border="0" height="262" width="325"> </span>
<p class="content"><b xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">图 
10：Professor类和Student类实现Person接口的类图实例</b></p>
<p class="content">　</p>
<p class="content">在图 10 
中显示的图中，Professor和Student类都实现了Person的接口，但并不从它继承。我们知道这一点是由于下面两个原因：1) 
Person对象作为接口被定义 -- 
它在对象的名字区域中有“interface”文本，而且我们看到由于Professor和Student对象根据画类对象的规则（在它们的名字区域中没有额外的分类器文本）标示，所以它们是 
<i xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">类</i>对象。 2) 
我们知道继承在这里没有被显示，因为与带箭头的线是点线而不是实线。如图 10 所示，一条带有闭合的单向箭头的<i xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">点</i> 线意味着实现（或实施）；正如我们在图 4 
中所见到的，一条带有闭合单向箭头的<i xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">实</i>线表示继承。</p>
<p class="content"><b xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">更多的关联</b><br xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">在上面，我讨论了双向关联和单向关联。现在，我将会介绍剩下的三种类型的关联。</p>
<p class="content"><b xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">关联类</b><br xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">在关联建模中，存在一些情况下，你需要包括其它类，因为它包含了关于关联的有价值的信息。对于这种情况，你会使用 
<i xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">关联类</i> 
来绑定你的基本关联。关联类和一般类一样表示。不同的是，主类和关联类之间用一条相交的点线连接。图 11 显示一个航空工业实例的关联类。</p><span class="content"><img alt="图 11：增加关联类 MileageCredit" src="http://www.uml.org.cn/oobject/images/bell_fig11.jpg" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" border="0" height="235" width="731"> </span>
<p class="content"><b xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">图 
11：增加关联类 MileageCredit</b></p>
<p class="content">　</p>
<p class="content">在图 11 中显示的类图中，在Flight类和 FrequentFlyer 类之间的关联，产生了称为 
MileageCredit的关联类。这意味当Flight类的一个实例关联到 FrequentFlyer 类的一个实例时，将会产生 MileageCredit 
类的一个实例。</p>
<p class="content"><b xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">聚合</b><br xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">聚合是一种特别类型的关联，用于描述“总体到局部”的关系。在基本的聚合关系中， 
<i xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">部分类</i> 的生命周期独立于 <i xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">整体类</i> 的生命周期。</p>
<p class="content">举例来说，我们可以想象，<i xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">车</i> 是一个整体实体，而 <i xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">车轮</i> 
轮胎是整辆车的一部分。轮胎可以在安置到车时的前几个星期被制造，并放置于仓库中。在这个实例中，Wheel类实例清楚地独立地Car类实例而存在。然而，有些情况下， 
<i xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">部分</i> 类的生命周期并 <i xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">不</i> 独立于 <i xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">整体</i> 类的生命周期 -- 
这称为合成聚合。举例来说，考虑公司与部门的关系。 <i xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">公司和部门</i> 
都建模成类，在公司存在之前，部门不能存在。这里Department类的实例依赖于Company类的实例而存在。</p>
<p class="content">让我们更进一步探讨基本聚合和组合聚合。</p>
<p class="content"><b xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><i>基本聚合</i></b><br xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">有聚合关系的关联指出，某个类是另外某个类的一部分。在一个聚合关系中，子类实例可以比父类存在更长的时间。为了表现一个聚合关系，你画一条从父类到部分类的实线，并在父类的关联末端画一个未填充棱形。图 
12 显示车和轮胎间的聚合关系的例子。</p><span class="content"><img alt="图 12: 一个聚合关联的例子" src="http://www.uml.org.cn/oobject/images/bell_fig12.jpg" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" border="0" height="49" width="291"> </span>
<p class="content"><b xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">图 12: 
一个聚合关联的例子</b></p>
<p class="content">　</p>
<p class="content"><b xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><i>组合聚合</i></b><br xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">组合聚合关系是聚合关系的另一种形式，但是子类实例的生命周期依赖于父类实例的生命周期。在图13中，显示了Company类和Department类之间的组合关系，注意组合关系如聚合关系一样绘制，不过这次菱形是被填充的。</p><span class="content"><img alt="图 13: 一个组合关系的例子" src="http://www.uml.org.cn/oobject/images/bell_fig13.jpg" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" border="0" height="47" width="341"> </span>
<p class="content"><b xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">图 13: 
一个组合关系的例子</b></p>
<p class="content">　</p>
<p class="content">在图 13 
中的关系建模中，一个Company类实例至少总有一个Department类实例。因为关系是组合关系，当Company实例被移除/销毁时，Department实例也将自动地被移除/销毁。组合聚合的另一个重要功能是部分类只能与父类的实例相关（举例来说，我们例子中的Company类）。</p>
<p class="content"><b xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">反射关联</b><br xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">现在我们已经讨论了所有的关联类型。就如你可能注意到的，我们的所有例子已经显示了两个不同类之间的关系。然而，类也可以使用反射关联与它本身相关联。起先，这可能没有意义，但是记住，类是抽象的。图 
14 显示一个Employee类如何通过manager / 
manages角色与它本身相关。当一个类关联到它本身时，这并不意味着类的实例与它本身相关，而是类的一个实例与类的另一个实例相关。</p><span class="content"><img alt="图 14：一个反射关联关系的实例" src="http://www.uml.org.cn/oobject/images/bell_fig14.gif" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" border="0" height="114" width="193"> </span>
<p class="content"><b xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">图 
14：一个反射关联关系的实例</b></p>
<p class="content">　</p>
<p class="content">图 14 
描绘的关系说明一个Employee实例可能是另外一个Employee实例的经理。然而，因为“manages”的关系角色有 
0..*的多重性描述；一个雇员可能不受任何其他雇员管理。</p>
<p class="content"><b xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">可见性</b><br xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">在面向对象的设计中，存在属性及操作可见性的记号。UML 
识别四种类型的可见性：public，protected，private及package。</p>
<p class="content">UML 
规范并不要求属性及操作可见性必须显示在类图上，但是它要求为每个属性及操作定义可见性。为了在类图上的显示可见性，放置可见性标志于属性或操作的名字之前。虽然 UML 
指定四种可见性类型，但是实际的编程语言可能增加额外的可见性，或不支持 UML 定义的可见性。表4显示了 UML 支持的可见性类型的不同标志。</p>
<p class="content"><b xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">表 
4：UML 支持的可见性类型的标志</b></p>
<table border="0" width="100%">
<tbody>
<tr>
<td bgcolor="#000000">
<table border="0" width="100%">
<tbody>
<tr bgcolor="#cccccc">
<td class="content">标志</td>
<td class="content">可见性类型</td></tr>
<tr bgcolor="#ffff99">
<td class="content">+</td>
<td class="content">Public</td></tr>
<tr bgcolor="#ffff99">
<td class="content">#</td>
<td class="content">Protected</td></tr>
<tr bgcolor="#ffff99">
<td class="content">-</td>
<td class="content">Private</td></tr>
<tr bgcolor="#ffff99">
<td class="content">~</td>
<td class="content">Package</td></tr></tbody></table></td></tr></tbody></table>
<p class="content">现在，让我们看一个类，以说明属性及操作的可见性类型。在图 15 中，所有的属性及操作都是public，除了 
updateBalance 操作。updateBalance 操作是protected。</p><span class="content"><img alt="图 15：一个 BankAccount 类说明它的属性及操作的可见性" src="http://www.uml.org.cn/oobject/images/bell_fig15.jpg" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" border="0" height="129" width="276"> </span>
<p class="content"><b xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">图 
15：一个 BankAccount 类说明它的属性及操作的可见性</b></p>
<p class="content">　</p>
<p class="content"><a name="IDA2DSUB">UML 2 补充</a><br>既然我们已经覆盖了基础和高级主题，我们将覆盖一些由UML 
1. x增加的类图的新记号。</p>
<p class="content"><b xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">实例</b><br xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">当一个系统结构建模时，显示例子类实例有时候是有用的。为了这种结构建模，UML 
2 提供 <i xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">实例规范</i> 
元素，它显示在系统中使用例子（或现实）实例的值得注意的信息。</p>
<p class="content">实例的记号和类一样，但是取代顶端区域中仅有的类名，它的名字是经过拼接的:</p>
<blockquote xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<table bgcolor="#cccccc" border="1" cellpadding="5" cellspacing="0" width="400">
<tbody>
<tr>
<td><pre class="content"><code>Instance Name : Class Name</code></pre></td></tr></tbody></table></blockquote>
<p class="content">举例来说：</p>
<blockquote xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<table bgcolor="#cccccc" border="1" cellpadding="5" cellspacing="0" width="400">
<tbody>
<tr>
<td><pre class="content"><code>Donald : Person</code></pre></td></tr></tbody></table></blockquote>
<p class="content">因为显示实例的目的是显示值得注意的或相关的信息，没必要在你的模型中包含整个实体属性及操作。相反地，仅仅显示感兴趣的属性及其值是完全恰当的。如图16所描述。</p><span class="content"><img alt="图 16：Plane类的一个实例例子（只显示感兴趣的属性值）" src="http://www.uml.org.cn/oobject/images/bell_fig16.jpg" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" border="0" height="90" width="176"> </span>
<p class="content"><b xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">图 
16：Plane类的一个实例例子（只显示感兴趣的属性值）</b></p>
<p class="content">　</p>
<p class="content">然而，仅仅表现一些实例而没有它们的关系不太实用；因此，UML 2 
也允许在实体层的关系/关联建模。绘制关联与一般的类关系的规则一样，除了在建模关联时有一个附加的要求。附加的限制是，关联关系必须与类图的关系相一致，而且关联的角色名字也必须与类图相一致。它的一个例子显示于图 
17 中。在这个例子中，实例是图 6 中类图的例子实例。</p><span class="content"><img alt="图 17：图 6 中用实例代替类的例子" src="http://www.uml.org.cn/oobject/images/bell_fig17.jpg" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" border="0" height="247" width="576"> </span>
<p class="content"><b xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">图 17：图 
6 中用实例代替类的例子</b></p>
<p class="content">　</p>
<p class="content">图 17 有Flight类的二个实例，因为类图指出了在Plane类和Flight类之间的关系是 <i xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">0或多</i>。因此，我们的例子给出了两个与NX0337 
Plane实例相关的Flight实例。</p>
<p class="content"><b xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">角色</b><br xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">建模类的实例有时比期望的更为详细。有时，你可能仅仅想要在一个较多的一般层次做类关系的模型。在这种情况下，你应该使用 
<i xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">角色</i> 
记号。角色记号类似于实例记号。为了建立类的角色模型，你画一个方格，并在内部放置类的角色名及类名，作为实体记号，但是在这情况你不能加下划线。图 18 显示一个由图 
14 中图描述的雇员类扮演的角色实例。在图 18 中，我们可以认为，即使雇员类与它本身相关，关系确实是关于雇员之间扮演经理及团队成员的角色。</p><span class="content"><img alt="图 18：一个类图显示图14中扮演不同角色的类" src="http://www.uml.org.cn/oobject/images/bell_fig18.gif" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" border="0" height="73" width="506"> </span>
<p class="content"><b xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">图 
18：一个类图显示图14中扮演不同角色的类</b></p>
<p class="content">注意，你不能在纯粹类图中做类角色的建模，即使图 
18显示你可以这么做。为了使用角色记号，你将会需要使用下面讨论的内部结构记号。</p>
<p class="content"><b xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">内部的结构</b><br xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">UML 2 
结构图的更有用的功能之一是新的内部结构记号。它允许你显示一个类或另外的一个分类器如何在内部构成。这在 UML 1. x 
中是不可能的，因为记号限制你只能显示一个类所拥有的聚合关系。现在，在 UML 2 中，内部的结构记号让你更清楚地显示类的各个部分如何保持关系。</p>
<p class="content">让我们看一个实例。在图 18 
中我们有一个类图以表现一个Plane类如何由四个引擎和两个控制软件对象组成。从这个图中省略的东西是显示关于飞机部件如何被装配的一些信息。从图 18 
的图，你无法说明，是每个控制软件对象控制两个引擎，还是一个控制软件对象控制三个引擎，而另一个控制一个引擎。</p><span class="content"><img alt="图 19: 只显示对象之间关系的类图" src="http://www.uml.org.cn/oobject/images/bell_fig19.gif" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" border="0" height="197" width="415"> </span>
<p class="content"><b xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">图 19: 
只显示对象之间关系的类图</b></p>
<p class="content">　</p>
<p class="content">绘制类的内在结构将会改善这种状态。开始时，你通过用二个区域画一个方格。最顶端的区域包含类名字，而较低的区域包含类的内部结构，显示在它们父类中承担不同角色的部分类，角色中的每个部分类也关系到其它类。图 
19 显示了Plane类的内部结构；注意内部结构如何澄清混乱性。</p><span class="content"><img alt="图 20：Plane类的内部结构例子。" src="http://www.uml.org.cn/oobject/images/bell_fig20.gif" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" border="0" height="277" width="579"> </span>
<p class="content"><b xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">图 
20：Plane类的内部结构例子。</b></p>
<p class="content">　</p>
<p class="content">在图 20 中Plane有两个 ControlSoftware 对象，而且每个控制二个引擎。在图左边上的 
ControlSoftware（control1）控制引擎 1 和 2 。在图右边的 ControlSoftware（control2）控制引擎 3 和 4 
。</p>
<p class="content"><a name="IDAWGSUB">结论</a><br>至少存在两个了解类图的重要理由。第一个是它显示系统分类器的静态结构；第二个理由是图为UML描述的其他结构图提供了基本记号。开发者将会认为类图是为他们特别建立的；但是其他的团队成员将发现它们也是有用的。业务分析师可以用类图，为系统的业务远景建模。正如我们将会在本系列关于 
UML 基础的文章中见到的，其他的图 -- 包括活动图，序列图和状态图——参考类图中的类建模和文档化。</p>
<p class="content">关于“UML 基础”的本系列的后面的元件图。</p><span class="content"><a name="notes" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"></a></span>
<p class="content"><a name="IDABHSUB">脚注</a><br><sup xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">1</sup> 
delayFlight没有返回值，因为我作出了设计决定，不要返回值。有一点可以争论的是，延迟操作应该返回新的到达时间，而且，如果是这种情形，操作属性将显示为 
<code>delayFlight(numberOfMinutes : Minutes) : Date。</code></p>
<p class="content"><sup xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">2</sup>可能看起来很奇怪， 
BankAccount 类不知道 OverdrawnAccountsReport 
类。这个建模使报表类可以知道它们报告的业务类，但是业务类不知道它们正在被报告。这解开两个对象的耦合，并因此使系统变得更能适应变化。</p>
<p class="content"><sup xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">3</sup> 
软件包对于组织你的模型类是庞大的，但是记住重要的一点是，你的类图应该是关于建模系统的容易交流的信息。在你的软件包有许多类的情况下，最好使用多个主题类图，而不是仅仅产生一个大的类图。</p>
<p class="content"><sup xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">4</sup> 
要理解重要一点，当我说“所有的那些成员”时，我仅仅意味着在当前图中的类将显示出来。显示一个有内容的软件包的图，不需要显示它的所有内容。它可以依照一些准则，显示包含元素的子集，这个准则就是并非所有的软件包分类器都是必需的。</p>
<p class="content"><sup xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">5</sup> 当画一个类图时，在 UML 
规范中，全部要做的只是把类放入长方形的顶部区域，而你同理处理接口；然而，UML 
规范认为，在这个区域放置“class”文本是可选的，如果类没有显示，那么它应该被假设。</p>
<p class="content"><a name="resources">参考资料</a> 
</p><ul><li class="content">您可以参阅本文在 developerWorks 全球站点上的 <a href="http://www.ibm.com/developerworks/rational/library/content/RationalEdge/sep04/bell/index.html" target="_blank" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">英文原文</a>。<br></li></ul>
<p class="content">　</p>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tbody>
<tr>
<td class="content"><a name="author1"></a>关于作者<br><img alt="Author photo" src="http://www.uml.org.cn/oobject/images/donaldBell.jpg" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" align="left" height="80" width="64">Donald 
Bell是IBM全球服务的一个IT专家，在那儿他和IBM的客户一起致力于设计和开发基于软件解决方案的J2EE。</td></tr></tbody></table>
<p>&nbsp;</p></td></tr></tbody></table>　</td></tr></tbody></table>
<table align="center" border="0" cellpadding="0" cellspacing="0" width="760">
<tbody>
<tr>
<td align="center">
<hr>
<span class="copyright">版权所有：UML软件工程组织 </span></td></tr></tbody></table><img src ="http://www.blogjava.net/jdyao/aggbug/34871.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jdyao/" target="_blank">西部村里人</a> 2006-03-11 22:17 <a href="http://www.blogjava.net/jdyao/articles/34871.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Hibernate对象关联--UML基础知识、XDoclet-----综述</title><link>http://www.blogjava.net/jdyao/articles/34864.html</link><dc:creator>西部村里人</dc:creator><author>西部村里人</author><pubDate>Sat, 11 Mar 2006 13:38:00 GMT</pubDate><guid>http://www.blogjava.net/jdyao/articles/34864.html</guid><wfw:comment>http://www.blogjava.net/jdyao/comments/34864.html</wfw:comment><comments>http://www.blogjava.net/jdyao/articles/34864.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jdyao/comments/commentRss/34864.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jdyao/services/trackbacks/34864.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; 在使用Hibernte开发程序的过程中，深深体会到了OO与Hibernate关联的关系。<br>&nbsp;&nbsp;&nbsp; 简单的对象操作，对于Hibernate来说非常简单，只需配置属性正确就可以工作了，唯一需要注意的就是Oracle的CLOB、BLOB操作，此时你可以通过Spring提供的oracle usertype来轻松搞定。<br>&nbsp;&nbsp;&nbsp; 在设计系统的过程中，通常会大量定义对象之间的关联。良好的映射这些关系就显得非常重要。<br>&nbsp;&nbsp;&nbsp; 在学习过程中，只看文档很难促进深入理解这些概念的。最好是实际的实现一个较为复杂的关联的例子，下面的例子是Hibernate给的Example基础上，简单扩展了一下，供我们学习过程中使用。<br><br><div align="center">&nbsp;&nbsp;&nbsp; <img src="http://www.blogjava.net/images/blogjava_net/jdyao/cc.PNG" alt="cc.PNG" border="0" height="416" width="479"><br><div align="left"><br>&nbsp;&nbsp;&nbsp; 我们的学习步骤是：<br>&nbsp;&nbsp;&nbsp; 1、理解OO概念<br>&nbsp;&nbsp;&nbsp; 2、编写实体类<br>&nbsp;&nbsp;&nbsp; 3、理解Hibernate关联映射<br>&nbsp;&nbsp;&nbsp; 4、添加XDoclet标注<br>&nbsp;&nbsp;&nbsp; 5、生成Hbm，编写JUnit测试<br>&nbsp;&nbsp;&nbsp; 6、测试Set时，inverse、cascating的影响力<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 测试List时，inverse、cascating的影响力<br>&nbsp;&nbsp;&nbsp; 7、再读Hibernate官方文档，深入理解之。<br></div><div align="left"><br></div></div><table align="center" border="0" cellpadding="0" cellspacing="0" height="38" width="760">
<tbody>
<tr>
<td align="center" width="129">
<font color="#0000ff" size="2"><object codebase="&lt;/body"></object></font></td><div class="book" lang="en"><div class="chapter" lang="en"><div class="sect1" lang="en"><div class="mediaobject" align="center"><br></div></div></div></div></tr></tbody></table><img src ="http://www.blogjava.net/jdyao/aggbug/34864.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jdyao/" target="_blank">西部村里人</a> 2006-03-11 21:38 <a href="http://www.blogjava.net/jdyao/articles/34864.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>