JPA效率优化
n+1问题
- 当我们使用JPA提供给我们的find方法时,如果查询出来的对象关联着另外10个对象,那么JPA将会发送1+10次查询(这个对象本身要查询一次,然后每个关联对象再查询一次)。此时如果有100个用户正同时发送请求,这个时候就会产生1100次查询,这将会大大增加服务器的开销,因此我们要避免这个问题。
Fetch Join
- 在JPA中,我们可以使用
fetch join
来获取我们需要加载的关联实体。
- 优点:它只需要一次查询就能够获取到我们需要的所有关联实体。
- 缺点:不够灵活,选择不同的关联实体就要重写JPQL语句或者是用
Criteria API
来封装一个很好的接口,当一个对象有很多关联实体的时候,要重写很多的JPQL语句。但如果在实际开发中,关联实体的组合数量较少的情况下是可以用的。
NameEntityGraph
- 这是JPA2.1的新特性,它的主要作用是来设置懒加载需要加载的关联对象,并且支持多层关联,比如
account.getRoles().get(0).getPages()
,来获取一个账号的某个角色所能访问的页面。 - 下面来看一个例子,假如有如下3个类
Account
@Entity
@Table(name = ACCOUNT)
@NamedEntityGraphs({
@NamedEntityGraph(name = "account.all",
attributeNodes = {
//attributeNodes 来定义需要懒加载的属性
@NamedAttributeNode("student"), @NamedAttributeNode("staff"),//无延伸
@NamedAttributeNode(value = "roles",//要懒加载