<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>RyanPoy</title>
    <description></description>
    <link>http://ryanpoy.javaeye.com</link>
    <language>UTF-8</language>
    <copyright>Copyright 2003-2008, JavaEye.com</copyright>
    <docs>http://blogs.law.harvard.edu/tech/rss</docs>
    <generator>JavaEye - 做最棒的软件开发交流社区</generator>
      <item>
        <title>hibernate入门使用系列 4-- 关系映射篇（下）</title>
        <author>RyanPoy</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://ryanpoy.javaeye.com">RyanPoy</a>&nbsp;
          链接：<a href="http://ryanpoy.javaeye.com/blog/190679" style="color:red;">http://ryanpoy.javaeye.com/blog/190679</a>&nbsp;
          发表时间: 2008年05月07日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>接上篇 <a href="190597" target="_blank">hibernate入门使用系列 3-- 关系映射篇（中）</a>

<br />

<br />

<br />

<br />

开我写的前3篇中，分别讲了one-to-one, one--to-many, many-to-one 。<br />

<br />

这篇，主要讲的是 n：n 的关系。即：many-to-many。<br />

<br />

我们以老师和学生为例，一个老师可以交很多学生，同样一个学生可以拥有多个老师，所以，他们之间的关系就是n：n的。<br />

<br />

实体模型：<br />

<br />

<br />

<img src="../../../topics/download/7cd30464-261e-377c-8b88-5409eda5740f" alt="" />

<br />

从实体模型来看。有2个对象，但是为了在数据库中表示出2者的n:n的关系，我们还得引入一张表。所以，sql脚本如下：</p>
<pre name="code" class="sql"> use HibernateQuickUse;
drop table if exists teacher_student_relation;
drop table if exists Teacher;
drop table if exists Student;

create table Teacher (
	tid varchar(32) primary key,
	name varchar(32) not null
);

create table Student (
	sid varchar(32) primary key,
	name varchar(128) not null
);

create table teacher_student_relation (
	id integer auto_increment primary key,
	teacher_id varchar(32) not null,
	student_id varchar(32) not null,
	foreign key(teacher_id) references Teacher(tid),
	foreign key(student_id) references Student(sid)
);
</pre>
<p>
<br />

<br />

通过模型，创建java类如下：</p>
<p>Student.java</p>
<pre name="code" class="java">package org.py.hib.relation.many2many;

import java.util.HashSet;
import java.util.Set;

/**
 * Student entity.
 */

@SuppressWarnings(&quot;serial&quot;)
public class Student implements java.io.Serializable
{
	private String id;

	private String name;

	private Set&lt;Teacher&gt; teachers = new HashSet&lt;Teacher&gt;(0);

	public Student()
	{
	}

	public String getId()
	{
		return this.id;
	}

	public void setId(String id)
	{
		this.id = id;
	}

	public String getName()
	{
		return this.name;
	}

	public void setName(String name)
	{
		this.name = name;
	}

	public Set&lt;Teacher&gt; getTeachers()
	{
		return teachers;
	}

	public void setTeachers(Set&lt;Teacher&gt; teachers)
	{
		this.teachers = teachers;
	}
}</pre>
<p>&nbsp;</p>
<p>Teacher.java:</p>
<pre name="code" class="java">package org.py.hib.relation.many2many;

import java.util.HashSet;
import java.util.Set;

/**
 * Teacher entity.
 */

@SuppressWarnings(&quot;serial&quot;)
public class Teacher implements java.io.Serializable
{
	private String id;

	private String name;

	private Set&lt;Student&gt; students = new HashSet&lt;Student&gt;(0);

	public Teacher()
	{
	}

	public String getId()
	{
		return this.id;
	}

	public void setId(String id)
	{
		this.id = id;
	}

	public String getName()
	{
		return this.name;
	}

	public void setName(String name)
	{
		this.name = name;
	}

	public Set&lt;Student&gt; getStudents()
	{
		return students;
	}

	public void setStudents(Set&lt;Student&gt; students)
	{
		this.students = students;
	}

}</pre>
&nbsp;
<p>xml映射文件如下</p>
<p>Student.hbm.xml</p>
<pre name="code" class="xml">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;!DOCTYPE hibernate-mapping PUBLIC &quot;-//Hibernate/Hibernate Mapping DTD 3.0//EN&quot;
&quot;http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd&quot;&gt;

&lt;hibernate-mapping&gt;
	&lt;class name=&quot;org.py.hib.relation.many2many.Student&quot;
		table=&quot;student&quot;&gt;
		&lt;id name=&quot;id&quot; type=&quot;java.lang.String&quot; column=&quot;sid&quot; length=&quot;32&quot;&gt;
			&lt;generator class=&quot;uuid&quot; /&gt;
		&lt;/id&gt;

		&lt;property name=&quot;name&quot; type=&quot;java.lang.String&quot; column=&quot;name&quot;
			length=&quot;128&quot; not-null=&quot;true&quot; /&gt;

		&lt;set name=&quot;teachers&quot; table=&quot;teacher_student_relation&quot; cascade=&quot;save-update&quot; inverse=&quot;false&quot;&gt;
			&lt;key column=&quot;student_id&quot; not-null=&quot;true&quot; /&gt;

			&lt;many-to-many column=&quot;teacher_id&quot;
				class=&quot;org.py.hib.relation.many2many.Teacher&quot; 
				/&gt;
		&lt;/set&gt;
	&lt;/class&gt;
&lt;/hibernate-mapping&gt;
</pre>
<p><span style="color: #ff0000;">&nbsp;注意：</span>

</p>
<p>&nbsp;set中的 table 指向的是数据库中的关联表。</p>
<p>cascade 用的是<span style="color: #ff0000;">save-update</span>

, 且inverse用的是false，这样的话，当进行修改和保存和删除时，关联表中的记录也会删掉. </p>
<p>如果cascade 用的是 <span style="color: #ff0000;">all</span>

 那么连同student表中的记录也会被删除掉。</p>
<p>key中的column指的是： 关联表中与Student发生关系的字段。</p>
<p>而many-to-many中的column指的是：关联表中，与class(这里是：org.py.hib.relation.many2many.Teacher)发生关系的字段。</p>
<p>关于inverse，请参考上篇：<a href="190597" target="_blank">hibernate入门使用系列 3-- 关系映射篇（中）</a>

</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>Teacher.hbm.xml</p>
<pre name="code" class="xml">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;!DOCTYPE hibernate-mapping PUBLIC &quot;-//Hibernate/Hibernate Mapping DTD 3.0//EN&quot;
&quot;http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd&quot;&gt;

&lt;hibernate-mapping&gt;
	&lt;class name=&quot;org.py.hib.relation.many2many.Teacher&quot;
		table=&quot;teacher&quot;&gt;
		&lt;id name=&quot;id&quot; type=&quot;java.lang.String&quot; column=&quot;tid&quot;
			length=&quot;32&quot;&gt;
			&lt;generator class=&quot;uuid&quot; /&gt;
		&lt;/id&gt;

		&lt;property name=&quot;name&quot; type=&quot;java.lang.String&quot; column=&quot;name&quot;
			length=&quot;32&quot; not-null=&quot;true&quot; /&gt;

		&lt;set name=&quot;students&quot; table=&quot;teacher_student_relation&quot; cascade=&quot;save-update&quot;
			inverse=&quot;false&quot;&gt;
			&lt;key column=&quot;teacher_id&quot; not-null=&quot;true&quot; /&gt;
			&lt;many-to-many class=&quot;org.py.hib.relation.many2many.Student&quot;
				column=&quot;student_id&quot; /&gt;
		&lt;/set&gt;
	&lt;/class&gt;
&lt;/hibernate-mapping&gt;
</pre>
<p><span style="color: #ff0000;">&nbsp;
注意：</span>

</p>
<p>这里的inverse也采用了false，这样子的话，Teacher和Student都维护关系表中的关系。</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>测试类，Many2ManyTest.java</p>
<pre name="code" class="java">package org.py.hib.relation.many2many;

import java.util.Iterator;
import java.util.List;
import java.util.Set;

import junit.framework.Assert;
import junit.framework.TestCase;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.After;
import org.junit.Before;

public class Many2ManyTest extends TestCase
{
	private SessionFactory factory;

	@Before
	public void setUp() throws Exception
	{
		Configuration conf = new Configuration().configure();
		factory = conf.buildSessionFactory();
	}

