Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
Tags
- 티스토리 쿠키 삭제
- iterator
- 스프링부트핵심가이드
- ㅒ
- 친절한SQL튜닝
- resttemplate
- 자료구조와함께배우는알고리즘입문
- 네트워크 설정
- 목록처리
- network configuration
- 코드로배우는스프링부트웹프로젝트
- 구멍가게코딩단
- 선형대수
- 처음 만나는 AI 수학 with Python
- 페이징
- 리눅스
- 서버설정
- 알파회계
- 코드로배우는스프링웹프로젝트
- 자바편
- 이터레이터
- 처음 만나는 AI수학 with Python
- GIT
- 스프링 시큐리티
- /etc/network/interfaces
- Kernighan의 C언어 프로그래밍
- baeldung
- 데비안
- d
- 자료구조와 함께 배우는 알고리즘 입문
Archives
- Today
- Total
bright jazz music
[bootBoard] N:1(다대일) 연관관계: 7-1. JPQL과 left(outer) join 연관관계 O 본문
Framework/Spring
[bootBoard] N:1(다대일) 연관관계: 7-1. JPQL과 left(outer) join 연관관계 O
bright jazz music 2022. 9. 28. 20:22- 하나의 엔티티 타입을 이용하여 목록 화면에서 게시글의 정보와 함께 댓글의 수를 함께 가져올 수는 없다.
- 이에 대한 해결책으로는 보편적으로 쓰이는 방법은 JPQL의 join을 이용하는 것이다.
1. left (outer) join
- 스프링 부트 2버전 이후 포함되는 JPA(Java Persistence API) 버전은 엔티티 클래스 내에 전혀 연관관계가 없어도 join을 사용할 수 있다.
- LEFT OUTER JOIN 혹은 LEFT JOIN 을 사용할 수 있다.
- 조인 시 INNER JOIN 혹은 JOIN 과 같이 일반적인 조인 역시 사용할 수 있다.
엔티티 클래스 내부에 연관관계가 있는 경우
Board 엔티티 클래스의 경우 내부에 Member 엔티티 클래스를 변수로 가짐으로서 연관관계를 맺고 있다.
//Board.java
package com.example.bootboard.entity;
import lombok.*;
import javax.persistence.*;
@Entity
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Getter
@ToString(exclude = "writer")
public class Board extends BaseEntity{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long bno;
private String title;
private String content;
@ManyToOne(fetch = FetchType.LAZY) //명시적으로 Lazy Loading 지정
private Member writer; //FK 연관관계 지정
//Board클래스는 Member클래스의 email(PK)를 FK로 참조하는 구조이다.
}
이러한 경우 Board의 writer 변수를 이용하여 조인을 처리한다. (연관관계를 맺고 있는 엔티티 클래스의 변수명)
BoardRepository.java 인터페이스에 해당 코드를 작성해 준다.
//BoardRepository.java
package com.example.bootboard.repository;
import com.example.bootboard.entity.Board;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
public interface BoardRepository extends JpaRepository<Board, Long> {
// 한 개의 로우(Object) 내에 Object[] 로 나옴
@Query("select b, w from Board b left join b.writer w where b.bno =: bno")
Object getBoardWithWriter(@Param("bno") Long bno);
//Board를 사용하지만 Member를 같이 조회해야 하는 상황
//Board 클래스에는 Member와의 연관관계가 있으므로 b.writer와 같은 형태로 사용한다.
// 이처럼 내부에 있는 엔티티를 이용할 때는 'LEFT JOIN' 뒤에 'ON'을 이용하는 부분이 없다.
}
작성을 완료했으니 테스트 코드로 getBoardWithWriter()를 확인한다.
//BoardRepositoryTests.java
...
@Test
public void testReadWithWriter() {
Object result = boardRepository.getBoardWithWriter(100L);
Object[] arr = (Object[]) result; //캐스팅
System.out.println("----------------------------");
System.out.println(Arrays.toString(arr));
}
에러 발생;
org.hibernate.QueryException: Named parameter not bound : bno; nested exception is java.lang.IllegalArgumentException: org.hibernate.QueryException: Named parameter not bound : bno
@Query("select b, w from Board b left join b.writer w where b.bno =: bno")
//마지막에 =: bno 사이를 띄어 써서 발생한 문제였음
아래와 같이 =:bno 붙여 쓰면 에러 소멸
@Query("select b, w from Board b left join b.writer w where b.bno =:bno")
테스트 결과
=> 지연 로딩으로 설정되어 있음에도 쿼리는 조인 처리가 되어 한 번에 board 테이블과 member 테이블을 이용함.
'Framework > Spring' 카테고리의 다른 글
[bootBoard] N:1(다대일) 연관관계: 8-1. 목록화면에 필요한 JPQL 생성 (0) | 2022.09.28 |
---|---|
[bootBoard] N:1(다대일) 연관관계: 7-2. JPQL과 left(outer) join 연관관계 X (0) | 2022.09.28 |
[bootBoard] N:1(다대일) 연관관계: 6-2. @ManyToOne과 Lazy loading (0) | 2022.09.27 |
[bootBoard] N:1(다대일) 연관관계: 6-1. @ManyToOne과 Eager loading (0) | 2022.09.27 |
[bootBoard] N:1(다대일) 연관관계: 5. 연관 관계 추가 (0) | 2022.09.18 |
Comments