지난 글에서 적었던대로 프록시와 spring data JPA에 대해서 알아봅니다.
이 내용은 김영한 님의 저서 「자바 ORM 표준 JPA 프로그래밍」의 내용을 담고 있습니다.
프록시를 활용하면 연관된 객체를 처음부터가 아닌 필요한 시점, 실제 사용하는 시점에 조회를 하여 가져올 수 있다.
JPA에서는 프록시 객체라는 것이 내부적으로 존재하여 가짜 역할을 해줘 실제 필요한 지점에서 데이터베이스에 접속해 데이터를 받아올 수 있도록 도와준다고 한다.
앞서서 설명하던 것이 지연 로딩을 말한다. JPA에서는 연관관계 annotation의 fetch 속성으로 이를 설정할 수 있다. fetch type의 기본 세팅은 아래와 같다.
보면 ToMany로 컬렉션과 연결된 field의 경우가 기본값이 LAZY이며 이는 처음부터 다수의 object를 가져오는 쿼리는 불필요할 수 있기 때문일 것이다. 이 지연로딩을 이용하는 것으로 속도를 최적화 할 수 있고, 불필요한 데이터및 소스 낭비를 줄일 수 있다.
여러 relation에서 정의해주면 좋은 옵션이다. 영속성 전이의 의미는 특정 엔티티를 영속 상태로 만들 때, 연관된 엔티티도 함께 영속 상태로 만드는 것이다.
CASCADE의 종류는 아래와 같다.
내용들을 적고 보니 (1) 글에서 살짝만 이해하고 넘어갔던 JPA의 내부 구현이었던 영속성 컨텍스트와의 큰 연관성이 느껴진다.
JPA에서 부모 엔티티와 연관관계가 끊어진 자식 엔티티를 자동으로 삭제하는 기능을 제공한다. 즉 부모 엔티티에서 해당 엔티티(자식)의 참조를 제거하면 해당 엔티티가 바로 삭제된다는 것이다.
orphanRemoval 속성에 의해서 실현될 수 있으며
@OneToMany(name=~~, orphanRemoval = true)
이런 식으로 코드를 작성하면 된다.
스프링 프레임워크에서 JPA를 편리하게 사용할 수 있도록 지원해주는 프로젝트이다. 추가적인 코드가 필요한 상황이 아닐경우 Repository를 인터페이스 만으로 만들 수 있게 해준다.
JPA는 3가지 쿼리 메소드 기능을 제공한다.
fun findByEmailAndAddress(email: String, name: String) : List<Member>
위와 같은 함수 인터페이스 정의는 email과 name을 통해서 일치하는 Member list를 반환하는 메소드가 된다.
// count 쿼리
fun findByName(name: String, pageable: Pageable) : Page<Member>
//count 쿼리 사용 안 함
fun findByName(name: String, pageable: Pageable) : List<Member>
Spring Data JPA에서 제공하는 편리한 기능과, 영속성, FetchType에 대해서 간단하게 알아보았다. 이제야 내가 눈가리고 적었던 코드들의 의미가 보이는 것 같다.
N+1 problem?