hibernate关联注解

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

说明:
本文对hibernate的一对多、多对一、多对多的关联
示例代码是Order类和OrderItem类的一对多的关系
1.一对多
1.1注解方式:
@OneToMany 代码示例如下:
双向关联,维护端在“多”的一端
Public class Order implements Serializable {
Private Set <OrderItem> orderItems = new HashSet<OrderItem>();
@OneToMany(mappedBy="order"(有了mappedby不能也不该在此再定义@joincolumn),cascade = CascadeType.ALL, fetch = ZY)
@OrderBy(value= "id ASC")
public Set<OrderItem> getOrderItems() {
return orderItems;
}
}
单向关联,维护端在此端
Public class Order implements Serializable {
private Set<OrderItem> orderItems = new HashSet<OrderItem>();
@OneToMany(cascade = CascadeType.ALL, fetch = ZY)
@JoinColumn(name=”order_id”)
@OrderBy(value= "id ASC")
public Set<OrderItem> getOrderItems() {
return orderItems;
}
}
1.2维护端和级联问题
维护端的意思是对外键进行维护,维护端有对外键进行插入和更新的权利。

下面分情况介绍hibernate的级联操作:
1.2.1单向关联
对“一”表进行插入一条记录的操作:
1)级联类型:CascadeType.ALL
执行语句:
1.insert into category (description, name, id) values(?, ?, ?)
如果在关联表中没有该记录,执行
2.insert into product (descripton, name, price, id)
values (?, ?, ?, ?)
3.update product set category_id=? Where id=?
同时对外键值进行了写入。

2)关联类型:CascadeType.PERSIST/MERGE
执行语句:
1.Insert into category (description, name, id) values
(?, ?, ?)
如果关联表中数据有更新,执行:
2.update product set category_id=? Where id=?
如果关联表中没有记录,则会报错。

1.2.2双向关联(维护端在“多”端)
对“一”表进行插入一条记录的操作:
1)级联类型:CascadeType.ALL
执行语句:
1.insert into category (description, name, id) values(?, ?, ?)
如果关联表总没有该记录,执行
2.insert into product(category_id, descripton, name, price, id) values(?, ?, ?, ?, ?)
注意:关联表中的外键值为空,及外键由维护端进行维护。

2)关联类型:CascadeType.PERSIST/MERGE
执行语句:
insert into category (description, name, id) values (?, ?, ?)
2.多对一
2.1注解方式:
@ManyToOne(cascade=CascadeType.REFRESH,optional=false)
@JoinColumn(name = "order_id")
例如:
Public class OrderItem implements Serializable {
private Order order;
@ManyToOne (cascade=CascadeType.REFRESH,optional=false)
@JoinColumn(name = "order_id")
public Order getOrder() {
return order;
}
}
2.2维护端的级联问题
“多端”维护外键,及对外键有更新插入的权利。

在面是在多端执行插入记录所执行的SQL语句。

2.2.1单向关联
1)在“多”端插入一条记录,级联类型为CascadeType.ALL,执行的SQL语句为:
A.当关联方记录存在:
insert into product(category_id, descripton, name, price, id) values (?, ?, ?, ?, ?)
如果“一”端有更新则执行:
Update category set description=?,name=?
Where id=?
B.当关联方记录不存在:
insert into category (description, name, id)
values (?, ?, ?)
insert into product(category_id, descripton, name, price, id) values(?, ?, ?, ?, ?)
2)在“多”端插入一条记录,级联类型为CascadeType.PERSIST/MERGE/,执行SQL语句为:
A.一端记录存在:
insert into product(category_id, descripton, name, price, id) values (?, ?, ?, ?, ?)
如果有更新则执行:
Update category set description=?,name=? where id=?
注意:更新“一”端主键会报错
B.一端记录不存在:运行报错
2.2.2双向关联(多端为维护端)
1)在“多”端插入一条记录,级联类型为CascadeType.ALL/PERSIST/MERGE,执行SQL语句为:A关联端存在记录:
insert into product (category_id, descripton, name, price, id) values (?, ?, ?, ?, ?) 如果“一”端的数据有更新
Update category set description=?,name=? where id=?
注意:更改“一”端主键会报错
B关联端不存在记录:运行报错
推荐博客:
/liangoo7/article/details/8070211
注意:
在做关联的时候:单向关联无需维护端,双向关联则需要多的一端维护。

一对多:
多对一:
@ManyToOne(cascade=CascadeType.REFRESH,optional=false)
@JoinColumn(name = "order_id")
例如:
Public class OrderItem implements Serializable {
private Order order;。

@ManyToOne(cascade=CascadeType.REFRESH,optional=false)
@JoinColumn(name = "order_id")
public Order getOrder() {
return order;
}
}
多对多:
/*
* @ManyToMany 注释表示Teacher 是多对多关系的一端。

* @JoinTable 描述了多对多关系的数据表关系,name属性指定中间表名称。

* joinColumns 定义中间表与Teacher 表的外键关系,中间表
Teacher_Student的Teacher_ID 列是Teacher 表的主键列对应的外键列。

* inverseJoinColumns 属性定义了中间表与另外一端(Student)的外键关系。

*/
@ManyToMany(cascade = CascadeType.PERSIST, fetch = ZY)
@JoinTable(name = "Teacher_Student",
joinColumns ={@JoinColumn(name = "teacher_ID", referencedColumnName = "teacherid") },
inverseJoinColumns = { @JoinColumn(name = "student_ID", referencedColumnName = "studentid")
})
public Set<Student> getStudents() {
return students;
}
相关属性:
fatch
可选择项包括:FetchType.EAGER和ZY。

前者表示关系类(本例是OrderItem 类)在主类(本例是Order类)加载的时候同时加载,后者表示关系类在被访问时才加载。

Cascade
四个值:的值只能从CascadeType.PERSIST(级联新建)、CascadeType.REMOVE(级联删除)、CascadeType.REFRESH(级联刷新)、CascadeType.MERGE(级联更新)中选择一个或多个。

还有一个选择是使用CascadeType.ALL,表示选择全部四项。

@ManyToMany(book为维护端、category为被维护端)
1)被维护端
1.1被维护端插入一条记录,级联类型:CascadeType.ALL,执行语句:
Hibernate:
insert
into
category
(description, name, id)
values
(?, ?, ?)
Hibernate:
insert
into
book
(author, price, id)
values
(?, ?, ?)
1.2被维护端插入一条记录,级联类型:CascadeType.PERSIST/MERGE,执行语
句:
Hibernate:
insert
into
category
(description, name, id)
values
(?, ?, ?)
2)
2.1.维护端插入一条语句,级联类型:CascadeTye.ALL,执行语句:Hibernate:
insert
into
book
(author, price, id)
values
(?, ?, ?)
如果被维护端没有数据则执行以下数据。

Hibernate:
insert
into
category
(description, name, id)
values
(?, ?, ?)
Hibernate:
insert
into
book_category
(bookId, categoryId)
values
(?, ?)
2.2维护端插入一条语句,级联类型:CascadeType.PERSIST/MERGE,执行语句:
Hibernate:
insert
into
book
(author, price, id)
values
(?, ?, ?)
Hibernate:
insert
into
book_category
(bookId, categoryId)
values
(?, ?)
注意:被维护端如果没有记录,则会报错:找不到维护端的记录。

@ManyToMany中双向关联与单向关联效果相同。

相关文档
最新文档