(1) JPA N + 1 문제 해결 방안 조회 효율 최적화

3016 단어 JPA
질문 배경:
하나의 트 리 구 조 를 설계 하 는 실체 에 다 대 일, 한 쌍 의 다 중 맵 관 계 를 사 용 했 고 관련 대상 을 불 러 올 때 성능 을 고려 하여 자 연 스 럽 게 게 게 으 른 로 딩 을 생각 했다.
그래서 N + 1 의 전형 적 인 문제 에 부 딪 혔 다. 일반적으로 1 개의 이 쪽 은 SQL 1 개 를 통 해 1 개의 대상 을 찾 을 수 있 으 며, JPA 는 Hibernate 를 기반 으로 fetch 전략 은 기본적으로 select (연결 표 조회 가 아 닌) 입 니 다. 관련 이 존재 하기 때문에 이 대상 과 관련 된 집합 을 꺼 내야 합 니 다. 집합 수량 은 N 이 고 N 개의 SQL 을 보 내야 합 니 다. 그래서 원래 의 1 개의 연결 표 조회 SQL 이 해결 할 수 있 는 문 제 는 N + 1 개의 SQL 로 바 뀌 었 습 니 다.
 
JPA 2.1 에서 추 가 된 @ EntityGraph, @ NamedEntityGraph 는 조회 효율 을 높이 기 위해 N + 1 개의 SQL 문 제 를 잘 해결 했다.둘 다 협조 해서 사용 해 야 합 니 다. 하나 가 없어 서 는 안 됩 니 다. @NamedEntityGraph 는 @ Entity 위 에 설정 되 어 있 고 @ EntityGraph 는 Repository 조회 방법 위 에 설정 되 어 있 습 니 다. 연결 표 조 회 를 통 해 해결 합 니 다.
해결 방법 은 다음 과 같다. 
데 모 는 다음 과 같 습 니 다:
1. 먼저 실체 에 @ NamedEntityGraph 를 주석 하고 name 을 가리 키 며 조회 방법 에 사용 합 니 다. attributeNodes 는 게 으 른 로 딩 으로 표 시 된 속성 노드 를 가리 킵 니 다.



@Entity
@Getter
@Setter
@Table(name = "ORG_AGENCY")
@NamedEntityGraph(name = "Agency.Graph", attributeNodes = {@NamedAttributeNode("region"), @NamedAttributeNode("parent"),@NamedAttributeNode("mofDep"),@NamedAttributeNode("unit")})
public class Agency extends BaseEntity {

    
   
    @Field
    @Column(nullable = false)
    @ApiModelProperty(value = "  ", required = true)
    private String code; 

    @Field
    @Column(nullable = false)
    @ApiModelProperty(value = "  ", required = true)
    private String name; 

    
    @ApiModelProperty(value = "    ")
    private Boolean enabled; //     

    
    @ApiModelProperty(value = "  ")
    private Integer levelNum;

    
    @ApiModelProperty(value = "    ")
    private String innerCode;

    
    @ApiModelProperty(value = "    ")
    private Boolean leafNode;

   
    @ApiModelProperty(value = "        ")
    private Boolean expandable;

    
    
    @ApiModelProperty(value = "    ")
    @ManyToOne(fetch = FetchType.LAZY)
    private Region region;

   
   

    @ManyToOne(fetch = FetchType.LAZY)
    @ApiModelProperty(value = "  ")
    private Agency parent;



   
    @ApiModelProperty(value = "  ")
    private String year;

 

  
    

    
    @ApiModelProperty(value = "    ")
    @ManyToOne(fetch = FetchType.LAZY)
    private MOFDep mofDep;

   
    @ApiModelProperty(value = "    ")
    @ManyToOne(fetch = FetchType.LAZY)
    private Organization unit;

   
}

2. 방문 한 dao 의 조회 방법 에 @ EntityGraph, value 속성 값 은 @ NamedEntityGraph 의 name 속성 값 입 니 다. 예 를 들 어 Agency Repository : 

public interface AgencyRepository extends GenericRepository {

    @QueryHints(value = {@QueryHint(name = "org.hibernate.cacheable", value = "true")})
    @EntityGraph(value = "Agency.Graph", type = EntityGraph.EntityGraphType.FETCH)
    List findAll(Predicate predicate, Sort sort);

   
}

 

좋은 웹페이지 즐겨찾기