JVM 85

컬렉션

하이버네이트는 컬렉션을 효율적으로 관리하기 위해 엔티티를 영속 상태로 만들 때 원본 컬렉션을 감싸고 있는 내장 컬렉션을 생성해서 이 내장 컬렉션을 사용하도록 참조를 변경한다. 하이버네이트가 제공하는 내장 컬렉션(org.hibernate.collection.internal.PersistentBag)은 원본 컬렉션을 감싸고 있어서 래퍼 컬렉션으로도 부른다. 하이버네이트는 이런 특징 때문에 컬렉션을 사용할 때 다음처럼 즉시 초기화해서 사용하는 것을 권장한다. Collection members = new ArrayList(); 하이버네이트 내장 컬렉션과 특징 컬렉션 인터페이스 내장 컬렉션 중복 허용 순서 보관 Collection, List PersistentBag O X Set PersistentSet X X ..

JVM/JPA 2023.07.02

스프링 데이터 JPA와 QueryDSL 통합

QueryDslPredicateExecutor QueryDSL을 검색조건으로 사용하면서 스프링 데이터 JPA가 제공하는 페이징과 정렬 기능도 함께 사용할 수 있다. 하지만 join, fetch를 사용할 수 없다. // 상속 public interface ItemRepository extends JpaRepository, QueryDslPredicateExecutor{} // 사용 QMember member = QMember.member; Iterable result = memberRepository.findAll( member.name.contains("김").and(member.age.between(10, 20)) ); public interface QuerydslPredicateExecutor { O..

JVM/JPA 2023.07.02

스프링 데이터 JPA

소개 단순 CRUD를 처리하기 위하여 데이터 접근 계층을 개발할 때 구현 클래스 없이 인터페이스만 작성하면 실행 시점에 스프링 데이터 JPA가 구현 객체를 동적으로 생성해서 주입해준다. 스프링 데이터 JPA는 스프링 데이터 프로젝트의 하위 프로젝트로 JPA에 특화된 기능을 제공한다. 스캔 범위 설정 @EnableJpaRepositories 어노테이션으로 범위를 지정해 줄 수 있으며 없을 시에는 @SpringBootApplication에서 설정한 빈 스캔 범위에서 스캔한다. @Configuration @EnableJpaRepositories(basePackages = "jpaboo.jpashop.repository") public class AppConfig {} JPARepository 주요 메소드 메소..

JVM/JPA 2023.07.02

객체지향 쿼리 심화

벌크 연산 벌크 연산은 수정, 삭제 모두 executeUpdate()를 사용한다. 이 메소드의 반환값은 영향을 받은 엔티티 건수이다. 벌크 연산은 2차 캐시와 영속성 컨텍스트를 무시하고 데이터베이스 직접 쿼리한다는 점에 주의해야한다. em.refesh(entity) 벌크 연산을 수행한 직후에 정확한 상품A 엔티티를 사용해야 한다면 em.refresh()를 사용해서 데이터베이스에서 상품A를 다시 조회하면 된다. 벌크 연산 먼저 실행 가장 실용적인 해결책은 벌크 연산을 가장 먼저 실행하는 것이다. 예를 들어 위에서 벌크 연산을 먼저 실행하고 나서 상품 A를 조회하면 벌크 연산으로 이미 변경된 상품 A를 조회하게 된다. 이 방법은 JPA와 JDBC를 함께 사용할 때도 유용하다. 벌크 연산 수행 후 영속성 컨텍..

JVM/JPA 2023.06.30

네이티브 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