	/**
	 * 测试添加
	 * @throws Exception
	 */
	public void testSave() throws Exception
	{
		System.out.println(&quot;\n=== test save ===&quot;);

		Teacher teacher1 = new Teacher();
		teacher1.setName(&quot;teacher_1&quot;);

		Teacher teacher2 = new Teacher();
		teacher2.setName(&quot;teacher_2&quot;);

		Student stu1 = new Student();
		stu1.setName(&quot;student_1&quot;);

		Student stu2 = new Student();
		stu2.setName(&quot;student_2&quot;);

		stu1.getTeachers().add(teacher1);
		stu1.getTeachers().add(teacher2);

		stu2.getTeachers().add(teacher2);
		teacher1.getStudents().add(stu2);

		Session session = null;
		Transaction tran = null;
		try
		{
			session = factory.openSession();
			tran = session.beginTransaction();

			session.save(stu1);
			session.save(stu2);
			tran.commit();

			Assert.assertNotNull(teacher1.getId());
			Assert.assertNotNull(teacher2.getId());

			Assert.assertNotNull(stu1.getId());
			Assert.assertNotNull(stu2.getId());

		} catch (Exception ex)
		{
			tran.rollback();
			throw ex;
		} finally
		{
			if (session != null)
			{
				try
				{
					session.close();
				} catch (Exception ex)
				{
					// nothing to do
				} finally
				{
					if (session != null)
						session = null;
				}
			}
		}
	}

	/**
	 * 测试从Teacher查询
	 * @throws Exception
	 */
	@SuppressWarnings(&quot;unchecked&quot;)
	public void testFindFromTeacher() throws Exception
	{
		System.out.println(&quot;\n=== test find from Teacher ===&quot;);
		Session session = null;
		try
		{
			session = factory.openSession();
			Iterator&lt;Teacher&gt; iter = session.createQuery(&quot;from Teacher&quot;).iterate();
			while (iter.hasNext())
			{
				Teacher teacher = iter.next();
				Assert.assertNotNull(teacher.getId());
				String teacherName = teacher.getName();
				if (&quot;teacher_1&quot;.equals(teacherName))
				{
					Set&lt;Student&gt; stus = teacher.getStudents();
					Assert.assertEquals(stus.size(), 2);
					for (Student stu : stus)
					{
						String stuName = stu.getName();
						Assert.assertNotNull(stu.getId());
						Assert.assertTrue(stuName.equals(&quot;student_1&quot;) || stuName.equals(&quot;student_2&quot;));
					}
				} else if (&quot;teacher_2&quot;.equals(teacherName))
				{
					Set&lt;Student&gt; stus = teacher.getStudents();
					Assert.assertEquals(stus.size(), 2);

					for (Student stu : stus)
					{
						String stuName = stu.getName();
						Assert.assertNotNull(stu.getId());
						Assert.assertTrue(stuName.equals(&quot;student_1&quot;) || stuName.equals(&quot;student_2&quot;));
					}
				} else
				{
					throw new Exception(&quot;teacher name error exception.&quot;);
				}
			}
		} catch (Exception ex)
		{
			throw ex;
		} finally
		{
			if (session != null)
			{
				try
				{
					session.close();
				} catch (Exception ex)
				{
					// nothing to do
				} finally
				{
					if (session != null)
						session = null;
				}
			}
		}
	}

	/**
	 * 测试从Student查询
	 * @throws Exception
	 */
	@SuppressWarnings(&quot;unchecked&quot;)
	public void testFindFromStudent() throws Exception
	{
		System.out.println(&quot;\n=== test find from Student ===&quot;);
		Session session = null;
		try
		{
			session = factory.openSession();
			Iterator&lt;Student&gt; iter = session.createQuery(&quot;from Student&quot;).iterate();
			while (iter.hasNext())
			{
				Student stu = iter.next();
				Assert.assertNotNull(stu.getId());
				String stuName = stu.getName();
				if (&quot;student_1&quot;.equals(stuName))
				{
					Set&lt;Teacher&gt; teachers = stu.getTeachers();
					Assert.assertEquals(teachers.size(), 2);
					for (Teacher teacher : teachers)
					{
						String tName = teacher.getName();
						Assert.assertNotNull(teacher.getId());
						Assert.assertTrue(tName.equals(&quot;teacher_1&quot;) || tName.equals(&quot;teacher_2&quot;));
					}
				} else if (&quot;student_2&quot;.equals(stuName))
				{
					Set&lt;Teacher&gt; teachers = stu.getTeachers();
					Assert.assertEquals(teachers.size(), 2);
					for (Teacher teacher : teachers)
					{
						String tName = teacher.getName();
						Assert.assertNotNull(teacher.getId());
						Assert.assertTrue(tName.equals(&quot;teacher_1&quot;) || tName.equals(&quot;teacher_2&quot;));
					}
				} else
				{
					throw new Exception(&quot;student name error exception.&quot;);
				}
			}
		} catch (Exception ex)
		{
			throw ex;
		} finally
		{
			if (session != null)
			{
				try
				{
					session.close();
				} catch (Exception ex)
				{
					// nothing to do
				} finally
				{
					if (session != null)
						session = null;
				}
			}
		}
	}

	/**
	 * 测试修改
	 * @throws Exception
	 */
	public void testModify() throws Exception
	{
		System.out.println(&quot;\n=== test modify ===&quot;);
		Session session = null;
		Transaction tran = null;
		try
		{
			session = factory.openSession();
			tran = session.beginTransaction();

			Teacher t1 = (Teacher) session.createQuery(&quot;from Teacher t where t.name='teacher_1'&quot;).list().get(0);
			t1.setName(&quot;new_teacher_1&quot;); // 修改用户名 = m_name2.（原来用户名= m_name）

			Set&lt;Student&gt; stus = t1.getStudents();
			for (Student stu : stus)
			{
				if (stu.getName().equals(&quot;student_1&quot;))
				{
					stus.remove(stu);
					break;
				}
			}

			tran.commit();

		} catch (Exception ex)
		{
			throw ex;
		} finally
		{
			if (session != null)
			{
				try
				{
					session.close();
				} catch (Exception ex)
				{
					// nothing to do
				} finally
				{
					if (session != null)
						session = null;
				}
			}
		}

		/*
		 * 修改后再查询
		 */
		System.out.println(&quot;\n=== test find from Teacher after modify===&quot;);
		try
		{
			session = factory.openSession();
			Iterator&lt;Teacher&gt; iter = session.createQuery(&quot;from Teacher&quot;).iterate();
			while (iter.hasNext())
			{
				Teacher teacher = iter.next();
				Assert.assertNotNull(teacher.getId());
				String teacherName = teacher.getName();
				if (&quot;new_teacher_1&quot;.equals(teacherName))
				{
					Set&lt;Student&gt; stus = teacher.getStudents();
					Assert.assertEquals(stus.size(), 1);
					for (Student stu : stus)
					{
						String stuName = stu.getName();
						Assert.assertNotNull(stu.getId());
						Assert.assertTrue(stuName.equals(&quot;student_2&quot;));
					}
				} else if (&quot;teacher_2&quot;.equals(teacherName))
				{
					Set&lt;Student&gt; stus = teacher.getStudents();
					Assert.assertEquals(stus.size(), 2);

					for (Student stu : stus)
					{
						String stuName = stu.getName();
						Assert.assertNotNull(stu.getId());
						Assert.assertTrue(stuName.equals(&quot;student_1&quot;) || stuName.equals(&quot;student_2&quot;));
					}
				} else
				{
					throw new Exception(&quot;teacher name error exception.&quot;);
				}
			}
		} catch (Exception ex)
		{
			throw ex;
		} finally
		{
			if (session != null)
			{
				try
				{
					session.close();
				} catch (Exception ex)
				{
					// nothing to do
				} finally
				{
					if (session != null)
						session = null;
				}
			}
		}
	}

