본문 바로가기

728x90

Spring/JPA

(11)
[JPA] 양방향 매핑 관계 로딩 방법 별로 살펴보기 (N+1 문제는 도대체 언제?) 개인적으로 너무 헷갈리고, 진심인데 블로그 포스트마다 내용이 다른 것 같기도 하다. 그냥 직접 하면서 최대한 가능한 상황들을 정리해보려고 한다. 더 헷갈리게만 만드는 장황한 설명따윈 없이, 그냥 내가 정리하고 싶기도 해서 특정 CASE 에 대한 결과만 정리하니, 참고하실 분들은 결과만 참고하시면 좋을 것 같다. 기본적으로 다음과 같이 클래스들이 있다. 이하로 정리되는 내용은 의 제목으로 정리된다. @Entity @Getter @NoArgsConstructor @Table(name = "groups") public class Group { @Id @GeneratedValue private Long id; private String name; @OneToMany(mappedBy = "group", fetch..
[JPA] 연관 객체 불러오기.. Fetch Join 정말 괜찮을까? 결론부터 말하자면 약간 뻘짓한 글이다. 그래도 긍정적으로 본다면 고민을 해봤다는 의의는 있으니.. 초보자의 수준에서 한 번 고민을 공유한다고 생각하면 될 것 같다. (1) 개요 서비스단을 개발하다 고민하게 된 부분이 있어서, 정리해보면서 결론을 만들어 나가보기로 했다. 우선 개요는 다음과 같다. Group 객체가 있고, Group 활동 안에 게시물인 Post 객체가 있으며, Post 에는 댓글인 Comment 객체가 있는 다음과 같은 상황이다. 아래에는 표시되어 있지 않지만, Member 객체가 당연히 있으며, Member 와 Group 사이에는 현재 상태가 기록되고, [강퇴 / 휴면 / 활동] 의 세 가지 상태로 관리된다. 이와 같은 관계는 많이 발생하는 일반적인 상황으로, 모두 비식별 관계이다. 이 ..
[JPA] - 나머지 쿼리 1. 다형성 쿼리 > treat, item 등의 쿼리문 사용 가능 > ex) select i from Item i where treat(i as Book).author= 'kim'; // treat = 일종의 캐스팅 > 사용한 테이블 전략에 맞춤형으로 SQL이 나가게 됨. 2. 엔티티 직접 사용 > 엔티티 칼럼을 직접 사용하면, SQL에서는 당연히 해당 엔티티의 기본 키값을 사용 > 그냥 엔티티를 직접 파라미터로 전달해서 사용할 수 있다는 특징이 있음 가령, em.createQuery("select m from Member m where m = :member").setParameter("member", member) em.createQuery("select m from Member m where m.id..
[JPA] JPQL 쿼리 2 (FETCH JOIN의 등장) 1. 경로 표현식 * 경로 표현식 - 객체 그래프 내를 탐색하기 위한 필드 표현 방식 상태 필드 (State Field) > 단순 값 저장 필드 : m.username (m = alias 준다고 표현) 연관 필드 (AssoociationField) > 연관관계를 위한 필드 : 단일 값 연관 필드(경로) / 컬렉션 값 연관 필드 *상태 필드 상태 필드 >> 경로 탐색의 끝. 탐색 종료. 예를 들자. String query = "select m.username from JpqlMember m"; *단일 값 연관경로 username.~ 가 더이상 어디서 갈 수가 없음. 상태필드를 만나게 되면 탐색의 끝. String query = "select m team from JpqlMember m"; 연관관계 (One..
[JPA] JPQL 쿼리 결국 DB 조회를 위해선 쿼리를 짤 수밖에 없는데, JPQL, 네이티브 SQL, Query DSL 등 다양한 방법을 지원 JPA를 사용하면 결국 Entity 중심으로 개발할 수밖에 없음. > 검색을 할때도 테이블이 아닌 Entity 를 대상으로 검색을 해야해함. > 그렇다면 뭐,, DB 데이터를 다~ 들고 온다음에 메모리에서 다~ 실행해서 객체로 변환한 다음에 Entity 대상으로 검색을 할 수 있도록 해야하나? > 이거는 말이 안됨. > App이 필요한 Data만 DB에서 불러오려면 결국 ! SQL을 찍어야 함. JPA + SQL 을 지원하는 JPQL 을 지원함. > JPQL은 일반 SQL처럼 DB 테이블 대상으로 하는게 아니고, 객체를 대상으로 한다. 니가 하던게 다 Entity 대상으로 쿼리 짠거임..
[JPA] - 값 타입 > 1) 엔티티 타입 - @Entity 로 정의하는 클래스 객체 - 데이터가 변해도 식별자로 지속 추적 가능 > PK 값으로 구분 가능 2) 값 타입 - 변경시 추적이 어려운, 단순한 값으로 사용되는 자바 기본 타입 / 객체 값타입 기본값 / 임베디드 타입 / 컬렉션 타입 으로 나뉨 >> 값타입은 항상 불변객체로 한다라고 그냥 생각해도 됨 (아래 나옴) 기본값 - 생명 주기가 엔티티에 의존된다. 기본값, 기본 타입 은(int, double) 은 공유가 안된다. int a= b int b= a a = 20; 출력해보면 a =20, b = 10 이 된다. 하지만 클래스 (래퍼 클래스처럼) Integer a= new Integer(10); Integer b = a; a.setValue(20); // 이런거 없..
[JPA] 프록시와 연관관계 - 2 4) 영속성 전이 :CASCADE (생각보다 많이 씀) CASCADE 란? 즉시 로딩 레이지 로딩과 아무 관계도 아니다! (헷갈릴 수는 있음) 특정 엔티티를 영속화 시킬 때 연관 엔티티도 함께 영속화 시키는 것을 말한다. 예시를 다음과 같이 보자. @Entity @Data public class Parent { @Id @GeneratedValue private Long id; private String name; @OneToMany(mappedBy = "parent") private List children = new ArrayList(); public void addChild(Child child) { children.add(child); child.setParent(this); } } @Entity ..
[JPA] 프록시와 연관관계 정리 ** 매우 중요한 부분 class Member{ String username; Team team; } class Team{ String name; } Member를 조회할 때 Team 도 함께 조회되어야 할까? ---- 만약 Member에 대한 정보와 Team 에 대한 정보를 한꺼번에 사용을 해야 할 때 : 한번에 쿼리로 가져오면 좋음 ---- 반대로 Member에 대한 정보만 활용하면 될 때 : Team 쿼리 까지 굳이 나가는 것은 손해임. (즉, 비즈니스 상황에 따라 다르긴 함) 1) 프록시 > em.find() // em.getReference() 란 녀석도 있음. getRefrence() 란, DB 조회를 미루는 가짜 (Proxy) Entity 객체가 조회됩니다. 다음 예시 @Test @Displ..
[JPA] 연관관계 매핑 -2 연관관계 매핑시 고려해야할 사항 1. 다중성 (다대일, 일대다, 일대일, 다대다) - 이건 참고로 RDBMS 를 위함임 2. 단방향 양방향 3. 연관주. 1) 다대일 다대다대 (외래키가 가는 곳이 다, 연관관계의 주인이 다, DB를 다스리는 쪽이 다, 조회만 하는쪽이 일) (지난 시간에 한 Member : Team 연관관계로 생각) (내가 DB에 넣을 칼럼과 동기화 시켜주면 됨. @JoinColumn(name = "team_id")) 2) 일대다 일대일대 (이건 연관주를 (일) 쪽에 두겠다는 것) (위에 모델을 뒤집은 것) (Team List 에서 DB를 다스림) (하지만 DB에서는 Member 쪽에 (다) 쪽에 외래키가 들어갈 수밖에 없음. 왜냐면 Team 쪽엔 그러면 ㅅㅂ member_id 계속 넣어..
[JPA] - 엔티티 매핑 실제 JPA 가 DB 와 어떻게 엔티티를 매핑할까요? 1) 객체와 테이블 매핑 (@Entity, @Table) @Entity - JPA 가 관리할, 엔티티라 부른다. (No Args Contructor 필수), 이상한 클래스로는 불가 @Table - Entity Class 이름과 다르게 들어가야 한다면 name 지정 가능 2) DB Schema 자동생성 JPA에서는 앱 로딩 시점에 DB table 을 생성하도록 함 -> 당연히 운영은 쓰면 안되고, 완성된 DB 구조를 넣어야 함. (운영에서 쓸 때는 테스트 서버, 릴리즈 서버에 있는 것을 다듬은 다음에 보내야 함) ddl-auto 속성 1) CREATE - 매번 모든 테이블을 (있으면) 모두 삭제후 다시 초기화 시킴 (@Entity 모두 확인 후) (이건..