22/12/05

송은우·2022년 12월 5일
0

TIL

목록 보기
40/61

오늘 목표
1. JPA 프로그래밍 책 다 읽기
2. 프로그라피 코드 수정
3. 개인 계정에서 오픈 서치 연동해보기
4. 백준 java로 자료구조 관련 문제 풀기(silver)

  1. 백준 java 문제 풀기
    자료구조 관련 브론즈 문제중 많이 풀렸던 문제들을 다 풀었고, 실버 5 한 문제를 풀었습니다 내일은 그 위쪽 난이도로 진행해볼 예정입니다
  1. JPA 프로그래밍 읽기
    7장은 대충 읽었습니다
    8장 프록시, 즉시로딩, 지연로딩
    영속성 전이와 고아 객체

ch8

하이버네이트 구현체에 대한 내용
하이버네이트는 프록시 or 바이트 코드 수정 방식이 있지만, 설정이 편한 것은 프록시 쪽이다

em.find를 통해서 하나를 조회하는 방식이 있음. 이렇게 된다면 실제 사용하든 안 하든 데이터베이스를 조회하게 된다
em.getPreference 메서드를 통하면 프록시 객체를 반환해 실제 데이터 참고를 미룬다

프록시는 처음에는 target을 null로 가지고 있고, 영속 컨텍 거쳤다 db 거쳤다 entity 만들어서 target 세팅하고, target에 요청을 전달하는 역할을 함
상속받은 객체이기에, 타입체크 주의 해야함
찾는 엔티티가 이미 있으면 em.getPreference는 실제 엔티티를 바로 반환함
준영속 상태의 프록시를 초기화 하면 문제가 발생함

프록시는 getId를 호출했을 때는 초기화가 발생하지 않음. 접근 방식을 @Access(AccessType.PROPERTY) 를 사용했을 경우만 그렇다
@Access(AccessType.FIELD)는 JPA가 id만 조회하는 것인지, 아닌지를 파악할 수 없어 초기화 한다

연관관계 설정시에는 프록시를 이용하면 데이터베이스 접근 횟수를 줄인다. 연관관계 설정시 접근 방식을 필드로 해도 프록시 초기화가 되지 않는다

프록시 isLoaded 를 통해 초기화 되어있는지 확인 가능
클래스명을 직접 찍어보면 됨. javassist 라면 프록시
initialize메서드라면 하이버네이트에서 강제 초기화 가능하긴 함

지연로딩, 지연로딩
즉시 로딩 : 연관된 엔티티도 함께 조회한다

fetch=FetchType.EAGER, fetch=FetchType.LAZY
같은 속성을 줄 수 있다.
@ManyToOne(fetch=FetchType.LAZY)

즉시 로딩을 했을 때 join 쿼리로 가능하다면 묶는다
기본적으로 null이 가능하기에 nullable을 false 로 두면 innerjoin으로 긁어오고, nullable이 true라면 outerjoin으로 묶는다

@ManyToOne(optional=false)라는 속성도 nullable과 같은 역할을 한다
같이 쓰는 경우가 많다면 eager타입이 좋다
lazy는 결국 쿼리가 2번 날아가는 문제가 있을 수 있음

컬렉션 래퍼
하이버네이트는 영속 상태로 만들 때 컬렉션이 있으면 컬렉션을 추적하고 관리할 명목으로 원본 컬렉션을 하이버네이트가 제공하는 내장 컬렉션으로 변경하는데, 이를 컬랙션 레퍼라고 한다. 컬랙션은 컬랙션 래퍼가 프록시에 대한 역할을 함
getOrders().get(0) 같이 실제 인덱스가 호출될 때 초기화 됨

연관된 데이터가 수만건이라면 함께 로딩되는 점이 있다.
지연 로딩을 쓰는 쪽이 좋긴 함
EAGER 타입에서 컬렉션을 하나 두개 이상 즉시 로딩하는 것은 권장하지 않는다.
컬렉션을 하나까지 로딩하는 것은 괜찮지만 2개가 되면 n*m이 되어서 이상해질 수 있음
컬렉션 즉시 로딩은 무조건 outerjoin을 사용함

ManyToOne, OneToOne
optional false일 때만 inner join
나머지 경우는 무조건 outer join

영속성 전이 cascade
영속성 전이를 쓰면
부모 객체를 영속시키면, 알아서 자식도 같이 영속되는 상태를 보장해줌
cascade=CascadeType.persist 라는 부분을 줄 수 있음

영속성 전이는 연관관계 매핑과 아무 관련이 없다.
영속화 할 때 같이 영속화 하는 편리함일 뿐
부모를 제거함녀 한꺼번에 제거가 될 수 있다는 점 정도

CascadeType.ALL 모두, Persist 영속, MERGE 병합, REMOVE, REFRESH, DETACH
여기서 여러 속성 동시도 가능함
em.persist, em.remove같은 경우에는 전이가 바로 발생하는 것이 아니라, 플러시 호출시 전이가 발생함