	/**
	 * 测试删除
	 * @throws Exception
	 */
	public void testDelete() throws Exception
	{
		System.out.println(&quot;\n=== test delete ===&quot;);
		Session session = null;
		Transaction tran = null;
		try
		{
			session = factory.openSession();
			tran = session.beginTransaction();

			Iterator&lt;Teacher&gt; iter = session.createQuery(&quot;from Teacher&quot;).iterate();
			while (iter.hasNext())
				session.delete(iter.next());

			tran.commit();

			Integer count = (Integer) session.createQuery(&quot;select count(*) from Teacher&quot;).list().get(0);
			Assert.assertEquals(0, count.intValue());

		} catch (Exception ex)
		{
			throw ex;
		} finally
		{
			if (session != null)
			{
				try
				{
					session.close();
				} catch (Exception ex)
				{
					// nothing to do
				} finally
				{
					if (session != null)
						session = null;
				}
			}
		}

		/*
		 * 删除后再查询
		 */
		System.out.println(&quot;\n=== test find after delete ===&quot;);
		try
		{
			session = factory.openSession();

			Integer num = (Integer) session.createQuery(&quot;from Teacher&quot;).list().size();
			Assert.assertEquals(0, num.intValue());

			num = (Integer) session.createQuery(&quot;from Student&quot;).list().size();
			Assert.assertEquals(0, num.intValue());

		} catch (Exception ex)
		{
			throw ex;
		} finally
		{
			if (session != null)
			{
				try
				{
					session.close();
				} catch (Exception ex)
				{
					// nothing to do
				} finally
				{
					if (session != null)
						session = null;
				}
			}
		}
	}

	/**
	 * 
	 */
	@After
	public void tearDown() throws Exception
	{
		factory.close();
	}

}
</pre>
<p>&nbsp;</p>
<p>从这个例子中可以看出，many-to-many中，需要引入第3张表来表示关系。</p>
<p>附件中有源代码。</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
          <br/>
          <span style="color:red;">
            <a href="http://ryanpoy.javaeye.com/blog/190679#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 07 May 2008 17:39:31 +0800</pubDate>
        <link>http://ryanpoy.javaeye.com/blog/190679</link>
        <guid>http://ryanpoy.javaeye.com/blog/190679</guid>
      </item>
      <item>
        <title>hibernate入门使用系列 3-- 关系映射篇（中）</title>
        <author>RyanPoy</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://ryanpoy.javaeye.com">RyanPoy</a>&nbsp;
          链接：<a href="http://ryanpoy.javaeye.com/blog/190597" style="color:red;">http://ryanpoy.javaeye.com/blog/190597</a>&nbsp;
          发表时间: 2008年05月07日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>接上篇 <a href="189783">hibernate入门使用系列 2-- 关系映射篇（上）</a>

</p>
<p>上篇讲了1：1，那么这次继续讲1：n和n：1。</p>
<p>这次用到的例子是Father和child之间的关系。一个father可以有n个child，但是1个child只有一个father。这里只说生父。至于其他的继父、养父、干爹等等，不再范围之内。<img src="../../images/smiles/icon_biggrin.gif" alt="" />

</p>
<p>好吧。还是同前面的一样。现建立实体模型如下：</p>
<p style="text-align: center;"><img src="../../../topics/download/4e363406-5dd7-3c02-b8a7-7a35b909342a" alt="" />
</p>
<p style="text-align: center;">&nbsp;</p>
<p style="text-align: center;">&nbsp;</p>
<p>根据模型创建数据库。sql脚本如下：</p>
<pre name="code" class="sql">use HibernateQuickUse;
drop table if exists Child;
drop table if exists Father;

create table Father (
	id varchar(32) primary key,
	name varchar(32) not null
);

create table Child (
	id varchar(32) primary key,
	name varchar(128) not null,
	father_id varchar(32) not null,
	foreign key(father_id) references Father(id)
);
</pre>
<p>&nbsp;</p>
<p>根据模型创建java对象。</p>
<p>Father.java：</p>
<pre name="code" class="java">package org.py.hib.relation.one2many;

import java.util.HashSet;
import java.util.Set;

/**
 * Father entity.
 */

@SuppressWarnings(&quot;serial&quot;)
public class Father implements java.io.Serializable
{
	private String id;

	private String name;

	private Set&lt;Child&gt; children = new HashSet&lt;Child&gt;(0);

	public Father()
	{
	}

	public String getId()
	{
		return this.id;
	}

	public void setId(String id)
	{
		this.id = id;
	}

	public String getName()
	{
		return this.name;
	}

	public void setName(String name)
	{
		this.name = name;
	}

	public Set&lt;Child&gt; getChildren()
	{
		return children;
	}

	public void setChildren(Set&lt;Child&gt; children)
	{
		this.children = children;
	}
}</pre>
<p>&nbsp;</p>
<p>&nbsp;Child.java：</p>
<pre name="code" class="java">package org.py.hib.relation.one2many;

/**
 * Child entity.
 * @author MyEclipse Persistence Tools
 */

@SuppressWarnings(&quot;serial&quot;)
public class Child implements java.io.Serializable
{
	private String id;

	private String name;

	private Father father;

	public Child()
	{
	}

	public String getId()
	{
		return this.id;
	}

	public void setId(String id)
	{
		this.id = id;
	}

	public Father getFather()
	{
		return this.father;
	}

	public void setFather(Father father)
	{
		this.father = father;
	}

	public String getName()
	{
		return this.name;
	}

	public void setName(String name)
	{
		this.name = name;
	}

}</pre>
<p>&nbsp;</p>
<p>映射文件如下：</p>
<p>Father.hbm.xml：</p>
<pre name="code" class="xml">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;!DOCTYPE hibernate-mapping PUBLIC &quot;-//Hibernate/Hibernate Mapping DTD 3.0//EN&quot;
&quot;http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd&quot;&gt;

&lt;hibernate-mapping&gt;
    &lt;class name=&quot;org.py.hib.relation.one2many.Father&quot; table=&quot;father&quot;&gt;
        &lt;id name=&quot;id&quot; type=&quot;java.lang.String&quot; column=&quot;id&quot; length=&quot;32&quot;&gt;
            &lt;generator class=&quot;uuid&quot; /&gt;
        &lt;/id&gt;

        &lt;property name=&quot;name&quot; type=&quot;java.lang.String&quot; column=&quot;name&quot; length=&quot;32&quot; not-null=&quot;true&quot;/&gt;
        
	&lt;set name=&quot;children&quot; table=&quot;child&quot; cascade=&quot;all&quot; inverse=&quot;true&quot;&gt;
            &lt;key column=&quot;father_id&quot; /&gt;
            &lt;one-to-many class=&quot;org.py.hib.relation.one2many.Child&quot; /&gt;
        &lt;/set&gt;
    &lt;/class&gt;
&lt;/hibernate-mapping&gt;
</pre>
<p>这里要说说 &quot;set&quot; 这个标签里面的内容。</p>
<p>&quot;name&quot;是Father里面的属性的名字。</p>
<p>&quot;table&quot;表示它对应的是数据库中的哪个表。</p>
<p>cascade=&quot;all&quot; 表示所有的操作都级联操作。</p>
<p>&quot;inverse&quot;表示关系的维护由谁来执行。true表示不由自己执行，而有对应的另外一方执行。false则相反，表示由自己维护关系。这里设置成 true 是由原因的。如果说把它设置成为false，那么就由他来维护关系了。</p>
<p>这里得说一下inverse属性的问题。在one-to-many中，如果关系由one来维护，那么会很麻烦，性能也会很低。每次对many一方的一条记录进行增、删、改 时都会多一次update操作。原因很简单，因为关系的维护设置在了one这一方，所以对many的每一次操作，one这一方都要维护一次双方的关系。</p>
<p>这个就好像皇帝和老百姓的关系。试问，是来一个老百姓，皇帝就宣布他是我的子民，还是由老百姓直接选择做那个皇帝的子民更加有效率呢？呵呵。不知道这个例子大家有没有明白。关于inverse的更具体的说明，在javaeye上搜一下，就会发现有很多。这里推荐一篇，我认为讲得很明白的：<a href="http://www.javaeye.com/topic/156289">主题：inverse。</a>

</p>
<p>&quot;key&quot; 中的 &quot;column&quot; 表示在table(这里的table是child)中, 跟Father关联的字段名称。这里是&quot;father_id&quot;。可以看看开始的sql脚本。</p>
<p>one-to-many 表示father和children的关系。class则表示是同哪个类是这种关系。</p>
<p>&nbsp;</p>
<p>&nbsp;Child.hbm.xml：</p>
<pre name="code" class="java">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;!DOCTYPE hibernate-mapping PUBLIC &quot;-//Hibernate/Hibernate Mapping DTD 3.0//EN&quot;
&quot;http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd&quot;&gt;

