@OneToOne等注解的使用

@OneToOne,@ManyToOne,@OneToMany这几个注解的使用见名知意就知道是一对一,多对一,一对多的关系了。

但今天要说的是由于没有正确的使用注解导致查询速度很慢的问题。

注意@OneToOne,@ManyToOne注解有一个FetchType枚举属性,分为lazy和eager, lazy表示的是懒加载(即不查询不加载,当查询某个对象时,不会去查询与其关联的对象),而eager英文就是饥渴的(即不管你需不需要,当查询某对象时,与其关联的对象也会一起通过join的方式查询出来)。

如果是lazy的方式,在查询列表时就可能出现N+1次查询的问题,

eg: 比如要查询某对象列表时,可能需要该对象的关联对象的一些信息,而lazy的方式是先查询该对象信息,然后根据查询到的关联对象ID再循环查询关联对象的信息,这就导致N+1次查询。

当然,这并不是说eager的查询方式要优于lazy, 当某个对象的关联对象较多并且数据库的数据达到一定量的时候,join查询的方式在一定程度上会影响性能,所以,使用lazy or eager 取决于你的数据量和业务逻辑。

有一点不可以忽略,那就是@NotFound(action = NotFoundAction.IGNORE)注解的使用:

这个注解是为了在没有查询到关联的对象时不抛出异常!!!

但是!!!

如果@OneToOne, @ManyToOne, @OneToMany 这些注解上设置了 fetch = FetchType.LAZY 并且在这些注解上在加上 @NotFound(action = NotFoundAction.IGNORE) ,

则懒加载失效, 会变成立即加载. (在程序中会带来很可怕的效应),产生n+1查询。

所以要使用fetch = FetchType.LAZY时, 要把 @NotFound给去掉 

如何解决N+1次的问题???

在JPA 2.1 版本之后, 推出了@EntityGraph,@NamedEntityGraph来提高查询效率,很好的解决了N+1次查询的问题。

⚠️@NotFound(action = NotFoundAction.IGNORE) 依旧不能使用

 

打印SQL:

你可能感兴趣的:(Spring,Data,JPA)