前面介绍了一对一的关联关系在Hibernate应该如何来实现,这篇博文就来介绍下多对一和一对多的关联关系。
多对一和一对多的关联关系在我们的生活中也比较常见,例如,在我们学生时代,一个班级可以有多个学生,而一个学生只能属于一个班级,这就是一个多对一(一对多)的例子;
还有在我们的工作中,一个工作小组可以有多个用户,而一个用户只能属于一个小组,这也是一个多对一(一对多)的关系的例子。
下面就以一个工作小组可以有多个用户,而一个用户只能属于一个小组,这个例子来进行设计介绍如何建立一个多对一的关联关系。
在类的层面上:在多的一方加另一个的引用
在数据库层面上:在”多对一”中”多”的一方设置外键即可
1.1、多对一单向的关联关系的Annotation实现
Group类
@Entity
@Table(name="t_group") //指定表名
public class Group {
private int idGroup;
private String nameGroup;
@Id
@GeneratedValue
public int getIdGroup() {
return idGroup;
}
public void setIdGroup(int idGroup) {
this.idGroup = idGroup;
}
public String getNameGroup() {
return nameGroup;
}
public void setNameGroup(String nameGroup) {
this.nameGroup = nameGroup;
}
}
User类
@Entity
@Table(name="t_user") //指定表名
public class User {
private int idUser;
private String nameUser;
private Group group;//指定外键
@ManyToOne //多对一 即一个组有多个用户,而一个用户只能属于一个组
@JoinColumn(name="group_id")
public Group getGroup() {
return group;
}
public void setGroup(Group group) {
this.group = group;
}
@Id
@GeneratedValue
public int getIdUser() {
return idUser;
}
public void setIdUser(int idUser) {
this.idUser = idUser;
}
public String getNameUser() {
return nameUser;
}
public void setNameUser(String nameUser) {
this.nameUser = nameUser;
}
}
由于User实体和Group实体,User是处于“多对一”中“多”的一方,因此,我们就在User类中设置一个Group的外键即可建立多对一的关联关系。
测试结果如下:
1.2、多对一单向的关联关系的XXX.hbm.xml实现
Group类和User类
Group和User类中,有相应的属性和get、set方法即可。
且User类中有一个Group的引用。
Group.hbm.xml
<?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.model">
<class name="Group" table="t_group" >
<id name="idGroup" column="idGroup">
<generator class="native"/>
</id>
<property name="nameGroup" column="nameGroup"/>
</class>
</hibernate-mapping>
User.hbm.xml
<?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.model">
<class name="User" table="t_user" >
<id name="idUser" column="id">
<generator class="native"/>
</id>
<property name="nameUser" column="nameUser"/>
<!-- 这样就构成了一个多对一的关系 -->
<many-to-one name="group" column="groupId"></many-to-one>
</class>
</hibernate-mapping>
通过在User.hbm.xml文件中,加入
<many-to-one name="group" column="groupId"></many-to-one>
就构建了多对一的关联关系。
在类实体的层面上:在一的一方存在多方的集合
在数据库的层面上:在多方加外键
下面就以一个工作小组可以有多个用户,而一个用户只能属于一个小组,这个例子来进行设计介绍如何建立一个一对多的关联关系。
2.1、一对多单向的关联关系的Annotation实现
先看多的这方:User类
@Entity
@Table(name="t_user") //指定表名
public class User {
private int idUser;
private String nameUser;
@Id
@GeneratedValue
public int getIdUser() {
return idUser;
}
public void setIdUser(int idUser) {
this.idUser = idUser;
}
public String getNameUser() {
return nameUser;
}
public void setNameUser(String nameUser) {
this.nameUser = nameUser;
}
}
再看一的这方:Group类
由于是一对多的关系,因此在一的这方必须要有一个容器,这里采用的Set,Set容器可以用来避免重复,数据库中也是不允许主键重复的,与我们数据库的逻辑是符合的。
然后在Set容器的get方法上采用@OneToMany注解来进行修饰。并通过@JoinColumn(name=”groupId”)来指定外键名(外键在多的一方的表中生成)。
@Entity
@Table(name="t_group") //指定表名
public class Group {
private int idGroup;
private String nameGroup;
private Set<User> set=new HashSet<User>();
@OneToMany //一对多关系的指定
@JoinColumn(name="groupId")
public Set<User> getSet() {
return set;
}
public void setSet(Set<User> set) {
this.set = set;
}
@Id
@GeneratedValue
public int getIdGroup() {
return idGroup;
}
public void setIdGroup(int idGroup) {
this.idGroup = idGroup;
}
public String getNameGroup() {
return nameGroup;
}
public void setNameGroup(String nameGroup) {
this.nameGroup = nameGroup;
}
}
测试结果如下:
如果我们不通过@JoinColumn(name=”groupId”)来指定外键名(外键在多的一方的表中生成),则Hibernate会为我们生成一个中间表,即将一对多当成多对多来进行处理了。
测试结果如下:
2.2、一对多单向的关联关系的XXX.hbm.xml实现
Group类
public class Group {
private int idGroup;
private String nameGroup;
private Set<User> set=new HashSet<User>();
public Set<User> getSet() {
return set;
}
public void setSet(Set<User> set) {
this.set = set;
}
public int getIdGroup() {
return idGroup;
}
public void setIdGroup(int idGroup) {
this.idGroup = idGroup;
}
public String getNameGroup() {
return nameGroup;
}
public void setNameGroup(String nameGroup) {
this.nameGroup = nameGroup;
}
}
在Group.bhm.xml文件:
主要是为Group类中的Set属性,添加如下的代码即可构成一对多的关联关系:
<set name="set" >
<key column="groupId"></key>
<one-to-many class="com.hibernate.model.User"/>
</set>
完整内容如下:
<?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.model">
<class name="Group" table="t_group" >
<id name="idGroup" column="idGroup">
<generator class="native"/>
</id>
<property name="nameGroup" column="nameGroup"/>
<set name="set" >
<key column="groupId"></key>
<one-to-many class="com.hibernate.model.User"/>
</set>
</class>
</hibernate-mapping>
User类
public class User {
private int idUser;
private String nameUser;
public int getIdUser() {
return idUser;
}
public void setIdUser(int idUser) {
this.idUser = idUser;
}
public String getNameUser() {
return nameUser;
}
public void setNameUser(String nameUser) {
this.nameUser = nameUser;
}
}
User.hbm.xml文件
<?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.model">
<class name="User" table="t_user" >
<id name="idUser" column="id">
<generator class="native"/>
</id>
<property name="nameUser" column="nameUser"/>
</class>
</hibernate-mapping>
在我们了解了一对多和多对一的单向关联之后,双向关联就相当简单了,就是将这两者的单向关联进行合并即可。下面只介绍下使用Annotation来构建双向关联。
在一的一方:Group实体类
类似构建一对多。
只是有一点需要注意:指定mappedBy
代码如下:
@Entity
@Table(name="t_group") //指定表名
public class Group {
private int idGroup;
private String nameGroup;
private Set<User> set=new HashSet<User>();
@OneToMany(mappedBy="group") //一对多关系的指定 且由于是双向关联,必须指定mappedBy,否则会生成两个外键。
public Set<User> getSet() {
return set;
}
public void setSet(Set<User> set) {
this.set = set;
}
@Id
@GeneratedValue
public int getIdGroup() {
return idGroup;
}
public void setIdGroup(int idGroup) {
this.idGroup = idGroup;
}
public String getNameGroup() {
return nameGroup;
}
public void setNameGroup(String nameGroup) {
this.nameGroup = nameGroup;
}
}
在多的一方的User类
类似构建多对一的关联即可。
@Entity
@Table(name="t_user") //指定表名
public class User {
private int idUser;
private String nameUser;
private Group group;
@ManyToOne
@JoinColumn(name="groupId")
public Group getGroup() {
return group;
}
public void setGroup(Group group) {
this.group = group;
}
@Id
@GeneratedValue
public int getIdUser() {
return idUser;
}
public void setIdUser(int idUser) {
this.idUser = idUser;
}
public String getNameUser() {
return nameUser;
}
public void setNameUser(String nameUser) {
this.nameUser = nameUser;
}
}
这样就Ok了。
多对一和一对多的单向关联关系的Annotation和XXX.hbm.xml文件的实现均比较简单。