Spring/스프링 JPA 13

객체지향 쿼리 언어2 - 중급 문법

경로 표현식 특징 상태 필드 (state field): 경로 탐색의 끝, 탐색 X 단일 값 연관 경로: 묵시적 내부 조인(inner join) 발생, 탐색 O 컬렉션 값 연관 경로: 묵시적 내부 조인 발생, 탐색 X FROM 절에서 명시적 조인을 통해 별칭을 얻으면 별칭을 통해 탐색 가능 결론 : 묵시적 조인은 실무에서 쓰면 안 된다. 유지보수하기도 힘들다. 그러므로 명시적 조인으로 항상 작성해야 된다.! 상태 필드 경로 탐색 JPQL: select m.username, m.age from Member m SQL: select m.username, m.age from Member m 단일 값 연관 경로 탐색 JPQL: select o.member from Order o SQL: select m.* fro..

객체지향 쿼리 언어1 - 기본 문법

JPQL 소개 JPQL은 객체지향 쿼리 언어다. 따라서 테이블을 대상으로 쿼리하는 것이 아니라 엔티티 객체를 대상으로 쿼리한다. JPQL은 SQL을 추상화해서 특정데이터베이스 SQL에 의존하지 않는다. JPQL은 결국 SQL로 반환된다. JPQL 문법 select m from Member as m where m.age > 18 엔티티와 속성은 대소문자 구분 해야된다. (Member, age) JPQL 키워드는 대소문자 구분이 필요 없다. (SELECT, FROM, where) 엔티티 이름 사용, 테이블 이름 아님 (Member) 별칭은 필수(m)(as는 생략가능) TypeQuery, Query TypeQuery: 반환 타입이 명확할 때 사용 Query: 반환 타입이 명확하지 않을 때 사용 TypedQue..

값 타입 과 불변 객체

값 타입 공유 참조 임베디드 타입 같은 값 타입을 여러 엔티티에서 공유하면 위험함 부작용(side effect) 발생 문제는 이러한 사이드 이팩트를 찾기도 힘들다. public class JpaMain { public static void main(String[] args) { EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello"); // 애플리케이션 에서 한개만 만들어 져야된다. EntityManager em = emf.createEntityManager(); //하나의 단위를 만들때마다 만들어 줘야된다. EntityTransaction tx = em.getTransaction(); tx.begin(); try { Addre..

값 타입 - 기본값 타입, 임베디드 타입

기본값 타입 JPA의 데이터 타입 분류 엔티티 타입 @Entitiy로 정의하는 객체 데이터가 변해도 식별자로 지속해서 추적 가능 예) 회원 엔티티의 키나 나이 값을 변경해도 식별자로 인식 가능 값 타입 int, Integerm String처럼 단순히 값으로 사용하는 자바 기본 타입이나 객체 식별자가 없고 값만 있으므로 변경시 추적 불가 얘) 숫자 100을 200으로 변경하면 완전히 다른 값으로 대체 값 타입 종류 기본값 타입 자바 기본 타입(int, double) 래퍼 클래스(Integer, Long) String 임베디드 타입(embedded type, 복합 값 타입) 컬렉션 값 타입(collection value type) 기본값 타입 예): String name, int age 생명주기를 엔티티의 ..

영속성 전이 : CASECADE

