Spring Boot/JPA

Spring Boot existsBy

최-코드 2024. 7. 29. 20:26

상황 : 고유성을 보장하는 email 컬럼에 대해 existsBy를 쓸지 findBy를 쓸지 고민중인 상황이다.
 
쿼리문 비교 

  • existsBy : select ue1_0.user_id from user ue1_0 where ue1_0.email=? limit 1
  • findBy :select  ue1_0.user_id,ue1_0.email,ue1_0.password,ue1_0.nickname,ue1_0.role from user ue1_0 where ue1_0.email=?

결론 : findBy의 경우 @Query를 통해 컬럼을 하나로 제한하고 limit 1을 추가하면 existsBy와 똑같아진다. limit 1의 경우 고유성을 보장하는 컬럼에 대해 추가하든 말든 결국 하나의 행만을 반환하므로 실질적인 성능 차이가 없다. 따라서 쿼리 결과로 바로 boolean 값을 반환해주는 existsBy를 쓰는게 편하겠다.
 
수정 :

  • 쿼리문 비교에서 existsBy의 쿼리문은 sql에서 실행되는 것으로 @Query에 저렇게 적으면 에러가 발생한다. @Query안에는 limit 1을 사용할 수 없고, boolean 값을 뱉어야 하는데 id값이므로 타입 에러가 뜬다.
  • 또한 exists문도 사용할 수 없다. 따라서 count를 이용해야 하는데 한 건만 있으면 바로 리턴하는 exists와는 달리 count의 경우 모든 결과를 조회하고 리턴하므로 성능상 문제가 크다.
  • limit 1을 사용하려면 QueryDSL을 사용해야 한다. 만약 복잡한 조건식이 필요하고 existsBy를 사용해야 한다면 QueryDSL을 사용하자. 
public boolean exists(Long id) {
  Integer result = queryFactory
    .selectOne() // select 1로 치환됨.
    .from(table)
    .where(table.id.eq(id))
    .fetchFirst();
  return fetchOne != null;
}