1.什么是关联关系?
关联关系是指两个实体或者表有相互关联,比如在学生表中,学生表有班级id,那么学生表中的班级id就关联班级表中班级Id字段。因此关联关系,可以看成是一种外键关系。
2.为什么要有关联关系?
为了实现级联操作,删除班级中某个学生,会连带删除学生表中的学生,以便维护表数据的一致性。
3.hibernate中实现关联关系
3.1单向一对多关系
package com.hibernate.hibernate_one2many;
import java.io.Serializable;
public class Student implements Serializable {
private static final long serialVersionUID = 1L;
private Integer sid;
private String sname;
private String sex;
public Student() {
}
public Student(String sname, String sex) {
this.sname = sname;
this.sex = sex;
}
//以下省略setter和getter方法
}
package com.hibernate.hibernate_one2many;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
public class Grade implements Serializable {
private static final long serialVersionUID = 1L;
private Integer gid;
private String gname;
private String descs;
private Set<Student> students = new HashSet<Student>();;
public Grade() {
}
public Grade(String gname, String descs) {
this.gname = gname;
this.descs = descs;
}
//以下省略setter和getter方法
}
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.hibernate.hibernate_one2many">
<class name="Grade" table="Grade">
<id name="gid" column="GID" type="java.lang.Integer">
<generator class="increment"></generator>
</id>
<property name="gname" column="GNAME" type="java.lang.String"></property>
<property name="descs" column="DESCS" type="java.lang.String"></property>
<!-- 在单方配置一对多关联关系 -->
<set name="students" table="STUDENT">
<key column="GID"></key>
<one-to-many class="Student"/>
</set>
</class>
</hibernate-mapping>
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.hibernate.hibernate_one2many">
<class name="Student" table="Student">
<id name="sid" column="SID" type="java.lang.Integer">
<generator class="increment"></generator>
</id>
<property name="sname" column="SNAME" type="java.lang.String"></property>
<property name="sex" column="SEX" type="java.lang.String"></property>
</class>
</hibernate-mapping>
3.2单向多对一关系
package com.hibernate.hibernate_one2many;
import java.io.Serializable;
public class Grade implements Serializable {
private Integer gid;
private String gname;
private String descs;
public Grade(String gname, String descs) {
this.gname = gname;
this.descs = descs;
}
public Grade() {
}
//以下省略setter和getter方法
}
package com.hibernate.hibernate_one2many;
import java.io.Serializable;
public class Student implements Serializable {
private Integer sid;
private String sname;
private String sex;
private Grade grade;
public Student(String sname, String sex, Grade grade) {
this.sname = sname;
this.sex = sex;
this.grade = grade;
}
public Student() {}
//以下省略setter和getter方法
}
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.hibernate.hibernate_many2one.entity.Grade" table="Grade">
<id name="gid" column="GID" type="java.lang.Integer">
<generator class="increment"></generator>
</id>
<property name="gname" column="GNAME" type="java.lang.String"></property>
<property name="descs" column="DESCS" type="java.lang.String"></property>
</class>
</hibernate-mapping>
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.hibernate.hibernate_many2one.entity.Student" table="Student">
<id name="sid" column="SID" type="java.lang.Integer">
<generator class="increment"></generator>
</id>
<property name="sname" column="SNAME" type="java.lang.String"></property>
<property name="sex" column="SEX" type="java.lang.String"></property>
<1-- 在多方配置多对一关系 -->
<many-to-one name="grade" class="com.hibernate.hibernate_many2one.entity.Grade" column="gid" ></many-to-one>
</class>
</hibernate-mapping>
3.3双向多对一(双向一对多)
public class Grade implements Serializable{
private Integer gid;
private String gname;
private String descs;
private Set<Student> students = new HashSet<Student>();
//以下省略javabean的方法
}
public class Student implements Serializable {
private Integer sid;
private String sname;
private String sex;
private Grade grade;
//以下省略javabean方法
}
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.hibernate.hibernate_many2oneBothSide.entity">
<class name="Grade" table="GRADE">
<id name="gid" column="GID" type="java.lang.Integer">
<generator class="increment"></generator>
</id>
<property name="gname" column="GNAME" type="java.lang.String"></property>
<property name="descs" column="DESCS" type="java.lang.String"></property>
<!-- cascade="all"表示对所有方法实现级联操作 inverse="true"将关联关系的控制权交给多方来维护 -->
<set name="students" table="STUDENT" cascade="all" inverse="true">
<key column="GID"></key>
<one-to-many class="Student"/>
</set>
</class>
</hibernate-mapping>
总结:
实现一对多、多对一的两个步骤:
1.在实体类中加入对单方或对多方的引用(对多方的引用要用集合属性,Set、List、Map等)
2.在hbm.xml配置文件中,配置对引用的关联信息
多对一关联,在多方配置hbm.xml中要配置
<many-to-one name="多方实体类中持有的一方引用名" class="所持有的一方引用对应类的权限名" column="多方关联到一方的列名" ></many-to-one>
一对多关联,在一方配置hbm.xm中要配置
<set name="一方持有的多方的集合名" table="多方集合中实体类对应的表名">
<key column="被多方指向列明,也集多方指向一方的主键key"></key>
<one-to-many class="多方对应的类的权限名"/>
</set>
双向多对一关联(双向一对多),在双方实体类都持有对方的引用(单方持有的是多方的集合引用)
在双方hbm.xml中配置引用即可,即把单向一对多和单向多对一的配置全都配置进对应的hbm.xml中,并且在单方集合属性中加入属性inverse="true" cascade="all"来实现级联操作和多方维护关联关系。