영속성 전이: CASECADE 특정 엔티티를 영속 상태로 만들 때 연관된 엔티티도 함께 영속 상태로 만들고 싶을 때 예: 부모 엔티티를 저장할 때 자식 엔티티도 함께 저장. 영속성 전이: 저장 @OneToMany(mappedBy="parent", cascade=CascadeType.PERSIST) package helloJpa; import javax.persistence.*; @Entity public class Child { @Id @GeneratedValue private Long id; private String name; @ManyToOne @JoinColumn(name = "parent_id") private Parent parent; import java.util.ArrayList; impo..

즉시 로딩과 지연 로딩

Member를 조회할 때 Team도 함께 조회해야 할까? 지연 로딩 LAZY을 사용해서 프록시로 조회 @Entity public class Member extends BaseEntity { @Id @GeneratedValue @Column(name = "MEMBER_ID") private Long id; @Column(name = "USERNAME") private String name; @ManyToOne(fetch = FetchType.LAZY) // 팀을 프록시로 조회한다. @JoinColumn private Team team; 지연 로딩 지연 로딩 LAZY을 사용해서 프록시로 조회 em.find(Member.class, 1L);로 조회를 하게 되면 멤버는 DB에서 조회 후 영속성 컨텍스트에 저장하..

프록시

Member를 조회할 때 Team도 함께 조회해야 할까? 문제 발생 우리가 연관관계를 맺음으로써 회원의 이름만 조회하고 싶은데, 팀의 정보도 맵핑이 돼서 같이 조회되는 자원낭비가 발생할 수 있다. 이를 해결하기 위해 프록시를 사용한다. 회원과 팀 함께 출력 public void printUserAndTeam(String memberId) { Member member = em.find(Member.class, memberId); Team team = member.getTeam(); System.out.println("회원 이름: " + member.getUsername()); System.out.println("소속팀: " + team.getName()); } 회원만 출력 public void printU..

고급 맵핑

상속관계 매핑 관계형 데이터베이스는 상속 관계가 없음 슈퍼 타입 서브타입 관계라는 모델링 기법이 객체 상속과 유사 상속관계 매핑: 객체의 상속 구조와 DB의 슈퍼 타입 서브타입 관계를 매핑 상속관계 매핑 슈퍼타입 서브타입 논리 모델을 실제 물리 모델로 구현하는 방법 각각 테이블로 변환 > 조인 전략 통합 테이블로 변환 > 단일 테이블 전략 서브타입 테이블로 변환 > 구현 클래스마다 테이블 전략 1) 조인 전략 Join을 할 때 @DiscriminatorColumn을 넣지 않으면 DTYPE이 안 들어가게 된다. 이렇게 될 시 객체적으로 볼 때는 문제가 안되지만 DB만을 보게 될 시 어떻게 값이 들어오는지 찾기가 어려워진다. 때문에 조인 전략을 사용 할때@DiscriminatorColumn을 써주자. 장점 ..

다양한 연관관계 맵핑

연관관계 매핑 시 고려사항 3가지 다중성 단방향, 양방향 연관관계의 주인 다중성 다대일: @ManyToOne 일대다: @OneToMany 일대일: @OneToOne 다대다: @ManyToMany 다중성 같은 경우 간혹 헷갈릴 경우가 발생한다. 그럴 때는 반대쪽으로 생각해보면 된다. 회원과 팀이면 반대로 팀과 회원의 관계를 생각해보면 된다. 일대일의 반대는 일대일, 일대다의 반대는 다대일, 다대다의 반대는 다대다로 대칭 성이 있기 때문이다. 하지만 무엇보다도 중요한건 실무에서는 다대다를 쓰면 안 된다. 단방향, 양방향 테이블 외래 키 하나로 양쪽 조인 가능 사실 방향이라는 개념이 없음 객체 참조용 필드가 있는 쪽으로만 참조 가능 한쪽만 참조하면 단방향 양쪽이 서로 참조하면 양방향 연관관계 주인 테이블은 외..

연관관계 맵핑 기초

연관관계 맵핑 목표 객체와 테이블 연관관계의 차이를 이해 객체의 참조와 테이블의 외래 키를 매핑 용어 방향(Direction): 단방향, 양방향 다중성 : 다대일(N:1), 일대다(1:N), 일대일(1:1), 다대다(N:M) 이해 연관관계의 주인(Onwer): 객체 양방향 연관관계는 관리 주인이 필요 연관관계가 필요한 이유 객체지향 설계의 목표는 자율적인 객체들의 협력 공동체를 만드는 것이다. 예제 시나리오 회원과 팀이 있다. 회원은 하나의 팀에만 소속될 수 있다. 회원과 팀은 다대일 관계다. 단방향 연관관계 1) 객체를 테이블에 맞추어 모델링 2) 객체를 테이블에 맞추어 모델링 package helloJpa; import javax.persistence.EntityManager; import javax..