Today I Learned
(24.07.24)[15주차] Sprint Data JPA Tuple 객체의 사용
JPQL을 통한 JPA를 쿼리 언어를 사용하면서 여러 테이블을 조인을 하다가 보면은 다양한 컬럼들의 값들을 골라서 사용을 하고 싶을 때가 있다.
즉 게시글 테이블에는 작성자 User의 ID만이 저장되어있지만, User 테이블과 JOIN을 해서 User 테이블에서 사용자ID가 아닌 이름이나 기타 정보를 가지고 있는 컬럼들을 골라서 가지고 올 수 있어
프로젝트에 있어서 조회 부분에 능동적으로 사용하기 위해서 Tuple 객체의 사용을 정리
Tuple 객체
- JPQL은 SQL 처럼 Table 이 아닌 Entity(객체) 기준으로 작성하는 쿼리문으로 @Query Annotation을 사용해서 해당 쿼리를 컴파일시 체크를 할 수 있도록 할 수 있음
- 따라서, 이러한 JPQL은 실제 SQL처럼 JOIN 문을 통해서 여러 엔터티 = 테이블을 합칠 수 있고, 여기서 발생한 DB에서 발생한 조인 테이블의 다중 컬럼들을 묶은 어떤 객체
- DB의 ROW 값을 Tuple이라하는 그 값을 말하는 것
Object[] 를 사용안하는 이유
- Tuple객체의 컬럼들은 이름을 지정해서 사용할 수 있고, Object는 컬럼 외에도 다른 Java 객체도 모두 포함하기 때문에 오류발생 가능성이 높음
- 무조건 하나씩 인덱스 값을 빼올때마다 캐스팅을 해야하는데 이 과정에서 맞지 않을 경우, 오류가 당연히 발생하는 불편함이 존재
Tuple 객체 주요 메서드
get(String alias)
- Tuple 객체에 있는 Column 이름을 넣어서 해당 Column을 Object 타입으로 반환
- 어떤 특정 값을 구하려는 것이 아니라 해당 컬럼을 다른 Tuple 타입을 지원하는 데이터로 add 등을 통해 가공을 할 때 사용
get(int index)
- 해당 인덱스의 Column을 Object 타입으로 반환 하는 메서드
- 위의 get과 비슷한 메서드
get(int index, Class<T> type)
- 해당 인덱스의 Column을 지정한 리터럴 타입으로 반환 하는 메서드
- 가장 많이 활용할 수 있는 메서드
ex) String name = tuple.get(0, String.class);
getJavaType(String alias)
- Class<T> type 으로 괄호안의 Column 어떤 타입인지 알 수 있는 메서드
getAlias(int index)
- 해당 index의 Column 의 Alias 를 String 타입으로 알 수 있는 메서드
Tuple 활용하기
- 실제 프로젝트에서 활용해보면서 어떻게 작동되는지 기록
// Repository
public interface CodeReviewCommentsRepository extends JpaRepository<CodeReviewComments, Long> {
@Query("SELECT crc, u.name, COUNT(l) AS likes FROM CodeReviewComments crc " +
"LEFT JOIN Users u ON crc.user.id = u.id " +
"LEFT JOIN Likes l ON crc.id = l.codeReviewComment.id AND l.status = 'LIKED' " +
"WHERE crc.codeReviews.id = :codeReviewsId AND crc.status = 'ACTIVE' " +
"GROUP BY crc.id, u.name " +
"ORDER BY crc.createdAt DESC")
List<Tuple> findByCodeReviewIdWithDetails(Long codeReviewsId);
}
- JPQL로 Likes 객체, User 객체, CodeReviewComments 객체 3가지 객체로 만들어진 DB의 테이블 JOIN
- CodeReviewComments Column들 + User의 Name Column + Likes 객체 COUNT Column
List<Tuple> responseList = codeReviewCommentsRepository.findByCodeReviewIdWithDetails(
codeReviewsId)
- 사실상 JOIN 된 테이블은 Tuple이 순서대로 저장된 어떠한 List<Tuple> 됨
public class CodeReviewCommentsWithLikesResponseDto {
private final Long id;
private final String contents;
private final String name;
private final Long likes;
private final LocalDateTime createdAt;
private final LocalDateTime modifiedAt;
public CodeReviewCommentsWithLikesResponseDto(Tuple tuple) {
CodeReviewComments codeReviewComments = tuple.get(0, CodeReviewComments.class);
String name = tuple.get(1, String.class);
Long likes = tuple.get(2, Long.class);
this.id = codeReviewComments.getId();
this.contents = codeReviewComments.getContents();
this.name = name;
this.likes = likes;
this.createdAt = codeReviewComments.getCreatedAt();
this.modifiedAt = codeReviewComments.getModifiedAt();
}
}
- 따라서, 각 튜플의 Column 즉 Attribute 를 인덱스로 반환 타입을 지정하는 get 메서드를 활용이 가능
- 위는 ResponseDto를 만들 수 있는 생성자에 사용된 예시
'Today I Learned' 카테고리의 다른 글
(24.08.05)[17주차] Nginx 404 Not Found 오류 고찰과 해결 (0) | 2024.08.05 |
---|---|
(24.08.02)[16주차] CD Pipeline 중 GitHubs자동화 배포에 대한 정리 (0) | 2024.08.02 |
(24.07.23)[15주차] MinIO 활용 정리 - 코드 분석 (0) | 2024.07.23 |
(24.07.22)[15주차] MinIO 활용 정리 (0) | 2024.07.22 |
(24.07.15)[14주차] 프로젝트 중 동시성 제어를 위한 Redisson 활용 (1) | 2024.07.15 |