转载自:https://blog.youkuaiyun.com/xingfei_work/article/details/75668328
在上一篇博客中我们知道数据库的三种关系,那么这一篇就聊聊一对多的关系。
一对多的时候,需要明确外键究竟应该设置到那个表上,一般都是多的那个表中拥有一的表的主键来做外键。
人和银行卡,一个人有多张银行卡,多张卡属于一个人,那么这2个表就存在一对多和多对一的关系。
首先我们看看基于xml的实现:
Person类:
//人类--体现一对多,一个人有多张银行卡
public class Person {
private int id;
private String name;
private int age;
//不需要通过索引操作集合
//private Set<BankCard> bankCards;//人拥有的所有银行卡
//需要索引操作集合
private List<BankCard> bankCards;//人拥有的所有银行卡
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
/*public Set<BankCard> getBankCards() {
return bankCards;
}
public void setBankCards(Set<BankCard> bankCards) {
this.bankCards = bankCards;
}*/
public List<BankCard> getBankCards() {
return bankCards;
}
public void setBankCards(List<BankCard> bankCards) {
this.bankCards = bankCards;
}
}
BankCard类:
//银行卡类,体现的是多对一,多张银行卡对应一个人
public class BankCard {
private int id;
private String name;//银行
private String no;//银行卡号
private Person person;//卡所属的人
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getNo() {
return no;
}
public void setNo(String no) {
this.no = no;
}
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
}
我这里才有的是list集合,所以配置的时候需要使用list标签并且还得维护一个索引字段,为了让Hibernate知道存储顺序的
Person类的映射文件:
<?xml version="1.0" encoding="UTF-8"?>
<!--文档说明,设置映射文件 -->
<!DOCTYPE hibernate-mapping
SYSTEM
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd" >
<!--映射标签 package:内部类的所在的包名 -->
<hibernate-mapping package="org.qf.onetomany">
<class name="Person" table="tb_person">
<!--id:主键,name:属性名称,column:字段名称 -->
<id name="id" column="id">
<generator class="identity" />
</id>
<!--配置属性对应的字段 -->
<property name="name" length="20" />
<property name="age" />
<!--属性为集合的配置 一对多 对多对 name:集合的属性名称 -->
<!--一对多是Set集合进行关联,无需去维护索引 -->
<!-- <set name="bankCards" lazy="false">
key标记的是集合中泛型类对应的外键字段 column:多的一方的外键(该外键必须来自当前的类的主键)
<key column="pid"></key>
存在一对多的关系 class:与哪个类存在一对多关系
<one-to-many class="BankCard" />
</set> -->
<!--使用List集合,通过索引控制 -->
<list name="bankCards" cascade="save-update">
<key column="pid"></key>
<index column="list_index"></index>
<one-to-many class="BankCard"/>
</list>
</class>
</hibernate-mapping>
BankCard类的映射文件:
<?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.onetomany">
<class name="BankCard" table="tb_bankcard">
<!--id:主键,name:属性名称,column:字段名称 -->
<id name="id" column="id">
<generator class="identity"/>
</id>
<!--配置属性对应的字段 -->
<property name="name" length="50" />
<property name="no" length="30" />
<!--在一对多和多对一中外键设置到多的一方
多对一,只需标记2个属性:
name:指明当前类的哪个属性存在多对一
column:指明外键的字段名称
cascade:级联设置,主要标记的书相关联的数据的修改操作:新增、修改、删除
当保存或删除当前对象时候,是否需要将有关联的对象也进行相同的操作
取值说明:
all:全部
delete:删除
save-update:保存或修改
fetch:抓取数据的策略
标记如果查询项关联的数据信息
取值:
1、join使用连接查询
2、 select单个查询 -->
<many-to-one name="person" column="pid" cascade="save-update" fetch="join"></many-to-one>
</class>
</hibernate-mapping>
以上就是一对多和多对一的关系配置,但是需要注意的是使用list集合,必须维护一个字段记录添加顺序,否则List集合无法使用
那么接下来,我们看看如何通过注解实现一对多和多对一呢?
注解主要用的就是@OneToMany和@ManyToOne
Person类:
//人类--体现一对多,一个人有多张银行卡
@Entity
@Table(name="tb_person")
public class Person {
@Id//主键
@GeneratedValue(strategy=GenerationType.IDENTITY)//主键生成策略
private int id;
@Column(length=20)
private String name;
private int age;
//不需要通过索引操作集合
//private Set<BankCard> bankCards;//人拥有的所有银行卡
//需要索引操作集合
@OneToMany(fetch=FetchType.EAGER,mappedBy="person",targetEntity=BankCard.class)//设置一对多,且立即加载
private List<BankCard> bankCards;//人拥有的所有银行卡
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
/*public Set<BankCard> getBankCards() {
return bankCards;
}
public void setBankCards(Set<BankCard> bankCards) {
this.bankCards = bankCards;
}*/
public List<BankCard> getBankCards() {
return bankCards;
}
public void setBankCards(List<BankCard> bankCards) {
this.bankCards = bankCards;
}
}
注意@OneToMany
体现一对多的映射,不会出现外键
常用属性:
mappedBy:关联的属性名称,就是存在多的一方中的本类的属性名称
targetEntity:集合中泛型类的Class类对象,其实就是多的类的Class
BankCard类:
//银行卡类,体现的是多对一,多张银行卡对应一个人
@Entity
@Table(name="tb_bc")
public class BankCard {
@Id//主键
@GeneratedValue(strategy=GenerationType.IDENTITY)//主键生成策略
private int id;
@Column(length=30)
private String name;//银行
@Column(length=30)
private String no;//银行卡号
@ManyToOne
@JoinColumn(name="pid")
private Person person;//卡所属的人
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getNo() {
return no;
}
public void setNo(String no) {
this.no = no;
}
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
}
以上就是关于Hibernate中实现一对多和多对一的2种方式,xml和注解