Hibernate四 关联关系之双向关联

双向关联

一 双向1--N关联

1.无连接表的双向1--N关联

N的一端需要使用@ManyToOne注解来修饰代表关联实体的属性,1的一端需要使用@OneToMany注解来修饰代表关联实体的属性。

双向关联应该由N的一端来控制关联关系,因此在使用@OneToMany注解时指定mappedBy属性。一旦为@OneToMany,@ManyToMany指定了该属性,则表明当前实体不能控制关联关系,一旦当前实体放弃控制关联关系后,hibernate就不允许使用@JoinColumn或@JoinTable修饰代表关联实体的属性了。

Person.java

@Entity

@Table(name="person_info")

public class Person {

@Id

@Column(name="person_id")

@GeneratedValue(strategy=GenerationType.AUTO)

private Integer id;

private String name;

private int age;

@OneToMany(targetEntity=Address.class,mappedBy="person")

private Set<Address> addresses=new HashSet<>();

...

}

Address.java

@Entity

@Table(name="address_info")

public class Address {

@Id

@Column(name="address_id")

@GeneratedValue(strategy=GenerationType.AUTO)

private int addressId;

private String adressDetail;

@ManyToOne(targetEntity=Person.class)

@JoinColumn(name="person_id",referencedColumnName="person_id",nullable=false)

private Person person;

...

}

测试:

public class myTest {

public static void main(String[] args) {

Configuration config=new Configuration().configure();

SessionFactory factory=config.buildSessionFactory();

Session session=factory.openSession();

Transaction tx=session.beginTransaction();

Person p=new Person();

p.setName("lyy");p.setAge(22);

session.save(p);   //持久化person对象

Address a=new Address("北京");

a.setPerson(p);    //设置person和address之间的关联关系

session.persist(a); //持久化address对象

Address a2=new Address("南京");

a2.setPerson(p);

session.persist(a2);

tx.commit();

session.close();

}

}

注意:最好先持久化Person对象或者该Person对象已经处于持久化状态,因为程序希望持久化Address对象时,Hibernate可以为Address的外键属性分配值。也就是说,向address_info数据表插入记录时,该记录的外键列已指定了值,着表明它参照的主表记录已存在。

不要通过Person对象来设置关联关系,因为在Person映射注解中指定了@mappedBy属性

2.有连接表的双向1--N关联

只要在N的一端使用@JoinTable显式指定连接表即可

Address.java

@Entity

@Table(name="address_info")

public class Address {

@Id

@Column(name="address_id")

@GeneratedValue(strategy=GenerationType.AUTO)

private int addressId;

private String adressDetail;

@ManyToOne(targetEntity=Person.class)

@JoinTable(name="person_address",

[email protected](name="address_id",referencedColumnName="address_id"),

[email protected](name="person_id",referencedColumnName="person_id"))

private Person person;

...

}

如果程序希望Person实体也可以控制关联关系,则可以将Person.java修改为:

@Entity

@Table(name="person_info")

public class Person {

@Id

@Column(name="person_id")

@GeneratedValue(strategy=GenerationType.AUTO)

private Integer id;

private String name;

private int age;

@OneToMany(targetEntity=Address.class)

@JoinTable(name="person_address",

[email protected](name="person_id",referencedColumnName="person_id"),

[email protected](name="address_id",referencedColumnName="address_id",unique=true))

private Set<Address> addresses=new HashSet<>();

...

}

二 双向N--N关联

两端都需要使用Set集合属性,双向N--N关联只能采用连接表来建立两个实体间的关联关系

Person.java

@Entity

@Table(name="person_info")

public class Person {

@Id

@Column(name="person_id")

@GeneratedValue(strategy=GenerationType.AUTO)

private Integer id;

private String name;

private int age;

@OneToMany(targetEntity=Address.class)

@JoinTable(name="person_address",

[email protected](name="person_id",referencedColumnName="person_id"),

[email protected](name="address_id",referencedColumnName="address_id",unique=true))

private Set<Address> addresses=new HashSet<>();

...

}

Address.java

@Entity

@Table(name="address_info")

public class Address {

@Id

@Column(name="address_id")

@GeneratedValue(strategy=GenerationType.AUTO)

private int addressId;

private String adressDetail;

@ManyToOne(targetEntity=Person.class)

@JoinTable(name="person_address",

[email protected](name="address_id",referencedColumnName="address_id"),

[email protected](name="person_id",referencedColumnName="person_id"))

private Person person;

...

}

三 双向1--1关联

两端都要使用@OneToOne注解进行映射,外键可以存放在任意一端,即通过@JoinColumn注解来映射外键列。一旦选择其中的一端来增加外键,该表即变为从表,另一个表则为主表。

双向1--1关联的主表对应的实体,也不应该用于控制关联关系,因此要用mappedBy属性

1.基于外键的双向1--1关联

Person.java

@Entity

@Table(name="person_info")

public class Person {

@Id

@Column(name="person_id")

@GeneratedValue(strategy=GenerationType.AUTO)

private Integer id;

private String name;

private int age;

@OneToOne(targetEntity=Address.class,mappedBy="person")

private Address address;

...

}

Address.java

@Entity

@Table(name="address_info")

public class Address {

@Id

@Column(name="address_id")

@GeneratedValue(strategy=GenerationType.AUTO)

private int addressId;

private String adressDetail;

@OneToOne(targetEntity=Person.class)

@JoinColumn(name="person_id",referencedColumnName="person_id",unique=true)

...

}

测试:

