转载自:https://blog.youkuaiyun.com/xingfei_work/article/details/75661251
我们知道关系型数据库表之间的关系,存在三种情况
1、一对一
A表数据和B表数据存在一一对应关系
2、一对多/多对一
一对多:A表中的一条数据对应B表的多条数据
多对一:B表多条数据对应A表的一条数据
3、多对多
A表的一条数据对应B表的多条数据
B表的一条数据对应A表的多条数据
其中又有单向和双向之分
何谓单双向,单就是一个中拥有另一个,双就是彼此拥有
那么我们下面就通过代码的形式展示下Hibernate对多表关系的支持:
一对一
Hibernate对于一对一又分为2种情况,分别是:
一对一主键:就是A表的字段作为B表的外键且又是主键
一对一外键:就是A表的字段作为B表的外键
按照方向我们又分为单向和双向
比如:人和身份证 ,一个人只有一个身份证
我们来实现下一对一主键映射,首先通过xml实现
学生类:
public class Student {
private int no;//学号
private String name;//姓名
private String sex;//性别
private StudentCard card;//学生的学生证对象
public StudentCard getCard() {
return card;
}
public void setCard(StudentCard card) {
this.card = card;
}
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
}
学生证类:
public class StudentCard {
private int id;
private Date startTime;//入学时间
private String major;//专业
private Student student;//当前学生证的学生对象
public Student getStudent() {
return student;
}
public void setStudent(Student student) {
this.student = student;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Date getStartTime() {
return startTime;
}
public void setStartTime(Date startTime) {
this.startTime = startTime;
}
public String getMajor() {
return major;
}
public void setMajor(String major) {
this.major = major;
}
}
我们在配置一对一的时候,需要明确哪个表中拥有外键,我这里让学生证表中依赖学生表的主键
学生证的配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping
SYSTEM
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd" >
<hibernate-mapping package="org.qf.onetoonep">
<class name="StudentCard" table="tb_sc">
<id name="id" column="id">
<!--标记外键充当主键-->
<generator class="foreign">
<param name="property">student</param>
</generator>
</id>
<!--配置属性对应的字段 -->
<property name="startTime" />
<property name="major" length="20"/>
<!--一对一主键映射
constrained:就是标记当前属性的主键作为当前类对应的表的外键 -->
<one-to-one name="student" constrained="true" ></one-to-one>
</class>
</hibernate-mapping>
如果我们需要配置双向的,那么就得在学生类的配置文件中添加一对一,学生类的配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping
SYSTEM
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd" >
<hibernate-mapping package="org.qf.onetoonep">
<class name="Student" table="tb_student">
<id name="no" column="id">
<generator class="identity"/>
</id>
<property name="name" length="20" />
<property name="sex" length="2"/>
<!--一对一主键,双向配置 -->
<one-to-one name="card"></one-to-one>
</class>
</hibernate-mapping>
以上就是使用xml进行一对一主键映射的配置
接下来我们看看如何通过xml配置一对多外键:
类不变,我们只需要把配置文件改改就可以了。
学生证的配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping
SYSTEM
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd" >
<hibernate-mapping package="org.qf.onetoonep">
<class name="StudentCard" table="tb_sc">
<id name="id" column="id">
<generator class="identity"></generator>
</id>
<!--配置属性对应的字段 -->
<property name="startTime" />
<property name="major" length="20"/>
<!--一对一外键映射,其实就是多对一,只是加个唯一约束这样就成了一对一
-->
<many-to-one name="student" unique="true" column="sid"></many-to-one>
</class>
</hibernate-mapping>
我们如果需要配置双向的,那么就得在学生的配置中添加一对一映射
学生的配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping
SYSTEM
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd" >
<hibernate-mapping package="org.qf.onetoonep">
<class name="Student" table="tb_student">
<id name="no" column="id">
<generator class="identity"/>
</id>
<property name="name" length="20" />
<property name="sex" length="2"/>
<!--一对一,双向配置
property-ref就是设置对方表中当前类型的属性名称 -->
<one-to-one name="card" property-ref="student"></one-to-one>
</class>
</hibernate-mapping>
以上就是通过xml配置实现的一对一主外键映射关系
使用注解的话就不需要写配置文件了,来看看类:
学生证类:
@Entity//映射类--说明该类是一个表
@Table(name="tb_sc")//表的设置
public class StudentCard {
@Id//主键
@GeneratedValue(strategy=GenerationType.IDENTITY)//主键生成策略
private int id;
private Date startTime;//入学时间
@Column(length=20)//字段的设置
private String major;//专业
@OneToOne(fetch=FetchType.EAGER)//一对一关系
@JoinColumn(name="sid")//外键字段设置
private Student student;//当前学生证的学生对象
public Student getStudent() {
return student;
}
public void setStudent(Student student) {
this.student = student;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Date getStartTime() {
return startTime;
}
public void setStartTime(Date startTime) {
this.startTime = startTime;
}
public String getMajor() {
return major;
}
public void setMajor(String major) {
this.major = major;
}
}
我的学生类的注解实现:
@Entity
@Table(name="tb_student")
public class Student {
@Id//主键
@GeneratedValue(strategy=GenerationType.IDENTITY)//主键生成策略
private int no;//学号
@Column(length=50,nullable=false)
private String name;//姓名
@Column(length=2,nullable=false)
private String sex;//性别
@OneToOne(fetch=FetchType.EAGER)
private StudentCard card;//学生的学生证对象
public StudentCard getCard() {
return card;
}
public void setCard(StudentCard card) {
this.card = card;
}
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
}
以上注解实现的一对一是一对一外键的实现。
这就是Hibernate对关系型数据库的一对一的关系的实现的2种方式
一种基于xml配置,另一种基于注解的实现。