본문 바로가기

웹 프로그래밍/JPA

(19)
객체 지향 쿼리 언어_중급 경로 표현식 -점을 찍어 객체 그래프를 탐색하는 것 select m.username (상태 필드) from Member m join m.team t (단일 값 연관 필드) join m.orders o (컬렉션 값 연관 필드) where t.name = '팀A' -상태 필드(state field): 단순히 값을 저장하기 위한 필드 -연관 필드(association field): 연관관계를 위한 필드 -단일 값 연관 필드: @ManyToOne, @OneToOne, 대상이 엔티티 -컬렉션 값 연관 필드: @OneToMany, @ManyToMany, 대상이 컬렉션 경로 표현식 특징 -상태 필드: 경로 탐색의 끝, 탐색 못함 -단일 값 연관 경로: 묵시적 내부 조인(inner join) 발생, 탐색 O -묵시적은..
객체 지향 쿼리 언어_기본 JPQL -JPA를 사용하면 엔티티 객체를 중심으로 개발 -문제는 검색 쿼리 -모든 데이터를 객체로 변환해서 검색하는것은 불가능 -검색 조건이 포함된 SQL이 필요 -JPA는 SQL을 추상화한 JPQL이라는 객체지향 쿼리 언어 제공 -JPQL은 엔티티 객체를 대상으로 쿼리 -SQL을 추상화해서 특정 데이터베이스 SQL에 의존X -동적 쿼리를 위해 QueryDSL 사용 JDBC 직접사용 하거나 SpringJdbcTemplate 사용 -JPA를 사용하면서 JDBC 커넥션을 직접 사용하거나, 스프링 JdbcTemplate, 마이바티스등을 함께 사용가능 -단, 영속성 컨텍스트를 적절한 시점에 강제로 플러시 필요(JPA와 관련이 없기 때문임) JPQL 문법 select_문 :: = select_절 from_절 [..
기본값 타입, 임베디드 타입 JPA의 데이터 타입 분류 -엔티티 타입 -@Entity로 정의하는 객체 -데이터가 변해도 식별자로 지속해서 추적가능 -값 타입 -int, Integer, String 처럼 단순히 값으로 사용하는 자바 기본타입이나 객체 -식별자 없으므로 변경시 추적 불가 값 타입 분류 -자바 기본타입(int, double) -래퍼 클래스(Integer, Long) -String -임베디드 타입(embedded type, 복합 값타입) e.g. 좌표등 커스텀 데이터 -컬렉션 값타입(자바 컬렉션) 기본값 타입 -생명주기를 엔티티에 의존 (e.g. 회원 삭제시 싹다 삭제됨) -값 타입은 공유 X 임베디드 타입 -새로운 값타입을 직접 정의 -주로 기본값타입을 모아서 만들어서 복합값 타입 값 타입 사용법 -@Embeddable:..
영속성 전이(CASCADE)와 고아 객체 영속성 전이(CASCADE) -특정 엔티티를 영속상태로 만들때 연관된 엔티티도 함께 영속 상태로 만들고 싶을때 -(e.g. 부모 엔티티 저장할때 자식도 함께 저장) -@OneToMany(mappedBy="parent", cascade=CascadeType.ALL) -부모를 persist할때 어노테이션 붙은 컬렉션등도 함께 persist(연쇄 반응) 주의 -연관관계 매핑하는것과 아무 상관이없음 -연관된 엔티티도 함께 영속화하는것임 -부모와 자식의 라이프 사이클이 동일하고 단일 엔티티에 종속적일때만 사용 고아 객체 -@OneToMany(mappedBy="parent", cascade=CascadeType.ALL, orphanRemoval = true) -고아 객체 삭제: 부모 엔티티와 연관관계가 끊어진 자식..
즉시로딩과 지연로딩 멤버 조회할때 팀까지 조회해야하나? -지연 로딩 LAZY를 사용해서 팀 객체를 프록시로 가져옴 -@ManyToOne(fetch = FetchType.LAZY) -실제로 팀 객체의 메서드를 사용하는 시점 DB에 쿼리가 따로 나감(초기화) 멤버와 팀을 자주 함께 사용한다면? 즉시로딩 EAGER를 사용해서 같이 가져옴 @ManyToOne(fetch = FetchType.EAGER) 주의사항 -실무에선 무조건 지연 로딩만 사용 -즉시 로딩을 적용하면 예상하지 못한 SQL이 발생(JPQL에서 N+1 문제를 일으킴) -@ManyToOne, @OneToOne은 기본이 즉시 로딩 -> LAZY로 설정 바꾸는거 필수 -@OneToMany, @ManyToMany는 기본이 지연 로딩
프록시 프록시의 기초 em.find(): 데이터베이스를 통해서 실제 엔티티(진짜) 객체 조회 em.getReferrence(): 데이터베이스 조회를 미루는 가짜(프록시) 엔티티 객체 조회 -DB에 쿼리가 안나가는데 저장이 된다? -> DB에 있는 값이 실제 사용되는 시점에 DB에 쿼리를 날림 프록시 특징 -실제 클래스를 상속받아서 만들어짐(겉모양이 같음) -사용자 입장에서 진짜인지 가짜인지 구분하지 않고 사용하면 됨 -프록시 객체는 실제 객체의 참조를 보관 -프록시 객체의 메서드를 호출하면 프록시 객체는 실제 객체의 메서드를 호출 -초기화 할때 없으면 영속성 컨텍스트에 초기화 요청하여 DB에서 가져와서 진짜 객체를 만들고 프록시 객체가 참조하여 연결시킴 -타입 비교 (==비교 대신 instance of 사용) ..
고급 매핑 상속관계 매핑 -RDB는 상속관계 X -슈퍼타입 서브타입 관계라는 모델링 기법이 객체상속과 유사하므로 매핑 상속관계 매핑 전략 -조인 전략(정석) -각각 테이블로 변환 -@Inheritance(strategy = InheritanceType.JOINED) -@DiscriminatorColumn (DTYPE 식별자 자동추가) -장점: 정규화, 외래키 참조 무결점 제약조건 활용(ITEM만 보면됨), 저장공간 효율화 -단점: 조인이 많이사용, 쿼리 많이 나감 -통합 테이블전략(싹 다 넣음): 단순할때 좋음 -기본값임(@Inheritance(strategy = InheritanceType.SINGLE_TABLE)) -DTYPE 필수(식별) -장점: 조인필요없음(빠름), 쿼리가 단순함 -단점: 자식 엔티티가 매핑..
연관관계 매핑 기초 연관관계가 필요한 이유 -객체를 테이블에 맞추어 데이터 중심으로 모델링하면, 협력관계를 만들수 없음 -테이블은 외래키로 JOIN을 사용해서 연관된 테이블을 찾는데 객체는 참조를 사용해서 연관관계를 찾음 -단방향 연관관계 지향(가급적 좋음) -객체 지향 모델링(연관관계 매핑(@JoinColumn)) 양방향 연관관계(반대 방향으로 객체 그래프 탐색) -테이블은 외래키로 다 조인할수 있음 -객체는 둘다 클래스 속성으로 가지고 있어야함 연관관계의 주인과 mappedBy -객체와 테이블의 연관관계 차이 -객체는 단반향이 두개 -테이블은 양뱡향 한개(외래키 조인) -둘중 하나로 외래 키를 관리해야함(외래키는 멤버객체를보고 바꿔야하나 팀 객체를 보고 바꿔야하나) 연관관계의 주인(Owner) -객체의 두관계중 하나를 ..