首页 > WEB开发 > 后台开发 > Hibernate关联关系映射及CRUD
2014
10-18

Hibernate关联关系映射及CRUD

07. Hibernate关联关系映射及CRUD21

标题中的“关系”指的是对象之间的关系。在《类与类(接口)之间的关系》一文中介绍了三种对象关系,本文只讨论对象之间的关联关系及其到数据库中关系模型的映射。对象之间的关联关系又可分为如下三种:

  • 一对多 / 多对一
  • 多对多
  • 一对一

关联具有一定的方向性:如果仅能从一个类单方向地访问另一个类,则被称为单向关联,因此上面的几种关联关系还可以再细分为单向和双向两种。

Hibernate中通过xml(映射文件)或注解配置对象模型到关系模型之间的映射。【注:就是java对象 –> 数据表】

下面分别介绍如何配置这几种关联关系到相应关系表的映射,行文思路如下:

① 介绍对应的关系表如何设计

② 分别用xml和注解的方式实现映射。

一、关系映射

1、一对多 / 多对一

对象之间一对多 / 多对一的关系体现在数据库表中如下图:

07. Hibernate关联关系映射及CRUD432

1)一对多单向

由一的一方维护关系(☆):

07. Hibernate关联关系映射及CRUD456

① xml映射文件配置

Group.hbm.xml:注意<set>元素的配置-----------
<class name="org.flyne.domain.Group" table="groups">
	<id name="id" column="id">
		<generator class="increment"></generator>
	</id>

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

	<set name="persons">
		<key column="gid"></key>
		<one-to-many class="org.flyne.domain.Person"/>
	</set>
</class>

② Annotation(Group类的定义如下)

@Entity
@Table(name="groups")
public class Group implements Serializable {
	private Integer id;
	private String name;

	private Set<Person> persons = new HashSet<Person>();

	@Id
	@GeneratedValue
	public Integer getId() {
		return id;
	}

	@OneToMany
	@JoinColumn(name="gid")
	public Set<Person> getPersons() {
		return persons;
	}
…………其他setter、getter从省………………
}

2)多对一单向

由多的一方维护关系(☆):

07. Hibernate关联关系映射及CRUD1223

① xml

<class name="org.flyne.domain.Person" table="persons">
	<id name="id" column="id">
		<generator class="increment"></generator>
	</id>

	<property name="name" column="name"></property>
	<many-to-one name="group" column="gid"></many-to-one>
</class>

② 注解:@ManyToOne

@Entity
@Table(name="persons")
public class Person {
	private Integer id;
	private String name;

	private Group group;

	@ManyToOne
	@JoinColumn(name="gid")
	public Group getGroup() {
		return group;
	}
	@Id
	@GeneratedValue
	public Integer getId() {
		return id;
	}
…………其他setter、getter从省………………
}

3)一对多双向

一对多、多对一双向是同一种情况,双方都要维护关系(☆):

07. Hibernate关联关系映射及CRUD1836

① xml配置方式

Person.hbm.xml同多对一、Group.hbm.xml同一对多

② 注解方式

@Entity
@Table(name="persons")
public class Person {
	private Integer id;
	private String name;

	private Group group;

	@ManyToOne
	@JoinColumn(name="gid")
	public Group getGroup() {
		return group;
	}
	@Id
	@GeneratedValue
	public Integer getId() {
		return id;
	}
…………其他setter、getter从省………………
}

@Entity
@Table(name="groups")
public class Group implements Serializable {
	private Integer id;
	private String name;
	private Set<Person> persons = new HashSet<Person>();

	@OneToMany(mappedBy="group")
	public Set<Person> getPersons() {
		return persons;
	}
	@Id
	@GeneratedValue
	public Integer getId() {
		return id;
	}
…………其他setter、getter从省………………
}

小技巧1:双向关联必须要设置mappedBy,不管是一对多、多对一还是多对多。

小技巧2:mappedBy是设置在“一”的一方还是“多”的一方?

在“一”的一方设置mappedBy比较好,即以“多”的一方为主导。因为在数据库表里,关联关系本来就是设置在多的一方。所以在OneToMany一方设mappedBy。

2、多对多

数据库中的表应该这样设计:

07. Hibernate关联关系映射及CRUD2726

1)多对多单向

07. Hibernate关联关系映射及CRUD2736

① xml配置

