반응형
가끔 가다가 DB 설계가 이상하게 되어 있어서 Number 타입이었어야 하는 컬럼이 Varchar로 되어 있는 경우가 있다.
이런 경우 음 그냥 String을 Int로 바꿔서 쿼리하면 되는 거 아니야? 라고 생각이 드는데 QueryDSL에선 그게 불가능하다.
해결 방법은 castToNum을 사용하면 된다. 아래 예제를 봐보자.
해결 방법
Comment의 seq는 원래 Int가 정상인데 잘못된 설계로 인해 String으로 설계가 되어있다고 가정한다. (DB: MySQL)
@NoArgsConstructor
@AllArgsConstructor
@Entity
public class Comment {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
private String seq; // Int가 정상
@OneToOne
private Board board;
}
seq가 2보다 큰 Comment를 가져오는 경우에 QComment의 seq를 보면 StringPath로 되어 있어서 goe나 loe 같은 메소드를 사용할 수 없다.
이런 경우엔 NumberExpression으로 변경해주는 castToNum을 사용하면 된다.
@Override
public List<Comment> findBySeqGreaterThanEqual(int seq) {
return queryFactory
.selectFrom(comment)
.where(comment.seq.castToNum(Integer.class).goe(seq)) // castToNum 사용
.fetch();
}
아래와 같이 테스트를 돌려서 쿼리를 확인해보면 cast 함수를 사용해서 쿼리를 던지는 걸 볼 수 있다.
@Test
void findByOrderGreaterThanEqual() {
for (int i=0; i<3; i++) {
commentRepository.save(new Comment(null, String.valueOf(i), null));
}
List<Comment> comments = commentRepository.findBySeqGreaterThanEqual(2);
assertThat(comments.size()).isEqualTo(1);
}
= select
comment0_.id as id1_1_,
comment0_.board_id as board_id3_1_,
comment0_.seq as seq2_1_
from
comment comment0_
where
cast(comment0_.seq as signed)>=?
Int 대신 Long이 필요한 경우 Long.class를 사용하면 된다.
반응형
'Spring' 카테고리의 다른 글
[Spring] API 문서화(apidoc, swagger) 라이브러리 비교 - springfox vs springdoc-openapi (0) | 2022.09.08 |
---|---|
[Spring] JMeter 사용법 - JMeter란?, 테스트 방법 (1) | 2022.09.07 |
[Spring Boot] 카오스 엔지니어링 - Chaos Monkey For Spring Boot (CM4SB) 소개 (0) | 2021.04.14 |
[Spring] IntelliJ에서 Spring + JSP hot reload 설정하기 (재시동 x) (0) | 2021.02.17 |
[Spring] IntelliJ에서 Spring + 톰캣 연동하기 (0) | 2021.02.17 |
댓글