一、表结构与配置
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import java.util.ArrayList;
import java.util.List;
@Setter
@Getter
@ToString
@NoArgsConstructor
@Entity
@Table(name = "DEMO_ONE")
public class DemoOne {
@Id
@GenericGenerator(name = "idGenerator", strategy = "org.hibernate.id.UUIDGenerator")
@GeneratedValue(generator = "idGenerator")
@Column(name = "ID", length = 50)
private String id;
@Column(name = "NAME", length = 50)
private String name;
@ToString.Exclude
@OneToMany(mappedBy = "demoOne")
private List<DemoMany> demoManyList = new ArrayList<>();
}
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import javax.persistence.*;
@Setter
@Getter
@ToString
@NoArgsConstructor
@Entity
@Table(name = "DEMO_MANY")
public class DemoMany {
@Id
@GenericGenerator(name = "idGenerator", strategy = "org.hibernate.id.UUIDGenerator")
@GeneratedValue(generator = "idGenerator")
@Column(name = "ID", length = 50)
private String id;
@Column(name = "NAME", length = 50)
private String name;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "DEMO_ONE_ID")
private DemoOne demoOne;
}
DEMO_ONE
ID | NAME |
---|---|
1 | one1 |
2 | one2 |
DEMO_MANY
ID | NAME | DEMO_ONE_ID |
---|---|---|
1 | many2 | 1 |
2 | many2 | 1 |
3 | many3 | 2 |
4 | many4 | 2 |
1、多对一需要配置懒加载,使用@ToString需要在关联的一方加 @ToString.Exclude
如果不加懒加载,当你使用jpa自带findAll或者jpa查询规则findByName查询DEMO_MANY表会执行3条一句:
语句A:select e.id,e.name … from many e
语句B:select e.id,e.name… from one e where e.id=1
语句C:select e.id,e.name… from one e where e.id=2
如果加了懒加载机制,只会执行一条语句,当使用DemoMany .getDemoOne()时,才会去执行语句B或者语句C,以此类推…!
如果使用了lombok的@ToString注解,关联会死循环导致内存溢出,需要在关联任意的一方加 @ToString.Exclude,建议在一对多的一方加,因为toString会去懒加载,查询数据库!
2、CascadeType详解
CascadeType.PERSIST:级联保存
多对一时,一般先是找出数据库存在的one,赋值many.set(one),保存save(many) 完成关联保存,当如果数据库中不存在one,这时候需要在 @OneToMany 配置 cascade = CascadeType.PERSIST 属性,这时候就要先创建新的one,One one = new One(),赋值many.set(one),保存save(many) 完成关联保存,此时就会同时保存 one 和 many;如果不加 cascade = CascadeType.PERSIST 属性就会报异常 save the transient instance before flushing!
一对多时保存的时候要注意是,不管是从数据库查询出来额many还是new出来的many,都需要many.set(one),否则关联关系将不会创建出来!
CascadeType.REMOVE:级联删除
如果你要删除一个实体,但是它有外键无法删除,配置该属性会删除与之关联的所有外键对应的数据!
CascadeType.MERGE:级联更新(合并)
未实践
CascadeType.DETACH:级联脱管/游离
如果你要删除一个实体,但是它有外键无法删除,配置该属性会撤销所有相关的外键关联!
CascadeType.REFRESH:级联刷新
未实践