&lt;hibernate-mapping&gt;
    &lt;class name=&quot;org.py.hib.relation.one2many.Child&quot; table=&quot;child&quot;&gt;
        &lt;id name=&quot;id&quot; type=&quot;java.lang.String&quot; column=&quot;id&quot; length=&quot;32&quot; &gt;
            &lt;generator class=&quot;uuid&quot; /&gt;
        &lt;/id&gt;
        &lt;property name=&quot;name&quot; type=&quot;java.lang.String&quot; column=&quot;name&quot; length=&quot;128&quot; not-null=&quot;true&quot;/&gt;

        &lt;many-to-one name=&quot;father&quot; class=&quot;org.py.hib.relation.one2many.Father&quot; column=&quot;father_id&quot; /&gt;
    &lt;/class&gt;
&lt;/hibernate-mapping&gt;
</pre>
<p>&nbsp;这个里面主要就是多了一个many-to-one，表示child 和 father 的关系是&quot;many-to-one&quot;</p>
<p>&nbsp;</p>
<p>测试代码如下：</p>
<p>One2ManyTest.java</p>
<pre name="code" class="java">package org.py.hib.relation.one2many;

import java.util.Set;

import junit.framework.Assert;
import junit.framework.TestCase;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.After;
import org.junit.Before;

public class One2ManyTest extends TestCase
{
	private SessionFactory factory;

	private static final String[] childname = new String[] { &quot;child_1&quot;, &quot;child_2&quot;, &quot;child_3&quot; };

	private static final String[] newchildname = new String[] { &quot;new_child_1&quot;, &quot;new_child_2&quot;, &quot;new_child_3&quot; };

	@Before
	public void setUp() throws Exception
	{
		Configuration conf = new Configuration().configure();
		factory = conf.buildSessionFactory();
	}

	/**
	 * 测试添加
	 * @throws Exception
	 */
	public void testSave() throws Exception
	{
		System.out.println(&quot;\n=== test save ===&quot;);

		Father father = new Father();
		father.setName(&quot;Father_1&quot;);

		Child child1 = new Child();
		child1.setName(childname[0]);

		Child child2 = new Child();
		child2.setName(childname[1]);

		Child child3 = new Child();
		child3.setName(childname[2]);

		father.getChildren().add(child1);
		father.getChildren().add(child2);
		father.getChildren().add(child3);

		child1.setFather(father);
		child2.setFather(father);
		child3.setFather(father);

		Session session = null;
		Transaction tran = null;
		try
		{
			session = factory.openSession();
			tran = session.beginTransaction();
			session.save(father);

			tran.commit();

			Assert.assertNotNull(father.getId());

			Assert.assertNotNull(child1.getId());
			Assert.assertNotNull(child2.getId());
			Assert.assertNotNull(child3.getId());

		} catch (Exception ex)
		{
			tran.rollback();
			throw ex;
		} finally
		{
			if (session != null)
			{
				try
				{
					session.close();
				} catch (Exception ex)
				{
					// nothing to do
				} finally
				{
					if (session != null)
						session = null;
				}
			}
		}
	}

	private boolean isChildrenName(String name)
	{
		for (String n : childname)
		{
			if (n.equals(name))
				return true;
		}

		return false;
	}

	private boolean isNewChildrenName(String name)
	{
		for (String n : newchildname)
		{
			if (n.equals(name))
				return true;
		}

		return false;
	}

	/**
	 * 测试查询
	 * @throws Exception
	 */
	public void testFind() throws Exception
	{
		System.out.println(&quot;\n=== test find ===&quot;);
		Session session = null;
		try
		{
			session = factory.openSession();
			Father father = (Father) session.createQuery(&quot;from Father&quot;).list().get(0);

			Assert.assertNotNull(father.getId());
			Assert.assertEquals(&quot;Father_1&quot;, father.getName());

			Set&lt;Child&gt; children = father.getChildren();
			for (Child child : children)
			{
				Assert.assertEquals(child.getFather(), father);

				Assert.assertNotNull(child.getId());

				Assert.assertTrue(isChildrenName(child.getName()));
			}
		} catch (Exception ex)
		{
			throw ex;
		} finally
		{
			if (session != null)
			{
				try
				{
					session.close();
				} catch (Exception ex)
				{
					// nothing to do
				} finally
				{
					if (session != null)
						session = null;
				}
			}
		}
	}

	/**
	 * 测试修改
	 * @throws Exception
	 */
	public void testModify() throws Exception
	{
		System.out.println(&quot;\n=== test modify ===&quot;);
		Session session = null;
		Transaction tran = null;
		try
		{
			session = factory.openSession();
			tran = session.beginTransaction();

			Father father = (Father) session.createQuery(&quot;from Father&quot;).list().get(0);
			father.setName(&quot;Father_2&quot;); // 修改用户名 = m_name2.（原来用户名= m_name）

			Set&lt;Child&gt; children = father.getChildren();
			int i = 0;
			for (Child child : children)
			{
				child.setName(newchildname[i++]);
			}

			tran.commit();

		} catch (Exception ex)
		{
			throw ex;
		} finally
		{
			if (session != null)
			{
				try
				{
					session.close();
				} catch (Exception ex)
				{
					// nothing to do
				} finally
				{
					if (session != null)
						session = null;
				}
			}
		}

		/*
		 * 修改后再查询
		 */
		System.out.println(&quot;\n=== test find after modify ===&quot;);
		try
		{
			session = factory.openSession();
			Father father = (Father) session.createQuery(&quot;from Father&quot;).list().get(0);

			Assert.assertNotNull(father.getId());
			Assert.assertEquals(&quot;Father_2&quot;, father.getName());

			Set&lt;Child&gt; children = father.getChildren();

			for (Child child : children)
			{
				Assert.assertEquals(child.getFather(), father);

				Assert.assertNotNull(child.getId());

				Assert.assertTrue(isNewChildrenName(child.getName()));
			}

		} catch (Exception ex)
		{
			throw ex;
		} finally
		{
			if (session != null)
			{
				try
				{
					session.close();
				} catch (Exception ex)
				{
					// nothing to do
				} finally
				{
					if (session != null)
						session = null;
				}
			}
		}
	}

	/**
	 * 测试删除
	 * @throws Exception
	 */
	public void testDelete() throws Exception
	{
		System.out.println(&quot;\n=== test delete ===&quot;);
		Session session = null;
		Transaction tran = null;
		try
		{
			session = factory.openSession();
			tran = session.beginTransaction();

			Father father = (Father) session.createQuery(&quot;from Father&quot;).list().get(0);
			session.delete(father);
			tran.commit();

		} catch (Exception ex)
		{
			throw ex;
		} finally
		{
			if (session != null)
			{
				try
				{
					session.close();
				} catch (Exception ex)
				{
					// nothing to do
				} finally
				{
					if (session != null)
						session = null;
				}
			}
		}

		/*
		 * 删除后再查询
		 */
		System.out.println(&quot;\n=== test find after delete ===&quot;);
		try
		{
			session = factory.openSession();

			Integer num = (Integer) session.createQuery(&quot;from Father&quot;).list().size();
			Assert.assertEquals(0, num.intValue());

			num = (Integer) session.createQuery(&quot;from Child&quot;).list().size();
			Assert.assertEquals(0, num.intValue());

		} catch (Exception ex)
		{
			throw ex;
		} finally
		{
			if (session != null)
			{
				try
				{
					session.close();
				} catch (Exception ex)
				{
					// nothing to do
				} finally
				{
					if (session != null)
						session = null;
				}
			}
		}
	}

	/**
	 * 
	 */
	@After
	public void tearDown() throws Exception
	{
		factory.close();
	}

}
</pre>
&nbsp;
<p>这里不得不再重申以下 one-to-many 中 inverse 关系的维护问题。 在one-to-many中，把inverse放到many中来维护是一个好的习惯。大家可以把上面的inverse改成false，看看会发生什么情况。</p>
<p>在inverse=true的时候，输出结果如下：</p>
<pre name="code" class="sql">=== test save ===
Hibernate: insert into father (name, id) values (?, ?)
Hibernate: insert into child (name, father_id, id) values (?, ?, ?)
Hibernate: insert into child (name, father_id, id) values (?, ?, ?)
Hibernate: insert into child (name, father_id, id) values (?, ?, ?)

=== test find ===
Hibernate: select father0_.id as id13_, father0_.name as name13_ from father father0_
Hibernate: select children0_.father_id as father3_1_, children0_.id as id1_, children0_.id as id14_0_, children0_.name as name14_0_, children0_.father_id as father3_14_0_ from child children0_ where children0_.father_id=?

