전체 글 283

QueryDSL

build.gradle dependencies { ... // QueryDSL JPA 라이브러리 implementation 'com.querydsl:querydsl-jpa' // QueryDSL 관련된 쿼리 타입(QClass)을 생성할 때 필요한 라이브러리로, annotationProcessor을 사용하여 추가 annotationProcessor "com.querydsl:querydsl-apt:${dependencyManagement.importedProperties['querydsl.version']}:jpa" // java.lang.NoClassDefFoundError(javax.annotation.Entity) 발생 시 추가 annotationProcessor 'jakarta.persistence:..

JVM/JPA 2023.06.28

JPQL 조건식

타입 표현 종류 설명 예제 문자 작은 따옴표 사이에 표현 작은 따옴표를 표현하고 싶으면 작은 따옴표 연속 두 개 사용 'HELLO' 'She''s' 숫자 L(Long 타입 지정) D(Double 타입 지정) F(Float 타입 지정) 10L 10D 10F 날짜 DATE {d 'yyy-mm-dd'} TIME {t 'hh-mm-ss'} DATETIME {ts 'yyyy-mm-dd hh:mm:ss,f'} {d '2012-03-24'} {t '10-11-11'} {ts '2012-03-24 10-11-11.123'} m.createDate = {d '2012-03-24'} Boolean TRUE, FALSE Enum 패키지명을 포함한 전체 이름을 사용 jpabook.MemberType.Admin 엔티티 타입 엔..

JVM/JPA 2023.06.28

JPQL 서브쿼리

제약 사항 WHERE, HAVING 절에서만 사용할 수 있고 SELECT, FROM 절에서는 사용할 수 없다. 하이버네이트의 HQL은 SELECT 절의 서브 쿼리도 허용한다. 하지만 FROM 절의 서브쿼리는 지원하지 않는다. 일부 구현체는 FROM 절의 서브 쿼리도 지원한다. 서브 쿼리 함수 EXISTS 문법: [NOT] EXISTS (subquery) 설명: 서브쿼리에 결과가 존재하면 참이다. NOT은 반대 팀A 소속인 회원 SELECT m FROM Member m WHERE EXISTS (SELECT t FROM m.team t WHERE t.name = '팀A') ALL, ANY, SOME 문법: { ALL | ANY | SOME } (subquery) 설명: 비교 연산자와 같이 사용한다. ALL:..

JVM/JPA 2023.06.26

JPQL 조인과 페치조인

조인 // 내부 조인 SELECT m FROM Member m JOIN m.team t List members = em.createQuery(query, Member.class).getResultList(); // 외부 조인 SELECT m FROM Member m LEFT JOIN m.team t List members = em.createQuery(query, Member.class).getResultList(); // 컬렉션 조인 SELECT t, m FROM Team t LEFT JOIN t.members m List members = em.createQuery(query, Member.class).getResultList(); // 세타 조인(전혀 관계 없는 테이블들끼리의 조인) // JPQL ..

JVM/JPA 2023.06.25

JPQL 기초

특징 객체지향 쿼리 언어다. 따라서 테이블을 대상으로 쿼리 하는 것이 아니라 엔티티 객체를 대상으로 쿼리 한다. SQL을 추상화해서 특정 데이터베이스 SQL에 의존하지 않는다. JPQL은 결국 SQL로 변환된다. SELECT 문 SELECT m FROM Member AS m where m.username = 'Hello' SELECT m FROM Member m where m.username = 'Hello' // AS는 생략할 수 있다. JPQL 키워드는 대소문자를 구분하지 않고 엔티티와 필드는 대소문자를 구분한다. JPQL은 별칭을 필수로 사용해야 한다. TypeQuery, Query 반환할 타입을 명확하게 지정할 수 있으면 TypeQuery, 반환 타입을 명확하게 지정할 수 없으면 Query 객체를..

JVM/JPA 2023.06.25

값 타입 컬렉션 @ElementCollection @CollictionTable

값 타입을 하나 이상 저장하려면 컬렉션에 보관하고 @Elementcollection, @CollectionTable 어노테이션을 사용한다. 값 타입 컬렉션은 영속성 전이와 고아 객체 제거 기능을 필수로 가지고 있다. 값 타입 컬레션도 조회할 때 페치 전략을 선택할 수 있는데 LAZY가 기본이다. 값 타입 컬렉션에 변경 사항이 발생하면 값 타입 컬렉션이 매핑된 테이블의 연관된 모든 데이터를 삭제하고, 현재 값 타입 컬렉션 객체이 있는 모든 값을 데이터베이스에 다시 저장한다. 따라서 값 타입 컬렉션이 매핑된 테이블에 데이터가 많다면 일대다 관계를 고려해야 한다. 예제 Member 엔티티 하나의 3개의 테이블을 사용하고 있는 예제이다. @Entity public class Member { @Id @Genera..

JVM/JPA 2023.06.25

임베디드 타입(복합 값 타입) @Embedded, @Embeddable

새로운 값 타입을 직접 정의해서 사용하는 것을 임베디드 타입이라고 한다 주의 임베디드 타입의 인스턴스를 여러 엔티티에서 공유하는 것은 데이터 무결성에 굉장히 치명적이다. 인스턴스를 복제해서 사용하거나 임베디드 타입에서 setter를 없애자. 예제 코드 @Entity public class Member { @Id @GeneratedValue private Long id; private String name; @Embedded Period workPeriod; @Embedded Address homeAddress; @Embedded @AttributeOverrides({ // 같은 타입을 사용할 경우 컬럼명을 재정의한다. 위치는 엔티티 필드에!! @AttrbuteOverride(name="city", col..

JVM/JPA 2023.06.24

영속성 전이, 고아 객체

CascadeType.ALL + orphanRemoval = true를 동시에 사용하면 부모 엔티티를 통해서 자식의 생명 주기를 관리할 수 있다. 영속성 전이: cascade 특정 엔티티를 영속 상태로 만들 때 연관된 엔티티도 함께 영속 상태로 만들고 싶을 때 사용하는 옵션이다. 부모 엔티티와 함께 자식 엔티티도 저장하거나 삭제할 수 있다. 종류 CascadeType.ALL 모두 Cascade를 적용한다. CascadeType.PERSIST Save, Persist 시 함께 영속화한다.. CascadeType.MERGE 업데이트 시 함께 업데이트한다. CascadeType.REMOVE 삭제 시 함께 삭제된다 CascadeType.REFRESH 새로고침 시 함께 새로고침 한다. CascadeType.DET..

JVM/JPA 2023.06.23

즉시 로딩, 지연 로딩, 프록시

JPA 기본 페치 전략 연관된 엔티티가 하나면 즉시 로딩을, 컬렉션이면 지연 로딩을 사용한다. 모든 연관관계에 지연 로딩을 사용하고 개발 완료단계에 꼭 필요한 곳에만 즉시 로딩을 사용하는 것을 권장한다. 즉시 로딩 JPA는 선택적 관계면 외부 조인을 사용하고 필수 관계면 내부 조인을 사용한다. 외부 조인보다 내부 조인이 성능가 최적화에서 더 유리하므로 NULL을 허용하지 않는다면 JPA에게 확실히 알려주는 게 좋다. 컬렉션 즉시 로딩은 항상 외부 조인을 사용한다. @JoinColumn(nullable = false) 혹은 @ManyToOne(optional = false) 프록시 프록시는 엔티티가 생성되어 있지 않으면 영속성 컨텍스트에 엔티티 생성을 요청하는데 이것을 초기화라 한다. EntityManag..

JVM/JPA 2023.06.23