본문 바로가기

반응형

JPA

(15)
[JPQL] 페치 조인 - Fetch Join! (JPA의 N+1 문제 해결법) 실무에서 정말 정말 중요한 Fetch Join...에 대해 학습하자! (복습하고 또 복습하기) Fetch Join 연관된 엔티티나 컬렉션을 한 번에 함께 조회하는 기능 ( = 즉시 로딩) ➡️ 성능 향상! 일반적인 SQL 조인 종류가 아니다! JPQL에서 제공하는 성능 최적화를 위한 Join 기능 join fetch Fetch Join 사용법 JOIN FETCH 명령어로 사용 #1. OUTER JOIN (OUTER은 생략 가능!) LEFT [OUTER] JOIN FETCH + 조인 경로 #2. INNER JOIN (INNER 생략 가능!) [INNER] JOIN FETCH + 조인 경로 예시 상황) 회원(다) - 팀(일) 의 연관관계를 맺은 두 엔티티가 있다. 페치 조인을 통해, 회원 엔티티를 조회 시,..
JPQL의 내장함수와 사용자 정의 함수 JPQL에서 제공하는 기본함수 COUNT 결과 집합의 개수를 반환. 예) "SELECT COUNT(e) FROM Employee e" SUM 숫자 필드의 합계 계산. 예) "SELECT SUM(e.salary) FROM Employee e" AVG 숫자 필드의 평균 값을 계산. 예) "SELECT AVG(e.salary) FROM Employee e" MAX 숫자나 날짜 필드의 최댓값을 반환. 예) "SELECT MAX(e.salary) FROM Employee e" MIN 숫자나 날짜 필드의 최솟값을 반환. 예) "SELECT MIN(e.salary) FROM Employee e" DISTINCT 중복된 결과를 제거. 예) "SELECT DISTINCT e.department FROM Employee ..
JPA 매핑 애너테이션들! 객체와 테이블 매핑 @Entity JPA가 관리하는 Entity 객체 주의사항 **기본 생성자 필수!** final class, enum, interface, inner class 에서는 사용 불가 저장할 필드에 final 사용 ❌ @Table Entity와 매핑할 테이블 지정 @Entity //name: 매핑할 테이블 이름 @Table(name = "") public class className() { ... } @Entity //catalog: DB catalog 매핑 @Table(catalog = "") public class className() { ... } @Entity //schema: DB Schema 매핑 @Table(schema = "") public class className() {..
[JPA+Spring] 개발 할 때, 신경써야할 체크리스트 1. 컨트롤러에서 요청과 응답은 Dto로 빼주자. 엔티티를 직접 노출 X 꼭 DTO를 만들어서 반환해주자. 2. 페치 조인을 활용하자 Lazy Fetch로 설계된 엔티티들을 Eager Fetch로 수정하지말고, 페치 조인을 써서 한방 쿼리로 최적화 시켜주자. N+1도 해결된다. 쿼리문에서 쿼리용 Dto로 필요한 데이터들만 명시해주면, 불필요한 데이터들은 가져오지 않아, 조금 더 최적화 시켜줄 수 있다. 3. 1 대 다 페치 조인에서는 페이징을 쓰면 안된다. ".setFirstResult(n1)" , ".setMaxResults(n2)"와 같은 페이징은 쓰면 안된다. - DB에서 가져온 뻥튀기된 데이터들이 메모리에 올라가 메모리가 가득 찰 수도 있다. 1 대 다 컬렉션 조회 시, 페이징 구현하는 방법 먼저..
[JPA] Named Query - 쿼리를 함수처럼 만들어보자 Named Query 쿼리에 이름을 붙일 수 있는 기능 정적인 쿼리 어노테이션 혹은 XML에 정의 애플리케이션 로딩 시점에 초기화 후 재사용함 ➡️ ‼️ 애플리케이션 로딩 시점에 쿼리를 검증할 수 있음 ‼️ 사용 예시 @Entity @NamedQuery( name = "Member.findByUsername", // 쿼리의 이름 query = "select m from Member m where m.username = :username" // 실행할 쿼리문 ) public class Member { ... } //main ... // em.createNamedQuery로 호출 List resultList = em.createNamedQuery("Member.findByUsername", Member.cl..
[JPA] 경로 표현 경로 표현식 SELECT m.username ➡️ 상태 필드 FROM Member m JOIN m.team t ➡️ 단일 값 연관 필드 JOIN m.orders o ➡️ 컬렉션 값 연관 필드 WEHRE t.name = "팀A" 상태 필드 단순히 값을 저장하기 위한 필드 연관 필드 연관관계를 위한 필드 단일 값 연관 필드 연관 관계 대상이 엔티티 컬렉션 값 연관 필드 연관 관계 대상이 컬렉션 각 경로 표현식의 특징들! 상태 필드 경로 탐색의 끝 더 이상 탐색이 안된다. 단일 값 연관 경로 묵시적 내부 조인 발생 더 깊이 탐색이 가능하다. 컬렉션 값 연관 경로 묵시적 내부 조인 발생 더 이상 탐색이 안된다. ! 중요 ! 묵시적 내부 조인의 발생을 피하는 방향으로 만들자. 왜? ➡️ 프로젝트의 크기가 커지면,..
조건식 (case, coalesce, nullif) 기본 CASE 식 case로 열고, end로 닫음 Select case when m.age = 60 then "경로요금" else "일반요금" end from Member m 단순 CASE 식 case 앞에 변수 명시 가능 select case t.name when '팀a' then '인센티브추가' when '팀b' then '인센티브감소' else '인센유지' end from Team t COALESCE 하나씩 조회 후, NULL이 아니면 반환 //m.username이 null ➡️ "이름 없는 회원"이 반환 //m.username이 not null ➡️ m.username 값 반환 SELECT COALESCE(m.username, '이름 없는 회원') FROM Member m ------REUSLT-..
즉시로딩(EAGER Loading)과 지연로딩(LAZY LOADING) 만약, 멤버 클래스와 팀 클래스가 연관관계로 매핑되어 있다고 가정하자. 이때, 조회는 아래와 같이 3가지의 경우의 수가 있다. 멤버만 조회 팀만 조회 멤버와 팀 모두 조회 //1.멤버와 팀 다 가져옴. Member member = em.find(Member.class, 1L); //2.이때도, 멤버와 팀 다 가져옴. Team team = em.find(Team.class, 2L); 지연 로딩 Lazy Loading 근데 만약, 멤버 혹은 팀 하나만 가져오고 싶다면? ➡️ 지연로딩 Lazy Loading을 사용하자! //Member class @Entity public class Member{ ... @ManyToOne(fetch = FetchType.LAZY) // 이 부분! @JoinColumn(nam..