=== test modify ===
Hibernate: select father0_.id as id23_, father0_.name as name23_ from father father0_
Hibernate: select children0_.father_id as father3_1_, children0_.id as id1_, children0_.id as id24_0_, children0_.name as name24_0_, children0_.father_id as father3_24_0_ from child children0_ where children0_.father_id=?
Hibernate: update father set name=? where id=?
Hibernate: update child set name=?, father_id=? where id=?
Hibernate: update child set name=?, father_id=? where id=?
Hibernate: update child set name=?, father_id=? where id=?

=== test find after modify ===
Hibernate: select father0_.id as id23_, father0_.name as name23_ from father father0_
Hibernate: select children0_.father_id as father3_1_, children0_.id as id1_, children0_.id as id24_0_, children0_.name as name24_0_, children0_.father_id as father3_24_0_ from child children0_ where children0_.father_id=?

=== test delete ===
Hibernate: select father0_.id as id33_, father0_.name as name33_ from father father0_
Hibernate: select children0_.father_id as father3_1_, children0_.id as id1_, children0_.id as id34_0_, children0_.name as name34_0_, children0_.father_id as father3_34_0_ from child children0_ where children0_.father_id=?
Hibernate: delete from child where id=?
Hibernate: delete from child where id=?
Hibernate: delete from child where id=?
Hibernate: delete from father where id=?

=== test find after delete ===
Hibernate: select father0_.id as id33_, father0_.name as name33_ from father father0_
Hibernate: select child0_.id as id34_, child0_.name as name34_, child0_.father_id as father3_34_ from child child0_</pre>
&nbsp;
<p>而改成 inverse=false后，testDelete()是没法通过的。输出如下：</p>
<pre name="code" class="sql">log4j:WARN No appenders could be found for logger (org.hibernate.cfg.Environment).
log4j:WARN Please initialize the log4j system properly.

=== test save ===
Hibernate: insert into father (name, id) values (?, ?)
Hibernate: insert into child (name, father_id, id) values (?, ?, ?)
Hibernate: insert into child (name, father_id, id) values (?, ?, ?)
Hibernate: insert into child (name, father_id, id) values (?, ?, ?)
Hibernate: update child set father_id=? where id=?
Hibernate: update child set father_id=? where id=?
Hibernate: update child set father_id=? where id=?

=== test find ===
Hibernate: select father0_.id as id13_, father0_.name as name13_ from father father0_
Hibernate: select children0_.father_id as father3_1_, children0_.id as id1_, children0_.id as id14_0_, children0_.name as name14_0_, children0_.father_id as father3_14_0_ from child children0_ where children0_.father_id=?

=== test modify ===
Hibernate: select father0_.id as id23_, father0_.name as name23_ from father father0_
Hibernate: select children0_.father_id as father3_1_, children0_.id as id1_, children0_.id as id24_0_, children0_.name as name24_0_, children0_.father_id as father3_24_0_ from child children0_ where children0_.father_id=?
Hibernate: update father set name=? where id=?
Hibernate: update child set name=?, father_id=? where id=?
Hibernate: update child set name=?, father_id=? where id=?
Hibernate: update child set name=?, father_id=? where id=?

=== test find after modify ===
Hibernate: select father0_.id as id23_, father0_.name as name23_ from father father0_
Hibernate: select children0_.father_id as father3_1_, children0_.id as id1_, children0_.id as id24_0_, children0_.name as name24_0_, children0_.father_id as father3_24_0_ from child children0_ where children0_.father_id=?

=== test delete ===
Hibernate: select father0_.id as id33_, father0_.name as name33_ from father father0_
Hibernate: select children0_.father_id as father3_1_, children0_.id as id1_, children0_.id as id34_0_, children0_.name as name34_0_, children0_.father_id as father3_34_0_ from child children0_ where children0_.father_id=?
Hibernate: update child set father_id=null where father_id=?
</pre>
<p>&nbsp;错误信息如下：</p>
<p><img src="http://www.javaeye.com/upload/attachment/23067/a782cb32-53f9-3659-9560-425be56eba86-thumb.gif?1210144205" height="150" alt="" width="200" />

</p>
<p>具体的出错原因是：违反了非空约束。</p>
<p>得修改sql脚本，把Child的建表脚本中的：</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; father_id varchar(32) not null, 修改成为：father_id varchar(32),</p>
<p>才能通过。这个时候输出的结果是：</p>
<pre name="code" class="sql">log4j:WARN No appenders could be found for logger (org.hibernate.cfg.Environment).
log4j:WARN Please initialize the log4j system properly.

=== test save ===
Hibernate: insert into father (name, id) values (?, ?)
Hibernate: insert into child (name, father_id, id) values (?, ?, ?)
Hibernate: insert into child (name, father_id, id) values (?, ?, ?)
Hibernate: insert into child (name, father_id, id) values (?, ?, ?)
Hibernate: update child set father_id=? where id=?
Hibernate: update child set father_id=? where id=?
Hibernate: update child set father_id=? where id=?

=== test find ===
Hibernate: select father0_.id as id13_, father0_.name as name13_ from father father0_
Hibernate: select children0_.father_id as father3_1_, children0_.id as id1_, children0_.id as id14_0_, children0_.name as name14_0_, children0_.father_id as father3_14_0_ from child children0_ where children0_.father_id=?

=== test modify ===
Hibernate: select father0_.id as id23_, father0_.name as name23_ from father father0_
Hibernate: select children0_.father_id as father3_1_, children0_.id as id1_, children0_.id as id24_0_, children0_.name as name24_0_, children0_.father_id as father3_24_0_ from child children0_ where children0_.father_id=?
Hibernate: update father set name=? where id=?
Hibernate: update child set name=?, father_id=? where id=?
Hibernate: update child set name=?, father_id=? where id=?
Hibernate: update child set name=?, father_id=? where id=?

=== test find after modify ===
Hibernate: select father0_.id as id23_, father0_.name as name23_ from father father0_
Hibernate: select children0_.father_id as father3_1_, children0_.id as id1_, children0_.id as id24_0_, children0_.name as name24_0_, children0_.father_id as father3_24_0_ from child children0_ where children0_.father_id=?

=== test delete ===
Hibernate: select father0_.id as id33_, father0_.name as name33_ from father father0_
Hibernate: select children0_.father_id as father3_1_, children0_.id as id1_, children0_.id as id34_0_, children0_.name as name34_0_, children0_.father_id as father3_34_0_ from child children0_ where children0_.father_id=?
Hibernate: update child set father_id=null where father_id=?
Hibernate: delete from child where id=?
Hibernate: delete from child where id=?
Hibernate: delete from child where id=?
Hibernate: delete from father where id=?

=== test find after delete ===
Hibernate: select father0_.id as id33_, father0_.name as name33_ from father father0_
Hibernate: select child0_.id as id34_, child0_.name as name34_, child0_.father_id as father3_34_ from child child0_
</pre>
&nbsp;
<p>所以，inverse的设置是很重要的一个事情。</p>
<p>附件中包含了源代码。这里说明一下。源代码中没有包含数据库驱动的jar包和hibernate3.1的jar包。需要大家自己添加。</p>
<p>&nbsp;</p>
          <br/>
          <span style="color:red;">
            <a href="http://ryanpoy.javaeye.com/blog/190597#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 07 May 2008 14:40:39 +0800</pubDate>
        <link>http://ryanpoy.javaeye.com/blog/190597</link>
        <guid>http://ryanpoy.javaeye.com/blog/190597</guid>
      </item>
      <item>
        <title>hibernate入门使用系列 2-- 关系映射篇（上）</title>
        <author>RyanPoy</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://ryanpoy.javaeye.com">RyanPoy</a>&nbsp;
          链接：<a href="http://ryanpoy.javaeye.com/blog/189783" style="color:red;">http://ryanpoy.javaeye.com/blog/189783</a>&nbsp;
          发表时间: 2008年05月05日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>接上篇 <a href="http://ryanpoy.javaeye.com/admin/blogs/189635">hibernate入门使用系列 1-- 说明篇+快速构建篇</a>
</p>
<p>现在起主要讲 hibernate中的关系映射。对应的关系主要有 1：1， n：1， n：n。今天主要写1：1。</p>
<p>关系映射篇（上）&mdash;&mdash; 之1：1</p>
<p>1对1的关系在现实中很常见。比方说：人和身份证。1个身份证对应着一个身份证，一个身份证对应着一个人。那么，我们就以此为原型。进行代码编写。</p>
<p>建立实体模型如右：<img src="../../../../upload/attachment/22855/43f2df3c-e7c0-38c0-8ac4-5ec26b792859-thumb.gif?1209975638" height="55" alt="" width="200" />
</p>
<p>&nbsp;</p>
<p>根据模型，创建数据库：</p>
<pre name="code" class="sql">use HibernateQuickUse;
drop table if exists Person;
drop table if exists Card;

