spring data jpa:@OneToMany 和 @ManyToOne
一、pojo
1 @Entity 2 @Table(name = "tb_organization") 3 @AllArgsConstructor 4 @NoArgsConstructor 5 @Setter 6 @Getter 7 @ToString(of = {"organization_id","organization_name","description"}) 8 @EqualsAndHashCode 9 public class Organization implements Serializable { 10 11 @Id 12 private String organization_id; 13 private String organization_name; 14 private String description; 15 @ManyToOne( 16 cascade = {CascadeType.MERGE,CascadeType.REFRESH} //由多端控制 17 ) 18 @JoinColumn(name = "parent_id") //外键(定义在控制端) 19 @JsonIgnore //忽略父类属性的JSON序列化 20 private Organization parent; 21 @OneToMany( 22 mappedBy = "parent", //属性(被控端)
23 cascade = CascadeType.ALL, //由多端控制
24 fetch = FetchType.LAZY //懒加载
25 )
26 @Fetch(FetchMode.SUBSELECT) //@Fetch(FetchMode.JOIN) 会使用left join查询 只产生一条sql语句
//@Fetch(FetchMode.SELECT) 会产生N+1条sql语句
//@Fetch(FetchMode.SUBSELECT) 产生两条sql语句 第二条语句使用id in (…..)查询出所有关联的数据
27 private List<Organization> children = new ArrayList<>();
28 }
二、annotation
1、FetchType.LAZY: 懒加载,在访问关联对象的时候加载(即从数据库读入内存)
2、FetchType.EAGER:立刻加载,在查询主对象的时候同时加载关联对象。
3、@Fetch(FetchMode.JOIN): 始终立刻加载,使用外连(outer join)查询的同时加载关联对象,忽略FetchType.LAZY设定。
4、@Fetch(FetchMode.SELECT) :默认懒加载(除非设定关联属性lazy=false),当访问每一个关联对象时加载该对象,会累计产生N+1条sql语句
5、@Fetch(FetchMode.SUBSELECT) 默认懒加载(除非设定关联属性lazy=false),在访问第一个关联对象时加载所有的关联对象。且FetchType设定有效。
可以右键图片,打开新标签查看。可能形状会有点“长”…
另外发现@Fetch(FetchMode.SELECT)中会有N+1的问题,于是找了两篇文章,讲到了如何解决N+1的问题:
NHibernate N+1问题实例分析和优化
Hibernate n+1问题
转自:https://blog.csdn.net/johnf_nash/article/details/80642581
转自:https://blog.csdn.net/sinat_28454173/article/details/52327220