版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010871004/article/details/81914629
简介
很多的需求中,可能会有一个对象中包含着另一个对象,而包含的这个对象又是一个List,在Java中,List可能是一个ArrayList或者是LinkedList。对于List的数据类型,hibernate又是如何做到持久化的?
泛型为简单类型的List
package com.hibernate.work_with_collections;
import java.util.List;
import javax.persistence.CollectionTable;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OrderColumn;
import javax.persistence.Table;
import org.hibernate.annotations.IndexColumn;
@Entity
@Table(name = "student")
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id")
private long id;
@Column(name = "name")
private String name;
@ElementCollection(fetch = FetchType.LAZY)
@CollectionTable(name = "email")
@IndexColumn(name = "email_index")
private List<String> emails;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<String> getEmails() {
return emails;
}
public void setEmails(List<String> emails) {
this.emails = emails;
}
@Override
public String toString() {
return "Student [id=" + id + ", name=" + name + ", emails=" + emails + "]";
}
}
这边会说是简单类型的原因的是,List<String>,中的泛型是个String,不是我们自定义的一个类型。
@ElementCollection(fetch = FetchType.LAZY):表明在获取email的数据时候,会进行延迟加载,查询的时候,会分成两次查询语句,如果fetch = FetchType.EAGER,hibernate会使用左外连接进行查询。
@CollectionTable(name = “email”):将依赖的email创建email表。
@IndexColumn(name = “email_index”):email表中会增加一个email_index的列。
泛型为复杂类型的List
package com.hibernate.work_with_collections;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.Table;
@Entity
@Table(name = "student")
public class ComplexStudent {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@Column(name = "name")
private String name;
@OneToMany(cascade = { CascadeType.ALL })
@JoinColumn(name = "student_id")
private List<Degree> degrees;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Degree> getDegrees() {
return degrees;
}
public void setDegrees(List<Degree> degrees) {
this.degrees = degrees;
}
@Override
public String toString() {
return "ComplexStudent [id=" + id + ", name=" + name + ", degrees=" + degrees + "]";
}
}
package com.hibernate.work_with_collections;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "degree")
public class Degree {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@Column(name = "degreename")
private String degreeName;
@Column(name = "passingyear")
private String passingYear;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getDegreeName() {
return degreeName;
}
public void setDegreeName(String degreeName) {
this.degreeName = degreeName;
}
public String getPassingYear() {
return passingYear;
}
public void setPassingYear(String passingYear) {
this.passingYear = passingYear;
}
@Override
public String toString() {
return "Degree [id=" + id + ", degreeName=" + degreeName + ", passingYear=" + passingYear + "]";
}
}
上述代码会给degree创建一外键关联student的主键,主要重要的注解是@JoinColumn(name = “student_id”),degree表的外键是student_id。如果删除掉这个注解,hibernate会创建第三张表,来映射对student表数据和degree表数据的关联。
@OneToMany(cascade = { CascadeType.ALL }):
cascade属性: 指定级联操作的行为(可多选)
- CascadeType.PERSIST 级联新增(又称级联保存):
获取A对象里也同时也重新获取最新的B时的对象。即会重新查询数据库里的最新数据,并且,只有A类新增时,会级联B对象新增。若B对象在数据库存(跟新)在则抛异常(让B变为持久态),对应EntityManager的presist方法,调用JPA规范中的persist(),不适用于Hibernate的save()方法 - CascadeType.MERGE 级联合并(又称级联更新) 指A类新增或者变化,会级联B对象(新增或者变化)
,对应EntityManager的merge方法,调用JPA规范中merge()时,不适用于Hibernate的update()方法
CascadeType.REMOVE 级联删除
只有A类删除时,会级联删除B类,即在设置的那一端进行删除时,另一端才会级联删除,对应EntityManager的remove方法,调用JPA规范中的remove()时,适用于Hibernate的delete()方法 - CascadeType.REFRESH 级联刷新
获取order(一或多)对象里也同时也重新获取最新的items(多)的对象,对应EntityManager的refresh(object),调用JPA规范中的refresh()时,适用于Hibernate的flush()方法 - CascadeType.ALL 包含所有持久化方法