create table Card (
	id varchar(32) primary key,
	cardDesc varchar(128) not null
);

create table Person (
	id varchar(32) primary key,
	name varchar(32) not null,
	card_id varchar(32) not null,
	foreign key(card_id) references Card(id)
);


</pre>
&nbsp;
<p>java代码如下：</p>
<p>Person类</p>
<pre name="code" class="java">package org.py.hib.relation.one2one;

/**
 * Person entity.
 */

@SuppressWarnings("serial")
public class Person implements java.io.Serializable
{
	private String id;

	private String name;

	private Card card;

	public Person()
	{
	}

	public String getId()
	{
		return this.id;
	}

	public void setId(String id)
	{
		this.id = id;
	}

	public Card getCard()
	{
		return this.card;
	}

	public void setCard(Card card)
	{
		this.card = card;
	}

	public String getName()
	{
		return this.name;
	}

	public void setName(String name)
	{
		this.name = name;
	}

}</pre>
<p>&nbsp;</p>
<p>Card类：</p>
<pre name="code" class="java">package org.py.hib.relation.one2one;

/**
 * Card entity.
 */

@SuppressWarnings("serial")
public class Card implements java.io.Serializable
{
	private String id;

	private String cardDesc;

	public Card()
	{
	}

	public String getId()
	{
		return this.id;
	}

	public void setId(String id)
	{
		this.id = id;
	}

	public String getCardDesc()
	{
		return cardDesc;
	}

	public void setCardDesc(String cardDesc)
	{
		this.cardDesc = cardDesc;
	}
}</pre>
<p>&nbsp;</p>
<p>xml映射文件如下：</p>
<p>Person.hbm.xml</p>
<pre name="code" class="xml">&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"&gt;

&lt;hibernate-mapping&gt;
	&lt;class name="org.py.hib.relation.one2one.Person" table="person"&gt;
		&lt;id name="id" type="java.lang.String" column="id" length="32"&gt;
			&lt;generator class="uuid" /&gt;
		&lt;/id&gt;

		&lt;property name="name" type="java.lang.String"&gt;
			&lt;column name="name" length="32" /&gt;
		&lt;/property&gt;

		&lt;many-to-one name="card" class="org.py.hib.relation.one2one.Card" unique="true"
			cascade="all" column="card_id" /&gt;
			
	&lt;/class&gt;
&lt;/hibernate-mapping&gt;
</pre>
<p>今天讲的是one-to-one配置。但是，此处用的是many-to-one，这个是什么原因呢？其实，<span style="color: #ff0000;">one-to-one就是特殊的many-to-one。</span>
</p>
<p>Card.hbm.xml：</p>
<pre name="code" class="xml">&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"&gt;
&lt;!-- 
    Mapping file autogenerated by MyEclipse Persistence Tools
--&gt;
&lt;hibernate-mapping&gt;
    &lt;class name="org.py.hib.relation.one2one.Card" table="card"&gt;
        &lt;id name="id" type="java.lang.String" column="id" length="32"&gt;
            &lt;generator class="uuid" /&gt;
        &lt;/id&gt;
        
        &lt;property name="cardDesc" type="java.lang.String" column="cardDesc" length="128" not-null="true"/&gt;

    &lt;/class&gt;
&lt;/hibernate-mapping&gt;
</pre>
<p>&nbsp;</p>
<p>测试代码如下：</p>
<p>One2OneTest.java</p>
<pre name="code" class="java">package org.py.hib.relation.one2one;

import junit.framework.Assert;
import junit.framework.TestCase;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.After;
import org.junit.Before;

public class One2OneTest extends TestCase
{
	private SessionFactory factory;

	private String m_name = "ryanpoy";

	private String m_name2 = "ryanpoy2";

	private String m_cardDesc1 = "desc_1";

	private String m_cardDesc2 = "desc_2";

	@Before
	public void setUp() throws Exception
	{
		Configuration conf = new Configuration().configure();
		factory = conf.buildSessionFactory();
	}

	/**
	 * 测试添加
	 * @throws Exception
	 */
	public void testSave() throws Exception
	{
		System.out.println("\n=== test save ===");

		Card card = new Card();
		card.setCardDesc(m_cardDesc1);

		Person person = new Person();
		person.setName(m_name); // 设置用户名 = m_name
		person.setCard(card);

		Session session = null;
		Transaction tran = null;
		try
		{
			session = factory.openSession();
			tran = session.beginTransaction();
			session.save(person);
			
			tran.commit();

			Assert.assertEquals(person.getId() != null, true);
			Assert.assertEquals(card.getId() != null, true);

		} catch (Exception ex)
		{
			tran.rollback();
			throw ex;
		} finally
		{
			if (session != null)
			{
				try
				{
					session.close();
				} catch (Exception ex)
				{
					// nothing to do
				} finally
				{
					if (session != null)
						session = null;
				}
			}
		}
	}

	/**
	 * 测试查询
	 * @throws Exception
	 */
	public void testFind() throws Exception
	{
		System.out.println("\n=== test find ===");
		Session session = null;
		try
		{
			session = factory.openSession();
			Person person = (Person) session.createQuery("from Person").list().get(0);

			Assert.assertEquals(true, person.getId() != null);
			Assert.assertEquals(m_name, person.getName());

			Assert.assertEquals(true, person.getCard().getId() != null);
			Assert.assertEquals(m_cardDesc1, person.getCard().getCardDesc());

		} catch (Exception ex)
		{
			throw ex;
		} finally
		{
			if (session != null)
			{
				try
				{
					session.close();
				} catch (Exception ex)
				{
					// nothing to do
				} finally
				{
					if (session != null)
						session = null;
				}
			}
		}
	}

	/**
	 * 测试修改
	 * @throws Exception
	 */
	public void testModify() throws Exception
	{
		System.out.println("\n=== test modify ===");
		Session session = null;
		Transaction tran = null;
		try
		{
			session = factory.openSession();
			tran = session.beginTransaction();

			Person person = (Person) session.createQuery("from Person").list().get(0);
			person.setName(m_name2); // 修改用户名 = m_name2.（原来用户名= m_name）
			person.getCard().setCardDesc(m_cardDesc2); // 修改cardDesc 为 m_cardDesc2 (原来是：m_cardDesc1)
			tran.commit();

		} catch (Exception ex)
		{
			throw ex;
		} finally
		{
			if (session != null)
			{
				try
				{
					session.close();
				} catch (Exception ex)
				{
					// nothing to do
				} finally
				{
					if (session != null)
						session = null;
				}
			}
		}

		/*
		 * 修改后再查询
		 */
		System.out.println("\n=== test find after modify ===");
		try
		{
			session = factory.openSession();
			Person person = (Person) session.createQuery("from Person").list().get(0);

			Assert.assertEquals(true, person.getId() != null);
			Assert.assertEquals(m_name2, person.getName());

			Assert.assertEquals(true, person.getCard().getId() != null);
			Assert.assertEquals(m_cardDesc2, person.getCard().getCardDesc());

		} catch (Exception ex)
		{
			throw ex;
		} finally
		{
			if (session != null)
			{
				try
				{
					session.close();
				} catch (Exception ex)
				{
					// nothing to do
				} finally
				{
					if (session != null)
						session = null;
				}
			}
		}
	}

	/**
	 * 测试删除
	 * @throws Exception
	 */
	public void testDelete() throws Exception
	{
		System.out.println("\n=== test delete ===");
		Session session = null;
		Transaction tran = null;
		try
		{
			session = factory.openSession();
			tran = session.beginTransaction();

			Person person = (Person) session.createQuery("from Person").list().get(0);
			session.delete(person);
			tran.commit();

		} catch (Exception ex)
		{
			throw ex;
		} finally
		{
			if (session != null)
			{
				try
				{
					session.close();
				} catch (Exception ex)
				{
					// nothing to do
				} finally
				{
					if (session != null)
						session = null;
				}
			}
		}

		/*
		 * 删除后再查询
		 */
		System.out.println("\n=== test find after delete ===");
		try
		{
			session = factory.openSession();

			Integer num = (Integer) session.createQuery("from Person").list().size();
			Assert.assertEquals(0, num.intValue());

			num = (Integer) session.createQuery("from Card").list().size();
			Assert.assertEquals(0, num.intValue());

		} catch (Exception ex)
		{
			throw ex;
		} finally
		{
			if (session != null)
			{
				try
				{
					session.close();
				} catch (Exception ex)
				{
					// nothing to do
				} finally
				{
					if (session != null)
						session = null;
				}
			}
		}
	}

