`
RyanPoy
  • 浏览: 50409 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

hibernate入门使用系列 2-- xml关系映射篇(上)

阅读更多

接上篇 hibernate入门使用系列 1-- 说明篇+试用篇

现在起主要讲 hibernate中的关系映射。对应的关系主要有 1:1, n:1, n:n。今天主要写1:1。

关系映射篇(上)—— 之1:1

1对1的关系在现实中很常见。比方说:人和身份证。1个身份证对应着一个身份证,一个身份证对应着一个人。那么,我们就以此为原型。进行代码编写。

建立实体模型如右:

 

根据模型,创建数据库:

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)
);


 

java代码如下:

Person类

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;
	}

}

 

Card类:

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;
	}
}

 

xml映射文件如下:

Person.hbm.xml

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
	<class name="org.py.hib.relation.one2one.Person" table="person">
		<id name="id" type="java.lang.String" column="id" length="32">
			<generator class="uuid" />
		</id>

		<property name="name" type="java.lang.String">
			<column name="name" length="32" />
		</property>

		<many-to-one name="card" class="org.py.hib.relation.one2one.Card" unique="true"
			cascade="all" column="card_id" />
			
	</class>
</hibernate-mapping>

今天讲的是one-to-one配置。但是,此处用的是many-to-one,这个是什么原因呢?其实,one-to-one就是特殊的many-to-one。

Card.hbm.xml:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- 
    Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
    <class name="org.py.hib.relation.one2one.Card" table="card">
        <id name="id" type="java.lang.String" column="id" length="32">
            <generator class="uuid" />
        </id>
        
        <property name="cardDesc" type="java.lang.String" column="cardDesc" length="128" not-null="true"/>

    </class>
</hibernate-mapping>

 

测试代码如下:

One2OneTest.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();
	}

}

 

运行test,一路飚绿。呵呵。陶醉一番。不过,这也就是一个拿不出手的测试和一个拿不出手的例子。没有任何实际意义的例子。仅此一个demo而已。

在1:1中,其实还有一种方式,即:唯一主见关联。但是,我一直倾向于上面的这种形式,所以,唯一主见关联的旧部介绍了。

 

  • 大小: 2.8 KB
分享到:
评论
12 楼 only_java 2009-01-12  
RyanPoy 写道

only_java 写道
在测试你的函数testsave时,结果为: Hibernate: insert into card (cardDesc, id) values (?, ?) Hibernate: insert into person (name, card_id, id) values (?, ?, ?) 我照着你的例子重新做的时候,却发现结果是:(报异常) Hibernate: insert into hibernatequickuse.person (name, card_id) values (?, ?) Hibernate: update card set NAME=? where ID=? 不同的是主键的生成方式不一样,你用的是uuid,我用的是identity,数据库自动增长 看了你帖的代码。看不出什么问题。不过从生成的sql语句不同。可以看出,你的配置和我的不一样。不是说主键配置不同。肯定还有其他的地方不同。你再看看。

谢谢,问题解决了!sql是我改动了些,但还是保持单向多对一的,原因是我映射文件的头部是引用2.0的Hibernate,而包却是3.0的!
11 楼 RyanPoy 2009-01-09  
only_java 写道
在测试你的函数testsave时,结果为:
Hibernate: insert into card (cardDesc, id) values (?, ?)
Hibernate: insert into person (name, card_id, id) values (?, ?, ?)
我照着你的例子重新做的时候,却发现结果是:(报异常)
Hibernate: insert into hibernatequickuse.person (name, card_id) values (?, ?)
Hibernate: update card set NAME=? where ID=?
不同的是主键的生成方式不一样,你用的是uuid,我用的是identity,数据库自动增长



看了你帖的代码。看不出什么问题。不过从生成的sql语句不同。可以看出,你的配置和我的不一样。不是说主键配置不同。肯定还有其他的地方不同。你再看看。

10 楼 only_java 2009-01-07  
在测试你的函数testsave时,结果为:
Hibernate: insert into card (cardDesc, id) values (?, ?)
Hibernate: insert into person (name, card_id, id) values (?, ?, ?)
我照着你的例子重新做的时候,却发现结果是:(报异常)
Hibernate: insert into hibernatequickuse.person (name, card_id) values (?, ?)
Hibernate: update card set NAME=? where ID=?
不同的是主键的生成方式不一样,你用的是uuid,我用的是identity,数据库自动增长


        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); //应该先执行insert person才对啊????  
               
            tran.commit();   
  

9 楼 only_java 2008-12-29  
one-to-one就是特殊的many-to-one
能否解释下?
8 楼 liucl_tiger 2008-10-24  
能不能用SSH框架写一个出来看一下呢!
还是感受很深!
7 楼 tianzhijie11 2008-10-23  
谢谢文章写的不错。太感谢了
6 楼 RyanPoy 2008-06-22  
wxb_love 写道
楼主的id好象不是递增的啊,要加个递增怎么弄啊。


1.修改数据库的主键为auto_increment
2.修改pojo的主键为integer
3.修改hbm.xml中的id的generator ,把uuid改成为native


5 楼 wxb_love 2008-06-17  
楼主的id好象不是递增的啊,要加个递增怎么弄啊。
4 楼 RyanPoy 2008-06-17  
tjlvan 写道
弱弱的问一下 删除person的时候为什么会把card也干掉啊 他们不是对于数据库两张表么 具体需要怎么设置

参看Person.hbm.xml配置文件中16行有这样子的一句话: cascade="all"
这里的cascade设置成为了all,那么就出现了你说的这个现象。

其实cascade有很多中设置:create, merge, save-update, delete, lock, refresh, evict, replicate。。。
每一种都有其不同的含义。具体的请google一下。
如果要想删除person而不删除card,请修改为:delete-orphan

3 楼 tjlvan 2008-05-31  
弱弱的问一下 删除person的时候为什么会把card也干掉啊 他们不是对于数据库两张表么 具体需要怎么设置
2 楼 RyanPoy 2008-05-07  
hantsy 写道

这个只是单向关联one-to-one ,而且是不严格的,不准确的,你要指明many-to-one是表示一个“一对一”关系,至少要用上unique。

多谢指出。已经修改过了。源代码也已经修改了。

hantsy 写道

one-to-one ,有很多东西可以讨论。
1.单向关联或双向关联

确实有单项关联和双向关联这2种。且任何的关系(1:1, ... n:n)都有单项和双向之分。在这个例子中里面我只用了单项。
抽空补上双向。

hantsy 写道

2.使用cascade

这个我一直认为且只认为代表级联操作,我觉得与1:1, ... , n:n都没有关系。

hantsy 写道

3.使用中间表

这个在n:n中,倒是用过。不知道你说的1:1中,采用中间表是什么意思。
是指临时表么?






1 楼 hantsy 2008-05-07  
这个只是单向关联one-to-one ,而且是不严格的,不准确的,你要指明many-to-one是表示一个“一对一”关系,至少要用上unique。
one-to-one ,有很多东西可以讨论。
1.单向关联或双向关联
2.使用cascade
3.使用中间表

相关推荐

    Hibernate入门.docx

    Hibernate是一种ORM框架,全称为 Object_Relative DateBase-Mapping ,在Java对象与关系数据库之间 建立某种映射,以实现直接存取Java对象 ! 为什么要使用Hibernate? 既然Hibernate是关于Java对象和关系数据库...

    Hibernate_3.2.0_符合Java习惯的关系数据库持久化

    1. Hibernate入门 1.1. 前言 1.2. 第一部分 - 第一个Hibernate应用程序 1.2.1. 第一个class 1.2.2. 映射文件 1.2.3. Hibernate配置 1.2.4. 用Ant构建 1.2.5. 启动和辅助类 1.2.6. 加载并存储对象 1.3. 第...

    Struts2+Spring+Hibernate整合入门详解

    Hibernate 是一个纯 Java 的对象关系映射和持久性框架,它允许您用 XML 配置文件把普通 Java 对象映射到关系数据库表。使用 Hibernate 能够节约大量项目开发时间,因为整个 JDBC 层都由这个框架管理。这意味着您的...

    HibernateAPI中文版.chm

    1. Hibernate入门 1.1. 前言 1.2. 第一部分 - 第一个Hibernate应用程序 1.2.1. 第一个class 1.2.2. 映射文件 1.2.3. Hibernate配置 1.2.4. 用Ant构建 1.2.5. 启动和辅助类 1.2.6. 加载并存储对象 1.3. 第...

    hibernate3.2中文文档(chm格式)

    1. Hibernate入门 1.1. 前言 1.2. 第一部分 - 第一个Hibernate应用程序 1.2.1. 第一个class 1.2.2. 映射文件 1.2.3. Hibernate配置 1.2.4. 用Ant构建 1.2.5. 启动和辅助类 1.2.6. 加载并存储对象 1.3. 第...

    hibernate基础

    主要内容包括Hibernate的基本体系结构、如何使用Java5注解和基于XML的映射文件来表示映射信息,并讨论了HibernateSession对象和HQL的使用。本书结合大量实际代码,力图使读者能够更好地学习并掌握Hibernate的使用。...

    搞定J2EE:STRUTS+SPRING+HIBERNATE整合详解与典型案例 (2)

    12.5 使用Hibernate的工具快速生成映射文件和POJO 12.5.1 使用MiddleGen根据数据库产生映射文件 12.5.2 使用hbm2java根据映射文件产生POJO 12.6 整合Struts、Spring和Hibernate实现用户管理 12.6.1 Struts、Spring和...

    Hibernate+中文文档

    1. Hibernate入门 1.1. 前言 1.2. 第一部分 - 第一个Hibernate应用程序 1.2.1. 第一个class 1.2.2. 映射文件 1.2.3. Hibernate配置 1.2.4. 用Ant构建 1.2.5. 启动和辅助类 1.2.6. 加载并存储对象 1.3. 第...

    搞定J2EE:STRUTS+SPRING+HIBERNATE整合详解与典型案例 (1)

    12.5 使用Hibernate的工具快速生成映射文件和POJO 12.5.1 使用MiddleGen根据数据库产生映射文件 12.5.2 使用hbm2java根据映射文件产生POJO 12.6 整合Struts、Spring和Hibernate实现用户管理 12.6.1 Struts、Spring和...

    Hibernate框架参考文档

    1. Hibernate入门; 2. 体系结构(Architecture); 3. 配置; 4. 持久化类(Persistent Classes); 5. 对象/关系数据库映射基础(Basic O/R Mapping); 6. 集合类(Collections)映射; 7. 关联关系映射; 8. 组件(Component)...

    Hibernate中文详细学习文档

    1. Hibernate入门 1.1. 前言 1.2. 第一部分 - 第一个Hibernate应用程序 1.2.1. 第一个class 1.2.2. 映射文件 1.2.3. Hibernate配置 1.2.4. 用Ant构建 1.2.5. 启动和辅助类 1.2.6. 加载并存储对象 1.3. 第...

    搞定J2EE:STRUTS+SPRING+HIBERNATE整合详解与典型案例 (3)

    12.5 使用Hibernate的工具快速生成映射文件和POJO 12.5.1 使用MiddleGen根据数据库产生映射文件 12.5.2 使用hbm2java根据映射文件产生POJO 12.6 整合Struts、Spring和Hibernate实现用户管理 12.6.1 Struts、Spring和...

    hibernate+中文api

    1. Hibernate入门 1.1. 前言 1.2. 第一部分 - 第一个Hibernate应用程序 1.2.1. 第一个class 1.2.2. 映射文件 1.2.3. Hibernate配置 1.2.4. 用Ant构建 1.2.5. 启动和辅助类 1.2.6. 加载并存储对象 1.3. 第...

    Hibernate 中文 html 帮助文档

    1. Hibernate入门 1.1. 前言 1.2. 第一部分 - 第一个Hibernate应用程序 1.2.1. 第一个class 1.2.2. 映射文件 1.2.3. Hibernate配置 1.2.4. 用Ant构建 1.2.5. 启动和辅助类 1.2.6. 加载并存储对象 1.3. 第...

    Hibernate框架介绍以及入门 【二】Hibernate的常见配置

    Hibernate框架介绍以及入门 【二】 Hibernate的常见配置 一、关于XML提示的配置 1、配置hibernate-mapping-3.0.dtd – XML 配置这三个地方 第一个;location 第二个:URL 第三个: 2、配置hibernate-...

    hibernate 体系结构与配置 参考文档(html)

    1. Hibernate入门 1.1. 前言 1.2. 第一部分 - 第一个Hibernate应用程序 1.2.1. 第一个class 1.2.2. 映射文件 1.2.3. Hibernate配置 1.2.4. 用Ant构建 1.2.5. 启动和辅助类 1.2.6. 加载并存储对象 1.3. 第...

    Hibernate O/R Mapping 入门工程包

    Hibernate 快速入门的工程包 包括用xml和annotation映射数据表

    Hibernate教程

    2. Hibernate入门 2.1. 前言 2.2. 第一部分 - 第一个Hibernate程序 2.2.1. 第一个class 2.2.2. 映射文件 2.2.3. Hibernate配置 2.2.4. 用Ant编译 2.2.5. 安装和帮助 2.2.6. 加载并存储对象 2.3. 第二部分 ...

    hibernate3.04中文文档.chm

    2. Hibernate入门 2.1. 前言 2.2. 第一部分 - 第一个Hibernate程序 2.2.1. 第一个class 2.2.2. 映射文件 2.2.3. Hibernate配置 2.2.4. 用Ant编译 2.2.5. 安装和帮助 2.2.6. 加载并存储对象 2.3. ...

    Hibernate参考文档

    1. Hibernate入门 1.1. 前言 1.2. 第一部分 - 第一个Hibernate应用程序 1.2.1. 第一个class 1.2.2. 映射文件 1.2.3. Hibernate配置 1.2.4. 用Ant构建 1.2.5. 启动和辅助类 1.2.6. 加载并存储对象 1.3. 第...

Global site tag (gtag.js) - Google Analytics