`
OracleX
  • 浏览: 123816 次
  • 性别: Icon_minigender_1
  • 来自: 地球
社区版块
存档分类
最新评论

Hibernate学习之一对一关联

阅读更多

一对一关联包括两种类型:
1.主键关联
2.惟一外键关联

主键关联:
两张关联表通过主键形成一对一映射关系
实例:一个公民对应一个身份证

1.主键关联

实体类

TUser .java

/**
 * 主键关联
 * 
 */
public class TUser implements Serializable {

	private static final long serialVersionUID = -133439792227297972L;
	private Integer id;
	private Integer age;
	private String name;
	private TPassport passport;

	..........................
}

 TPassport.java

/**
 * 主键关联
 * 
 */
public class TPassport implements Serializable{

	private static final long serialVersionUID = -2207892280100301351L;
	private Integer id;
	private String serial;
	private Integer expiry;
	private TUser user;
}

配置文件 

Tuser.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 2.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" >
<!-- 主键关联 -->    
<hibernate-mapping>
<class 
name="com.model.TUser" 
    table="t_user"
    dynamic-update="true"
>

<id
name="id"
        type="java.lang.Integer"
        column="id"
        unsaved-value="0"
>
<generator class="native" />
</id>

<property name="name" column="name" type="string"/>
<property name="age" column="age" type="java.lang.Integer"/>
<one-to-one name="passport" class="com.model.TPassport" cascade="all" outer-join="false"/>
</class>
</hibernate-mapping>

Tpassport.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 2.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" >
<!-- 主键关联 -->  
<hibernate-mapping>
<class 
name="com.model.TPassport" 
    table="t_passport"
    dynamic-update="true"
>

<id
name="id"
        type="java.lang.Integer"
        column="id"
        unsaved-value="0"
>
<!-- 由于采用了主键关联方式,那么通过主键关联的两张表,其关联记录的主键值必须保持同步。
         这也就意味着,我们只需为一张表设定主键生成策略,而另一张表的主键与之共享相同的主键值
         通过“foreign”类型的主键生成策略与外键共享主键值    
-->
<generator class="foreign">
<param name="property">user</param>
</generator>
</id>

<property name="serial" column="serial" type="string"/>
<property name="expiry" column="expiry" type="java.lang.Integer"/>
<!-- constrained必须是“true”,以告知hibernate当前表主键上存在一个约束:t_passport表引用了t_user表的主键 -->
<one-to-one name="user" class="com.model.TUser" constrained="true"/>
</class>
</hibernate-mapping>

测试代码(部分)

	//主键关联
	public void testSave() {
		TUser user = new TUser();
		user.setName("zhangsan");
		user.setAge(20);

		TPassport passport = new TPassport();
		passport.setExpiry(445555);
		passport.setSerial("PCN2324");

		// 设置相互关联
		passport.setUser(user);
		user.setPassport(passport);

		try {
			Transaction tx = session.beginTransaction();
			// 由于TUser类的one-to-one节点被设置为cascade=all,其关联的passport对象将被级联保存
			session.save(user);
			tx.commit();
		} catch (HibernateException e) {
			e.printStackTrace();
		}
	}
	//主键关联
	public void testLoad1() {
		try {
			TUser user = (TUser) session.load(TUser.class, 1);
			System.out.println("user name---->" + user.getName());
			System.out.println("passport serial---->"
					+ user.getPassport().getSerial());
		} catch (HibernateException e) {
			e.printStackTrace();
		}
		/**  out-join="true" 加载TUser实例时 hibernate通过left outer join将t_user表及其关联的t_group表同时读出
		 * Hibernate: select tuser0_.id as id1_, tuser0_.name as name1_,
		 * tuser0_.age as age1_, tpassport1_.id as id0_, tpassport1_.serial as
		 * serial0_, tpassport1_.expiry as expiry0_ from t_user tuser0_ 
		 * left outer join 
		 * t_passport tpassport1_ on tuser0_.id=tpassport1_.id where tuser0_.id=?
		 */
	}
	//主键关联
	public void testLoad2() {
		try {
			TUser user = (TUser) session.load(TUser.class, 1);
			System.out.println("user name---->" + user.getName());
			System.out.println("passport serial---->"
					+ user.getPassport().getSerial());
		} catch (HibernateException e) {
			e.printStackTrace();
		}
		/** one-to-one节点设定为 out-join="false"时,分别读取
		 * Hibernate: select tuser0_.id as id0_, tuser0_.name as name0_, tuser0_.age as age0_ from t_user tuser0_ where tuser0_.id=?
		 * Hibernate: select tpassport0_.id as id1_, tpassport0_.serial as serial1_, tpassport0_.expiry as expiry1_, tuser1_.id as id0_, tuser1_.name as name0_, tuser1_.age as age0_ from t_passport tpassport0_ left outer join t_user tuser1_ on tpassport0_.id=tuser1_.id where tpassport0_.id=?
		 */
	}

2.惟一外键关联

 实体类

TGroup.java

/**
 * 惟一外键关联实体
 */
public class TGroup implements Serializable {

	private static final long serialVersionUID = 263676571059714064L;
	private Integer id;
	private String name;
	// 不加实现的是单向一对一关系 通过Tuser2对象可以获得其相对应的Tgroup对象,但不能反过来
	// 增加是为了实现双向一对一关系 可以互相获得 并且还要在TGroup.cfg.xml中追加one-to-one配置
	private TUser2 user;

               .............................
}

TUser2.java

/**
 *惟一外键关联实体 
 */
public class TUser2 implements Serializable{
	private static final long serialVersionUID = -1898408468538505300L;
	private Integer id;
	private Integer age;
	private String name;
	private TGroup group;

                ..................
}

配置文件

TGroup.hbm.xml

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

<hibernate-mapping>
<class 
name="com.model.TGroup" 
    table="t_group"
    dynamic-update="true"
>

<id
name="id"
        type="java.lang.Integer"
        column="id"
        unsaved-value="0"
>
<generator class="native" />
</id>

<property name="name" column="name" type="string"/>

<one-to-one name="user" class="com.model.TUser2" property-ref="group"/>
</class>
</hibernate-mapping>

Tuser2.hbm.xml

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

<hibernate-mapping>
<class 
name="com.model.TUser2" 
    table="t_user2"
    dynamic-update="true"
>

<id
name="id"
        type="java.lang.Integer"
        column="id"
        unsaved-value="0"
>
<generator class="native" />
</id>

<property name="name" column="name" type="string"/>
<property name="age" column="age" type="java.lang.Integer"/>
<!-- 惟一外键关联的一对一关系只是多对一关系的一个特例而已 -->
<many-to-one name="group" class="com.model.TGroup" column="group_id" unique="true"/>
</class>
</hibernate-mapping>

测试代码(部分)

public void testSave2(){
		TGroup group=new TGroup();
		group.setName("group-one");
		
		TUser2 user=new TUser2();
		user.setName("lisi");
		user.setAge(20);
		user.setGroup(group);
		try {
			Transaction tx=session.beginTransaction();
			session.save(user);
			session.save(group); //必须保存 但先后顺序不要求
			tx.commit();
		} catch (HibernateException e) {
			e.printStackTrace();
		}
		
	}
	//单向 user---->group
	public void testLoad3(){
		try {
			TUser2 user=(TUser2) session.load(TUser2.class, 1);
			System.out.println("group name--->"+user.getGroup().getName());
		} catch (HibernateException e) {
			e.printStackTrace();
		}
	}

	//双向 group-->user
	public void testLoad4(){
		/**
		 * 在TGroup.cfg.xml中不添加one-to-one配置时,查不到user信息
		 * Hibernate: select tgroup0_.id as id0_, tgroup0_.name as name0_ from t_group tgroup0_ where tgroup0_.id=?
		   Group name---->group-one
		 */
		try {
			TGroup group=(TGroup) session.load(TGroup.class, 1);
			System.out.println("Group name---->"+group.getName());
			System.out.println("group user---->"+group.getUser().getName());
		} catch (HibernateException e) {
			e.printStackTrace();
		}
		/** 添加配置后
		 * Hibernate: select tgroup0_.id as id1_, tgroup0_.name as name1_, tuser21_.id as id0_, tuser21_.name as name0_, tuser21_.age as age0_, tuser21_.group_id as group_id0_ from t_group tgroup0_ left outer join t_user2 tuser21_ on tgroup0_.id=tuser21_.group_id where tgroup0_.id=?
			Hibernate: select tuser20_.id as id1_, tuser20_.name as name1_, tuser20_.age as age1_, tuser20_.group_id as group_id1_, tgroup1_.id as id0_, tgroup1_.name as name0_ from t_user2 tuser20_ left outer join t_group tgroup1_ on tuser20_.group_id=tgroup1_.id where tuser20_.group_id=?
			Group name---->group-one
			group user---->lisi

		 */
	}

 

分享到:
评论

相关推荐

    hibernate一对一关联关系

    本资源主要探讨的是“hibernate一对一关联关系”。 一对一关联关系在现实世界中很常见,比如一个人只有一个身份证,或者一个公司的总部只有一个。在Hibernate中,设置一对一关联关系可以帮助我们更好地管理和操作...

    Hibernate双向一对一关联映射(注解版)

    本主题聚焦于“Hibernate双向一对一关联映射”的注解实现,这是一种高级的数据库设计模式,用于处理两个实体之间一对一的关系。 在Hibernate中,一对一关联映射分为单向和双向。单向一对一映射通常涉及一个实体持有...

    hibernate使用主键关联的一对一关系

    在Java的持久化框架Hibernate中,一对一(OneToOne)关系是一种常见的对象关系映射(ORM)配置,用于表示两个实体类之间的一种唯一关联。在这个场景中,“hibernate使用主键关联的一对一关系”指的是通过共享主键来...

    hibernate一对一之唯一外键关联(双向关联)

    - 虽然一对一关联提供了便利,但过多的一对一关联可能会影响性能,因为每次查询可能涉及多个表,增加数据库访问的复杂性。因此,应谨慎设计实体间的关系。 8. **实例应用** - 在实际项目中,一对一关联常用于用户...

    Hibernate ORM - 一对一连接表关联关系

    描述部分虽然为空,但我们可以根据标题推测,这篇内容可能涉及了如何在Hibernate中配置和使用一对一关联,包括实体类的设计、注解的使用以及数据库表的结构设计等。 **知识点详解** 1. **Hibernate ORM框架**: ...

    Hibernate一对一唯一外键关联映射(双向关联)

    一、Hibernate一对一关联类型 一对一关联在现实世界中很常见,例如一个人只有一个身份证,一个身份证也只能属于一个人。在数据库设计中,这种关系通常通过主键和外键的方式实现,其中一方的主键作为另一方的外键,...

    hibernate一对一主键关联映射(单项关联)

    - **唯一性约束**:在数据库层面,为了确保一对一关联,通常需要添加唯一性约束。例如,`IdCard`表的`person_id`列应具有唯一性约束。 以上就是关于Hibernate中一对一主键关联映射(单项关联)的详细解释。通过这种...

    Hibernate一对一主键关联映射(双向关联)

    标题"Hibernate一对一主键关联映射(双向关联)"中的"主键关联"指的是两个实体通过共享相同的主键来建立关联。"双向关联"则意味着在两个实体类中,都可以直接访问到对方的实例,即在实体A中有一个对实体B的引用,...

    Hibernate一对一主键关联映射(单向关联)

    在Java的持久化框架Hibernate中,一对一(One-to-One)关联映射是常见的关系映射方式之一,尤其在处理两个实体之间存在唯一对应关系时非常有用。本篇将重点讲解如何实现一对一主键关联映射的单向关联,并通过一个...

    hibernate主键实现一对一单向关联关系源码

    首先,我们需要理解一对一关联关系的基本概念。在数据库中,一对一关系意味着两个表中的每一条记录都对应另一表中的唯一一条记录。在Hibernate中,这种关系可以通过共享主键或外键来实现。由于题目中提到的是“主键...

    hibernate外键实现一对一单向关联关系源码

    **一对一关联关系**在数据库设计中表示两个表之间存在唯一的对应关系,例如,一个人可能只有一个护照,或者一个员工只有一个职位。在Hibernate中,这种关系可以通过外键(Foreign Key)在一方或双方实体中实现。 **...

    Hibernate一对一,一对多,多对多实例

    一对一关联通常出现在两个实体之间存在唯一对应关系的情况,例如一个人只有一个身份证。在Hibernate中,可以通过在实体类的属性上使用`@OneToOne`注解来定义这种关系。此外,还需要通过`@PrimaryKeyJoinColumn`或`@...

    hibernate关联映射详解

    包含《多对多双向关联映射》《多对一单向关联映射》《多对一双向关联映射》《一对多单向关联映射》等文档,并有图解及例子,非常适合新手学习,尤其是刚刚接触hibernate,对映射关系不清楚的。。。。

    hibernate框架一对一测试案例

    学习并理解Hibernate中的一对一关联对于提升Java开发效率至关重要。通过这个测试案例,新手可以深入理解如何配置和使用`@OneToOne`注解,以及如何进行关联操作。实践中,要注意合理设置级联操作,避免数据冗余,确保...

    Hibernate 一对一关联查询.docx

    综上所述,基于外键的一对一关联在Hibernate中是通过在实体类中定义引用以及在映射文件中设置外键映射来实现的。这种关联关系提供了灵活性,但也需要注意维护关联的正确性和性能优化。在实际开发中,应根据业务需求...

    hibernate外键实现一对一双向关联关系源码

    在实际应用中,确保在两个实体类间的一对一关联正确无误非常重要。在创建和更新关联时,应避免循环引用和数据不一致的问题。在保存或更新对象时,需确保在双方都进行了正确的设置。 8. **性能考虑**: 一对一双向...

    Hibernate教程05_关系映射之一对一双向外键关联

    在Hibernate中,一对一关联的配置主要通过注解或XML配置文件完成。对于双向关联,我们需要在两个实体类中分别设置相应的属性和关联注解。 在实体类A中,我们将添加一个类型为B的属性,并使用`@OneToOne`注解来指定...

    Hibernate 一对一外键单向关联

    在Hibernate中,一对一(One-to-One)映射是一种常见的关联关系,它表示两个实体之间存在一对一的对应关系。本篇文章将深入探讨Hibernate中的一对一外键单向关联。 首先,一对一外键关联指的是一个实体通过外键直接...

    Hibernate ORM - 一对一主键关联关系

    - **外键约束**:在一对一关联中,如果不使用共享主键,可以创建外键约束,但这样就不再是真正的“主键关联”。 - **懒加载与立即加载**:默认情况下,关联对象会在加载主对象时一同加载,这称为“立即加载”。若...

    hibernate一对一之唯一外键关联(单向关联)

    在这个场景下,我们将讨论一种特殊的一对一关联方式——唯一外键关联(Single ForeignKey Association),且为单向关联。这种关联方式意味着在一个实体中有一个字段作为另一个实体的主键引用。 首先,我们需要理解...

Global site tag (gtag.js) - Google Analytics