	/**
	 * 
	 */
	@After
	public void tearDown() throws Exception
	{
		factory.close();
	}

}
</pre>
<p>&nbsp;</p>
<p>运行test，一路飚绿。呵呵。陶醉一番。不过，这也就是一个拿不出手的测试和一个拿不出手的例子。没有任何实际意义的例子。仅此一个demo而已。</p>
<p>在1：1中，其实还有一种方式，即：唯一主见关联。但是，我一直倾向于上面的这种形式，所以，唯一主见关联的旧部介绍了。</p>
<p>&nbsp;</p>
          <br/>
          <span style="color:red;">
            <a href="http://ryanpoy.javaeye.com/blog/189783#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 05 May 2008 16:20:37 +0800</pubDate>
        <link>http://ryanpoy.javaeye.com/blog/189783</link>
        <guid>http://ryanpoy.javaeye.com/blog/189783</guid>
      </item>
      <item>
        <title>hibernate入门使用系列 1-- 说明篇+快速构建篇</title>
        <author>RyanPoy</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://ryanpoy.javaeye.com">RyanPoy</a>&nbsp;
          链接：<a href="http://ryanpoy.javaeye.com/blog/189635" style="color:red;">http://ryanpoy.javaeye.com/blog/189635</a>&nbsp;
          发表时间: 2008年05月05日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <div style="text-align: center"><strong>说明篇</strong>
<br />
</div>
<p>
<br />
    写这个 入门使用 系列的文章，算是一个简单的复习吧。<br />
<br />
    目的1是让没有用过hibernate的工作者们，快速的使用起来。不会介绍太多的深层次的东西。仅仅是一个入门使用而已。<br />
<br />
   <br />
    目的2是总结一下hibernate的基本使用，顺便自己再熟悉熟悉。<br />
<br />
   <br />
    目的3是交流心得。一个人掌握的东西只有一点点。且掌握的程度有深有浅，如不交流、固步自封，只有被淘汰。欢迎任何人拍砖的。群众的力量是无穷的。在此系列中，难免会有些不恰当或者不对的地方。尽请指出、批评。<br />
<br />
    对于认为已经熟练掌握hibernate的高手们，可能没有什么用处。但是，无限欢迎交流。<img src="../../../images/smiles/icon_biggrin.gif" alt="" />
 <br />
<br />
废话不多说，下面开始进入主题。</p>
<div style="text-align: center"><strong>快速构建篇</strong>
<br />
</div>
<p>
一. 何谓hibernate？<br />
&nbsp;&nbsp;&nbsp;&nbsp;
答：you can find the answer @google ...<img src="../../images/smiles/icon_wink.gif" alt="" />
<br />
<br />
二. 快速构建。<br />
&nbsp;&nbsp;&nbsp;&nbsp;
在此先要说明一下。由于本人懒惰，记不住hibernate的配置选项，所以，此系列的实例都是使用myeclipse进行快速开发。各位对myeclipse不齿的，就请见谅。然后，数据库都是mysql。<br />
<br />
    下面开始利用hibernate进行数据库的访问。  <br />
<br />
    需求：实现对用户的增、删、改、查。为了方便，用户就2个属性 用户ID和用户名。实体模型如下：<br />
<br />
<img src="http://www.javaeye.com/upload/attachment/22765/839c5457-db3c-352f-b3a1-28e2844012e5-thumb.gif?1209956971" height="90" alt="" width="132" />
<br />
<br />
    建立工程:HibernateQuickUse，并且建立包。如下：<br />
<br />
<br />
<img src="http://www.javaeye.com/upload/attachment/22768/0c32152f-6318-30eb-92c4-daeba9f5ebbe-thumb.gif?1209958096" height="124" alt="" width="200" />
<br />
<br />
<br />
根据实体，创建类User，代码如下：</p>
<pre name="code" class="java">package org.py.hib.quickstart;

/**
 * User entity.
 * @author MyEclipse Persistence Tools
 */

@SuppressWarnings(&quot;serial&quot;)
public class User implements java.io.Serializable
{
	private String id;
	private String name;

	public User()
	{
	}

	public String getId()
	{
		return this.id;
	}

	public void setId(String id)
	{
		this.id = id;
	}

	public String getName()
	{
		return this.name;
	}

	public void setName(String name)
	{
		this.name = name;
	}
}
</pre>
<p>&nbsp;</p>
<p>根据实体，创建数据表。sql如下：</p>
<pre name="code" class="sql">use HibernateQuickUse;
drop table if exists User;

create table user (
	id varchar(32) primary key,
	name varchar(32)
);</pre>
<p>这里的id，我没有采用Integer auto_increment, 原因是为了数据库的数据能方便的导入到另外一种数据库里面，比方说：oracle。当然，这个是以牺牲部分效率为前提的。因为id是integer的，能更加快速查询。不过，从数据库会自动为 primary key 建立 index来看，效率也不会相差太多。</p>
<p>要想通过hibernate访问数据库。首先要建立描述数据库的文件：hibernate.cfg.xml。放到src下面。内容如下：</p>
<pre name="code" class="xml">&lt;?xml version='1.0' encoding='UTF-8'?&gt;
&lt;!DOCTYPE hibernate-configuration PUBLIC
          &quot;-//Hibernate/Hibernate Configuration DTD 3.0//EN&quot;
          &quot;http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd&quot;&gt;

&lt;hibernate-configuration&gt;

	&lt;session-factory&gt;
		&lt;property name=&quot;dialect&quot;&gt;org.hibernate.dialect.MySQLDialect&lt;/property&gt;
		&lt;property name=&quot;connection.url&quot;&gt;jdbc:mysql://localhost:3306/hibernatequickUse&lt;/property&gt;
		&lt;property name=&quot;connection.username&quot;&gt;root&lt;/property&gt;
		&lt;property name=&quot;connection.password&quot;&gt;root&lt;/property&gt;
		&lt;property name=&quot;connection.driver_class&quot;&gt;com.mysql.jdbc.Driver&lt;/property&gt;
		
		&lt;property name=&quot;show_sql&quot;&gt;true&lt;/property&gt;
		&lt;mapping resource=&quot;org/py/hib/quickstart/User.hbm.xml&quot; /&gt;

	
	&lt;/session-factory&gt;

&lt;/hibernate-configuration&gt;</pre>
<p>&nbsp;说说上面的 &quot;dialect&quot;, 这个对应着hibernate生成哪种数据库的sql。</p>
<p>&nbsp;然后是：&quot;show_sql&quot;, 这个是为了调试时候输出sql语句到屏幕用的。</p>
<p>注意&quot;mapping resource&quot;部分。这个部分表示你的 实体- 数据库 映射文件的位置。（什么是实体-数据库 映射文件，看下面。）</p>
<p>&nbsp;</p>
<p>实体-数据库映射文件 -- 主要是告诉hibernate，这个User类，对应着哪个table，User类里面的那个属性对应着table里面的哪个字段。</p>
<p>我们可以建立 实体-数据库 的xml映射文件，也可以采用Annotations映射，但是目前只说xml映射方式。如下：</p>
<pre name="code" class="xml">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;!DOCTYPE hibernate-mapping PUBLIC &quot;-//Hibernate/Hibernate Mapping DTD 3.0//EN&quot;
&quot;http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd&quot;&gt;

&lt;hibernate-mapping&gt;
	&lt;class name=&quot;org.py.hib.quickstart.User&quot; table=&quot;user&quot;&gt;
                &lt;id name=&quot;id&quot; type=&quot;java.lang.String&quot; column=&quot;id&quot; length=&quot;32&quot;&gt;
			&lt;generator class=&quot;uuid&quot; /&gt;
		&lt;/id&gt;

		&lt;property name=&quot;name&quot;  type=&quot;java.lang.String&quot; column=&quot;name&quot;	length=&quot;32&quot; /&gt;
	&lt;/class&gt;
&lt;/hibernate-mapping&gt;

</pre>
<p>&nbsp;上面的xml还是很好理解的。注意一个generator中的class，他可以有很多。我们这用的是uuid。什么是uuid。这个可以google一下。呵呵。google是最好的教科书。还能有很多其他的，比方说：native。具体的同样请教google。</p>
<p>&nbsp;有了上面的准备，那么我们开始来测试一下。这里我们用junit。具体怎么使用junit，呵呵。答案我想大家都知道了，也不用我说了。其实我对test 和 使用它也不熟练。</p>
<p>我把测试用力放到了test/org.py.hib.quickstart下面。代码如下：</p>
<pre name="code" class="java">package org.py.hib.quickstart;

