JVM 80

네이티브 SQL

JPQL을 사용할 수 없을 때 SQL을 직접 사용할 수 있는 기능을 네이티브 SQL이라 한다. 네이티브 SQL을 사용하면 엔티티를 조회할 수 있고 JPA가 지원하는 영속성 컨텍스트의 기능을 그대로 사용할 수 있다. 엔티티 조회 실제 데이터베이스 SQL을 사용한다는 것과 위치기반 파라미터만 지원한다는 차이가 있다. 하이버네이트는 이름 기반 파라미터를 지원한다. String sql = "SELECT ID, AGE, NAME, TEAM_ID FROM MEMBER WHERE AGE > ?"; Query nativeQuery = em.createNativeQuery(sql, Member.class).setParameter(1, 20); List resultList = nativeQuery.getResultList..

JVM/JPA 2023.06.30

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