Teacher.hbm.xml-----------------
<class name="org.flyne.domain.Teacher" table="teachers">
	<id name="id" column="id">
		<generator class="increment"></generator>
	</id>

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

	<set name="students" table="teachers_students">
		<key column="tid"></key>
		<many-to-many column="sid" class="org.flyne.domain.Student"></many-to-many>
	</set>
</class>

② 注解

@Entity
@Table(name="teachers")
public class Teacher implements Serializable {
	private Integer id;
	private String name;

	private Set<Student> students = new HashSet<Student>();

	@Id
	@GeneratedValue
	public Integer getId() {
		return id;
	}

	@ManyToMany
	@JoinTable(
		name="teachers_students",
		joinColumns={@JoinColumn(name="tid")},
		inverseJoinColumns={@JoinColumn(name="sid")}
	)
	public Set<Student> getStudents() {
		return students;
	}

…………其他setter、getter从省………………
}

2)多对多双向(用的少)

07. Hibernate关联关系映射及CRUD3643

① XML配置

Teacher部分没变

Student.hbm.xml部分如下

<class name="org.flyne.domain.Student" table="students">
	<id name="id" column="id">
		<generator class="increment"></generator>
	</id>

	<property name="name" column="name"></property>
	<set name="teachers" table="teachers_students">
		<key column="sid"></key>
		<many-to-many column="tid" class="org.flyne.domain.Teacher"></many-to-many>
	</set>
</class>

② 注解

Teacher类的定义同上

@Entity
@Table(name="students")
public class Student implements Serializable {

	private Integer id;
	private String name;

	private Set<Teacher> teachers = new HashSet<Teacher>();

	@Id
	@GeneratedValue
	public Integer getId() {
		return id;
	}

	@ManyToMany(mappedBy="students")
	public Set<Teacher> getTeachers() {
		return teachers;
	}
…………其他setter、getter从省………………
}

3、一对一

数据库的设计:

07. Hibernate关联关系映射及CRUD4452

1)一对一单向关联

07. Hibernate关联关系映射及CRUD4464

① XML文件配置:Husband.hbm.xml

<class name="org.flyne.domain.Husband" table="husbands">
	<id name="id" column="id">
		<generator class="increment"></generator>
	</id>

	<property name="name" column="name"></property>
	<many-to-one name="wife" column="wid" unique="true"></many-to-one>
</class>

注:Hibernate中,一对一单向外键关联的xml配置方式为:<many-to-one unique=”true”>!

② 注解配置

@Entity
@Table(name="husbands")
public class Husband implements Serializable {
	private Integer id;
	private String name;

	private Wife wife; //wife不要实例化!

	@Id
	@GeneratedValue
	public Integer getId() {
		return id;
	}
	@OneToOne
	@JoinColumn(name="wid")
	public Wife getWife() {
		return wife;
	}
…………其他setter、getter从省………………
}

2)一对一双向关联

07. Hibernate关联关系映射及CRUD5169

① XML方式:Wife.hbm.xml

<class name="org.flyne.domain.Wife" table="wifes">
	<id name="id" column="id">
		<generator class="increment"></generator>
	</id>

	<property name="name" column="name"></property>
	<one-to-one name="husband" property-ref="wife"></one-to-one>
</class>

② 注解方式

@Entity
@Table(name="wifes")
public class Wife implements Serializable {
	private Integer id;
	private String name;

	private Husband husband;

	@OneToOne(mappedBy="wife")
	public Husband getHusband() {
		return husband;
	}

	@Id
	@GeneratedValue
	public Integer getId() {
		return id;
	}
…………其他setter、getter从省………………
}

4、组件映射

组件映射是一对一关联的特殊情况

07. Hibernate关联关系映射及CRUD5799

1)XML文件配置

<class name="org.flyne.domain.Husband" table="husbands">
	<id name="id" column="id">
		<generator class="increment"></generator>
	</id>

	<property name="name" column="name"></property>
	<component name="wife">
		<property name="wifename" column="wifename" />
		<property name="wifeage" column="wifeage" />
	</component>
</class>

2)Annotation配置:@Embeded

由于只需要生成husbands一张表,所以只需在hibernate.cfg.xml中引入Husband即可。

@Entity
@Table(name="husbands")
public class Husband implements Serializable {
	private Integer id;
	private String name;

	private Wife wife;

	@Id
	@GeneratedValue
	public Integer getId() {
		return id;
	}

	@Embedded
	public Wife getWife() {
		return wife;
	}
…………其他setter、getter从省………………
}

留下一个回复

你的email不会被公开。