public class myTest {

public static void main(String[] args) {

Configuration config=new Configuration().configure();

SessionFactory factory=config.buildSessionFactory();

Session session=factory.openSession();

Transaction tx=session.beginTransaction();

Person p=new Person("lu",23);

Address a=new Address("nanjing");

p.setAddress(a);

session.save(p); session.save(a);

tx.commit();

session.close();

}

}

时间: 2024-10-03 05:34:34

Hibernate四 关联关系之双向关联的相关文章

Hibernate三 关联关系之单向关联

一 分类Hibernate的关联关系可分为:单向关联和双向关联单向关联包括:1->1 1->N N->1 N->N 双向关联包括:1->1 1->N N->N二 单向N->1关联1.程序应该在N的一端的持久化类中增加一个属性,该属性引用1的一端的关联实体对于N->1关联,都需要在N的一端使用@ManyToOne修饰代表关联实体的属性,该注解可以指定以下属性:(1)cascade:指定Hibernate对关联实体采用怎样的级联策略,包括以下五种情况:Ca

Hibernate一对一外键双向关联(Annotation配置)

如上图所示:一个学生有一个学生证号,一个学生证号对应一名学生.在Hibernate中怎么用Annotation来实现呢? 学生类,主键是id:学生证的主键也是Id: Student.java package edu.xaut.hibernate; import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persisten

Hibernate多对多双向关联的配置

Hibernate的双向多对多关联有两种配置方法:那我们就来看看两种方案是如何配置的.  一.创建以各自类为类型的集合来关联 1.首先我们要在两个实体类(雇员<Emploee>.工程<Project>)中各自给对方添加一个对方的集合 1.1 雇员实体类 package cn.manytomany.one; import java.util.HashSet; import java.util.Set; public class Emploee { //雇员id private Int

hibernate(四)一对多单向、多对一双向、自身双向关联

?经过前几篇文章的简略总结,主要认识了关于hibernate的基本认识,顺便认识了hibernate的简单的一个原理.具体参见 Hibernate (一)hibernate入门 Hibernate(二)hibernate原理简单实现对比JDBC hibernate(三)入门级--hibernate实例 从这篇文章开始就接触具体hibernate是如何来配置使用,更多的是一些细节的掌握.首先需要声明的是作者也是在诸多资料和工作学习中不断在更新自己关于知识的理解,难免出现一些在现阶段的主观认识和片面

【Hibernate步步为营】--(一对多映射)之双向关联

上篇文章讨论了单向关联的一对多映射,在一的一端维护双向的关系这样的做法尽管能实现可是存在非常多缺陷,首先生成非常多多余的SQL语句,由于多的一端不维护关系,仅仅有一的一端维护,在进行操作时一的一端会发出多余的update语句:其次,由于多的一端不知道一的一端存在,所以在保存多的一端时假设外键为null值,而且在设计数据库时关系字段设为非空,则将无法保存数据.由于单向关联一对多存在非常多缺点那就没有其他的办法了吗,能够採用双向关联来优化. 一.一对多双向关联 这里继续採用上篇文章的学生和班级作为演

【Hibernate步步为营】--双向关联一对一映射具体解释(一)

一对一的映射在对象模型中是常常见到的,为了将对象模型转换为关系模型就必须在映射文件里进行配置,上篇文章讨论了一对一映射的单向关联的情况,重点是<one-to-one>标签的使用,须要在映射的主对象中加入该标签,并将该对象的主键设置为foreign这样就实现了主键关联映射.讨论完了单向接下来讨论双向映射. 一.双向主键关联 双向的主键关联事实上是单向一对一主键关联的一种特殊情况.仅仅只是要在关联对象的两端的映射文件里都要进行<one-to-one>的配置.另外还要在主映射的主键一端採

【Hibernate步步为营】--双向关联一对一映射详解(二)

很不好意思,有两天时间没有更新博客文章了,不写文章的日子还真是感觉很空洞啊,养成了写文章的恶习想改也改不掉啊.说点题外话,前两天收到一位朋友的私信,邀请笔者写一篇有关OWS的文章,用来研究图标工具的一种技术,很荣幸收到这位朋友的邀请,但是因为这几天开发的项目着急上线所以暂时没有时间去研究,只能等这周末了,利用周末的时间来研究然后更新类似的技术文章. 回到文章的正题,上篇文章讨论了双向主键关联,它其实是一对一主键关联的一种特殊情况,想要实现双向的关联就必须在映射文件的两端同时配置<one-to-o

Hibernate映射多对多双向关联关系(小案例)

多对多双向关联关系(Project(工程)/Emp(员工)为案例): 步骤如下: 1.创建Project类,并需要定义集合类型的Emp属性 public class Project { //编号 private Integer pid; //名称 private String pname; //定义集合类型的Emp属性 private Set<Emp> emps=new HashSet<Emp>(); public Integer getPid() { return pid; }

Hibernate中用注解配置一对多双向关联和多对一单向关联

Hibernate中用注解配置一对多双向关联和多对一单向关联 Hibernate提供了Hibernate Annotations扩展包,使用注解完成映射.在Hibernate3.3之前,需单独下载注解开发包 配置持久化类 配置关联关系 下面我们先从多对一单向关联关系讲起,多对一单向关联就是在多的一方植入一的一方的主键作为外键,下面我们先进行初始配置, 在配置的过程中我们会遇到一个问题  就是无论用load还是get都不会出现延迟加载,那么我们应该如何设置为要延迟加载,这样做的好处是可以在用的时候