Coalesce
Query를 직접 쓴다면 뭐 DBMS에 따라 문법이 조금 다르겠지만
오라클의 경우 NVL이 바로 떠오르텐데 QueryDsl에서는 NVL이나 IF NULL 대신 Coalesce를 쓴다.
단순한 조회 시 문법은 아래와 같다.
.select(
QueryDsl 전용 엔티티(dto)의 참조변수.칼럼명.coalesce("NULL일시 표출하고 싶은 메세지").as("가명")
)
.from(QueryDsl 전용 엔티티(dto)의 참조변수)
.fetch();
위 문법의 예시는 아래와 같다.
.select(
codeDto.codeName.coalesce("아무것도 없네요").as("codeName")
)
.from(codeDto)
.fetch();
여기서 포인트는 as 로 가명을 지정해두는 것인데 가명을 지정해두지 않으면
어떤 필드로 인식해야하는지 모르기에 가명을 지정해둬야하고 그 가명은 엔티티 혹은 dto에 선언된 칼럼이어야 한다.
그래서 보통은 NVL 처리를 하고 싶었던 바로 그 칼럼을 가명으로 지정하는 경우가 많다.
출력하는 곳에서 그 칼럼을 출력하도록 설정해놨을 확률이 높기 때문이다.
위 문법을 활용해서 조금 응용해본다면 String 값으로 꼭 넣어야만 하는 것은 아니다.
칼럼을 넣을 수도 있다. 예시는 아래와 같다.
.select(
cardDto.userType.coalesce(cardDto.errorType).as(cardDto.userType)
)
.from(cardDto)
.fetch();
이렇게 되면 cardDto의 userType이 coalesce => NVL 이라면
cardDto의 errorType으로 출력하고 이 출력하는 것을 userType으로 인식해라 =>
HTML과 같은 VIEW에서는 userType을 출력 하도록 세팅만 해놓으면
DB에서 값을 긁어올 때 NULL인 경우 그 알맹이만 errorType으로 자동으로 치환해주고 껍데기는 userType안에 넣어놨기에 VIEW에서 바로 읽어올 수 있는 것이다.
한단계 더 응용해보자.
UserType이라는 칼럼에 값은 존재한다. 그러므로 그 자체로는 NULL이 아니다.
하지만 다른 테이블의 특정 칼럼과 비교해서 동일한 것만 가져오도록 설정해놨다면
UserType이라는 칼럼에 값은 그 값 자체는 존재해도 조건절에 걸리지 않아서 NULL이 들어올 수 있는것이다.
예를 들어 어떤 이유에서인지 UserType이라는 칼럼에 01, 02, 03, 04, 05 라는 값이 존재하고
다른 테이블에는 01, 02, 03 만 각각 성인, 노인, 어린이 등으로 정의되어 있다면
04, 05는 일치하지 않는 값이 되고 , 당연히 where 조건절에 걸리지 않아서 NULL이 되는 것이다.
이런 경우 NULL을 반환하지 않고 coalesce 를 활용해서 04를 그대로 넣어줄 수 있고
04 대신 04-미정의 라고 표시한다든지 커스터마이징(?)을 해서 출력할 수도 있다.
아래는 QueryDsl 파트의 예시이다.
codeDto.codeValue.coalesce(cardDto.userType).as(cardDto.userTypeValue),
codeDto.codeName.coalesce("미정의").as(cardDto.userTypeName),
아래는 View 파트의 예시이다.
<td class="table-data" th:text="|${history.userTypeValue} - ${history.userTypeName}|"></td>
이렇게 되면 coalesce 처리 후 04-미정의 로 출력이 되는 것을 확인할 수 있다.
'개발자 전향 프로젝트' 카테고리의 다른 글
Spring Boot에서 Logback 을 활용해서 Log 남기기 (0) | 2023.04.24 |
---|---|
QueryDsl - Case When과 Concat 활용법 (0) | 2023.04.11 |
Springdoc-openapi-ui로 Swagger3 사용하기 (0) | 2023.02.14 |
최신 Spring Security 사용법 - SecurityFilterChain (0) | 2023.02.09 |
QueryDSL에서 Date 타입들의 Parsing and Comparing (StringTemplate, DateTemplate, & Expressions) (0) | 2023.02.03 |