
프로젝트의 Service 테스트중 repository의 쿼리를 줄일 수 있는 방법이 생각났다.
동적쿼리가 사용된 Repository를 개선해보자
매개변수로 객체의 타입과 해당 객체의 ID가 전달된다.
WordType은 PERFUME, BRAND, NOTE를 name으로 갖는 enum이다
List<Word> findByTypeAndTypeId(Long typeId, WordType wordType)
public List<Word> findByTypeAndTypeId(Long typeId, WordType wordType){
String jpql = "SELECT w FROM Word w " +
"LEFT JOIN w.brand b " +
"LEFT JOIN w.note n " +
"LEFT JOIN w.perfume p " +
"WHERE w.wordType = :wordType " +
"AND (b.id = :id OR n.id = :id OR p.id = :id)";
return em.createQuery(jpql, Word.class)
.setParameter("wordType", wordType)
.setParameter("id", typeId)
.getResultList();
}
Join을 사용했고, 결과를 정상적으로 반환 받을 수 있었다.
하지만 Hibernate에 의해 binding 되는 값이 4개이고, where절의 and와 or를 줄일 수 있을 것 같았다.
WordType의 name을 적극 활용하기로 했다.
WordType은 PERFUME, BRAND, NOTE를 name으로 갖기에,
Word 테이블의 perfume, brand, note 열의 이름과 같다.(대문자,소문자 차이)
public List<Word> findByTypeAndTypeId(Long typeId, WordType wordType) {
String jpql = "select w from Word w where " + "w." +
wordType.name().toLowerCase() +
".id = :id";
return em.createQuery(jpql, Word.class)
.setParameter("id", typeId)
.getResultList();
}
Word 테이블에서 Type에 맞는 열만을 비교하므로, 쿼리를 줄일 수 있었다.

이 방법이 더 나은 로직인지는 확실치 않다.
다만, 확실히 쿼리가 줄었고 고민해서 코드를 고안해냈으니 다음엔 더 좋은 방법이 떠오르지 않을까.. 하는 기대를 가져보자!