본문 바로가기

개발

[스프링부트] Querydsl 쿼리문 작성 (닉네임 공백, 대소문자)

닉네임을 검색해서 정보를 받아올 때, 처음에 해당 닉네임이 DB에 있는지 찾아보고 없으면 라이엇API를 통해 가져오는 코드를 작성 중이다.

 

처음에는 JPA로 findByNIckname을 사용했는데, 하다보니 검색을 할 때 공백을 잘못 작성하면 DB에서 찾지 못하는 현상이 발생했다.

그래서 쿼리문을 작성했다.

 

[변경 전 코드]

@Repository
@Transactional
public class RiotUpgradeRepository {

    private final EntityManager em;
    public RiotUpgradeRepository(EntityManager em) {
        this.em = em;
    }

    public Optional<Summoner> findByNickname(String nickname){
        Summoner summoner = em.createQuery("SELECT s FROM Summoner s WHERE replace(s.nickname, ' ', '')=:nickname", Summoner.class)
                .setParameter("nickname",nickname)
                .getSingleResult();

        Optional<Summoner> optional = Optional.ofNullable(summoner);
        return optional;
    }
}

공백을 replace함수로 제거한 후, service단에서 공백을 제거한 닉네임과 비교하는 쿼리문이다.

 

 

[에러]

jakarta.persistence.NoResultException: No result found for query [SELECT s FROM Summoner s WHERE replace(s.nickname, ' ', '')=:nickname]

.getSingleResult()가 무조건 하나의 결과값이 있어야하는 듯한다.

 

 

[변경 후 코드]

public Optional<Summoner> findByNickname(String nickname){
        Optional<Summoner> summoner = em.createQuery("SELECT s FROM Summoner s WHERE replace(s.nickname, ' ', '')=:nickname", Summoner.class)
                .setParameter("nickname", nickname)
                .getResultList().stream().findAny();

        return summoner;
    }

 

추가적으로 대소문자 구분을 안되게하려고 했는데, 기본적으로 그런 기능이 있는 듯하다.

만약 나중에 대소문자 구분이 필요하다면 그런 코드를 작성해주면 될 것 같다.