import junit.framework.Assert;
import junit.framework.TestCase;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.After;
import org.junit.Before;

public class QuickStartTest extends TestCase
{
	SessionFactory factory;

	String m_name = &quot;ryanpoy&quot;;

	String m_name2 = &quot;ryanpoy2&quot;;

	@Before
	public void setUp() throws Exception
	{
		Configuration conf = new Configuration().configure();
		factory = conf.buildSessionFactory();
	}

	/**
	 * 测试添加
	 * @throws Exception
	 */
	public void testSave() throws Exception
	{
		System.out.println(&quot;\n=== test save ===&quot;);
		User u = new User();
		u.setName(m_name); // 设置用户名 = m_name

		Session session = null;
		Transaction tran = null;
		try
		{
			session = factory.openSession();
			tran = session.beginTransaction();
			session.save(u);
			tran.commit();

			Assert.assertEquals(u.getId() != null, true);
		} catch (Exception ex)
		{
			tran.rollback();
			throw ex;
		} finally
		{
			if (session != null)
			{
				try
				{
					session.close();
				} catch (Exception ex)
				{
					// nothing to do
				} finally
				{
					if (session != null)
						session = null;
				}
			}
		}
	}

	/**
	 * 测试查询
	 * @throws Exception
	 */
	public void testFind() throws Exception
	{
		System.out.println(&quot;\n=== test find ===&quot;);
		Session session = null;
		try
		{
			session = factory.openSession();
			User u = (User) session.createQuery(&quot;from User&quot;).list().get(0);

			Assert.assertEquals(true, u.getId() != null);
			Assert.assertEquals(m_name, u.getName());
		} catch (Exception ex)
		{
			throw ex;
		} finally
		{
			if (session != null)
			{
				try
				{
					session.close();
				} catch (Exception ex)
				{
					// nothing to do
				} finally
				{
					if (session != null)
						session = null;
				}
			}
		}
	}

	/**
	 * 测试修改
	 * @throws Exception
	 */
	public void testModify() throws Exception
	{
		System.out.println(&quot;\n=== test modify ===&quot;);
		Session session = null;
		Transaction tran = null;
		try
		{
			session = factory.openSession();
			tran = session.beginTransaction();

			User u = (User) session.createQuery(&quot;from User&quot;).list().get(0);
			u.setName(m_name2);  // 修改用户名 = m_name2.（原来用户名= m_name）
			tran.commit();

		} catch (Exception ex)
		{
			throw ex;
		} finally
		{
			if (session != null)
			{
				try
				{
					session.close();
				} catch (Exception ex)
				{
					// nothing to do
				} finally
				{
					if (session != null)
						session = null;
				}
			}
		}

		/*
		 * 修改后再查询
		 */
		System.out.println(&quot;\n=== test find after modify ===&quot;);
		try
		{
			session = factory.openSession();
			User u = (User) session.createQuery(&quot;from User&quot;).list().get(0);

			Assert.assertEquals(true, u.getId() != null);
			Assert.assertEquals(m_name2, u.getName());
		} catch (Exception ex)
		{
			throw ex;
		} finally
		{
			if (session != null)
			{
				try
				{
					session.close();
				} catch (Exception ex)
				{
					// nothing to do
				} finally
				{
					if (session != null)
						session = null;
				}
			}
		}
	}

	/**
	 * 测试删除
	 * @throws Exception
	 */
	public void testDelete() throws Exception
	{
		System.out.println(&quot;\n=== test delete ===&quot;);
		Session session = null;
		Transaction tran = null;
		try
		{
			session = factory.openSession();
			tran = session.beginTransaction();

			User u = (User) session.createQuery(&quot;from User&quot;).list().get(0);
			session.delete(u);
			tran.commit();

		} catch (Exception ex)
		{
			throw ex;
		} finally
		{
			if (session != null)
			{
				try
				{
					session.close();
				} catch (Exception ex)
				{
					// nothing to do
				} finally
				{
					if (session != null)
						session = null;
				}
			}
		}

		/*
		 * 删除后再查询
		 */
		System.out.println(&quot;\n=== test find after delete ===&quot;);
		try
		{
			session = factory.openSession();
			Integer num = (Integer) session.createQuery(&quot;from User&quot;).list().size();

			Assert.assertEquals(0, num.intValue());
		} catch (Exception ex)
		{
			throw ex;
		} finally
		{
			if (session != null)
			{
				try
				{
					session.close();
				} catch (Exception ex)
				{
					// nothing to do
				} finally
				{
					if (session != null)
						session = null;
				}
			}
		}
	}

	/**
	 * 
	 */
	@After
	public void tearDown() throws Exception
	{
		factory.close();
	}

}
</pre>
&nbsp;
<p>运行后，我们很欣慰的看到一路绿灯，全部通过了。那么测试没有问题。呵呵(这里的测试可能还不完善。请大家指出。前面说过，我对测试这块也不熟)。</p>
<p>看控制台，会输出如下信息：</p>
<pre name="code" class="sql">=== test save ===
Hibernate: insert into hibernatequickuse.user (name, id) values (?, ?)

=== test find ===
Hibernate: select user0_.id as id2_, user0_.name as name2_ from hibernatequickuse.user user0_

=== test modify ===
Hibernate: select user0_.id as id4_, user0_.name as name4_ from hibernatequickuse.user user0_
Hibernate: update hibernatequickuse.user set name=? where id=?

=== test find after modify ===
Hibernate: select user0_.id as id4_, user0_.name as name4_ from hibernatequickuse.user user0_

=== test delete ===
Hibernate: select user0_.id as id6_, user0_.name as name6_ from hibernatequickuse.user user0_
Hibernate: delete from hibernatequickuse.user where id=?

=== test find after delete ===
Hibernate: select user0_.id as id6_, user0_.name as name6_ from hibernatequickuse.user user0_
</pre>
&nbsp;
<p>这些，就是hibernte自动生成的。仔细看看，其实就是标准sql。呵呵。懂jdbc的都能看懂。</p>
<p>好了，第一部分就到这。附件中的zip包是原代码。</p>
<p>&nbsp;&nbsp;&nbsp; 语言的组织，举例的细节似乎像记流水账，看来还是没有文学细胞啊。忘了上次是哪位了，他写的标题就像是看 《圣斗士星矢》一项，激情洋溢啊。</p>
          <br/>
          <span style="color:red;">
            <a href="http://ryanpoy.javaeye.com/blog/189635#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 05 May 2008 11:09:29 +0800</pubDate>
        <link>http://ryanpoy.javaeye.com/blog/189635</link>
        <guid>http://ryanpoy.javaeye.com/blog/189635</guid>
      </item>
      <item>
        <title>要不要在数据库中建立主外键约束</title>
        <author>RyanPoy</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://ryanpoy.javaeye.com">RyanPoy</a>&nbsp;
          链接：<a href="http://ryanpoy.javaeye.com/blog/189259" style="color:red;">http://ryanpoy.javaeye.com/blog/189259</a>&nbsp;
          发表时间: 2008年05月04日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          今天发现一个问题。一个遗留的系统上，每个表都是独立的，没有主外键约束。问系统以前的开发人员。他们说，系统的主外键都是直接由hibernate控制的。<br />    很是不解。细问之。答曰：效率问题。<br />    问大家，到底需不需要建立呢？<br />    我先说说我的想法：<br />       其实，以前我的所有系统都是建立的。不过听了他的回答，感觉也有些道理。但是，如果上面没有控制得好，就会出现错误的数据。<br />       所以，我觉得如果系统小，就那么几十张表，业务不复杂就不需要了。系统大，表多，业务复杂那还是建立的好。<br />    说完我的想法，自己都感觉这个东西都没有必要发帖了。<br />    不过，仁者见仁，智者见智，还是想听听大家的看法。说说，大家平时怎么做的？以及为什么这么做？
          <br/>
          <span style="color:red;">
            <a href="http://ryanpoy.javaeye.com/blog/189259#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 04 May 2008 12:48:31 +0800</pubDate>
        <link>http://ryanpoy.javaeye.com/blog/189259</link>
        <guid>http://ryanpoy.javaeye.com/blog/189259</guid>
      </item>
  </channel>
</rss>