说明:本文对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:insertintocategory(description, name, id)values(?, ?, ?)Hibernate:insertintobook(author, price, id)values(?, ?, ?)1.2被维护端插入一条记录,级联类型:CascadeType.PERSIST/MERGE,执行语句:Hibernate:insertintocategory(description, name, id)values(?, ?, ?)2)2.1.维护端插入一条语句,级联类型:CascadeTye.ALL,执行语句:Hibernate:insertintobook(author, price, id)values(?, ?, ?)如果被维护端没有数据则执行以下数据。