고아객체 : 부모 엔티티와 연관관계가 끊어진 자식 엔티티를 자동으로 제거하는 기능 제공. 이를 고아 객체 제거라 한다.

부모 엔티티의 컬렉션에서 자식 엔티티의 참조를 제거하면 바로 자식엔티티가 제거되도록 하는 것

orphanRemoval=true 를 통해 줄 수 있음
OneToOne이나, OneToMany 일 경우에만 할 수 있다

CASCADE type.REMOVE도 같이 하게 해준다

CascadeType.ALL, orphanRemoval=true
2가지를 모두 사용하면
부모 엔티티를 통해 자식 엔티티의 생명주기를 관리할 수 있음
DDD의 AggregateRoot와 같이 사용하면 좋음
OneToMAny, ManyToMany는 기본이 지연 로딩, 나머지는 기본이 EagerLoading임.

ch9

값 타입
String같은 단순 값으로 사용되는 객체
식별자가 없고, 속성만 있어 추적할 수 없음
값 타입은 3종류
기본값(int, Integer, String)
임베디드 타입(복합 값타입)
컬렉션 값타입(collectionValueType)
임베디드는 jpa 개발자가 직접 정의한 값 타입
컬렉셭 값타입은 하나 이상의 값 타입을 저장할 때 사용한다

값 타입은 공유되면 큰일난다. 한 명의 나이를 바꾼다고 다른 사람의 나이까지 바뀌면 안 되는 느낌

임베디드
@Embedded 를 적으면 됨
column은 눈치껏 있고, 메서드도 눈치껏 있는 객체
@Embeddable 값타입을 정의하는 곳에 표시
@Embedded 값타입을 사용하는 곳에 표시
기본 생성자가 필수
composition 관계
하이버네이트는 임베디드 타입을 컴포넌트라고 함
객체에 컬럼을 매핑해줌.
임베디드 타입 덕분에 fine-graned 하게 매핑하는 것이 가능함
ORM을 사용하면 테이블 수보다 클래스가 많다.

@AttributeOverrides를 쓰면 임베디드 타입에 정의한 매핑 정보를 수정할 수 있다
보통 너무 복잡해져서 잘 안쓰는 편
embeded 타입이 null이면 연관된 거 다 null

값 타입은 복잡한 객체를 더 단순하게 만듦
값타입을 복사해야됨
하지만 값타입인지를 볼 수가 없음
따라서 그냥 update같은 메서드를 없애는 쪽이 좋음
불변객체로 설계하는 쪽이 좋음
생성자로만 설정함
동일 ==
동등 equals. equals 재정의 시 hashcode도 같이 재생성해라
ide에 보통 자동 생성 기능이 있음
@ElementCollection 을 통해서 가능함
@CollectionTable을 통해서 설정이 가능함
일대다 관계로 매핑해줌
이때도 @Embeddable을 설정해야됨
값타입 컬렉션은 영속성 전이, 고아 객체 제거 기능을 필수로 가짐
값 타입 컬렉션은 모든 데이터를 다 삭제하고 다시 추가해버려야됨. 기본키도 무조건 필요함
이런 문제를 수정하고자 컬렋녀 댓니 일대다를 하는 경우가 많음
엔티티 타입의 특징 :
식별자 있음
생명 주기가 있다. 생성, 영속, 소멸
공유 가능

값타입
식별자 없음
생명 주기 엔티티에 의존
공유하지 않는 것이 안전

ch10

criteria나, querydsl은 jpql을 편리하게 학습하도록 도와주는 기술

jpql : 테이블이 아닌 객체가 대상으로 검색하는 쿼리
sql을 추상화해서 특정 데이터베이스 sql에 의존하지 않음
querydsl : jpql 작성 도와줌
코드 간결
엔티티 직접 조회, 묵시적 조인, 다형성 지원으로 sql보다 코드 간단

criteria는 코드 기반 jpql이기에 컴파일 타임 검증 가능
단점은 장황하게 느껴질 수 있음
메타 모델로 "username"같은 필드도 코드로 바꿀 수 있다는 부분이 있었음

QueryDSL은 비표준 오픈소스 프로젝트 일뿐.
QueryDSL은 어노테이션 프로세서를 사용해서 쿼리 전용 클래스를 만들어야 함.
jpa로 native sql 도 작성 가능함
jdbc를 직접 사용하고 싶다면 jpa 구현체가 사용하는 방법을 사용해야됨
jdbc나 마이바티스를 jpa와 사용하면 영속성 컨텍스트를 강제로 플러싱 해야됨
jdbc, 마이바티스 같은 sql 매퍼 같은 것들은 모두 jpa를 우회함

마지막 봐야될 부분
cascade와, orphanRemoval, 7장

profile
학생의 마음가짐으로 최선을 다하자

0개의 댓글