인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

인프런 커뮤니티 질문&답변

임현석님의 프로필 이미지
임현석

작성한 질문수

스프링 DB 2편 - 데이터 접근 활용 기술

JPA 적용1 - 개발

JpaItemRepositoryV1의 findAll() 로직 질문 있습니다

해결된 질문

작성

·

394

1

안녕하세요.
JpaItemRepositoryV1의 findAll() 메소드의 로직 중에
...
if (StringUtils.hasText(itemName) || maxPrice != null) {
        jpql += " where";
}
    boolean andFlag = false;
    List<Object> param = new ArrayList<>();
    if (StringUtils.hasText(itemName)) {
        jpql += " i.itemName like concat('%',:itemName,'%')";
        param.add(itemName);
        andFlag = true;
}
...
이 param이 없어도 테스트 코드가 정상 동작하고, 안쓰는것 같은 느낌이 들어서요,
안쓰는것 맞을까요?

답변 1

1

안녕하세요. 임현석님, 공식 서포터즈 OMG입니다.

강의 19분 48초 보시면 상품명 검색하는 부분에서 해당 코드가 동작합니다 :)


감사합니다.

임현석님의 프로필 이미지
임현석
질문자

정확히 List<Object> param = new ArrayList<>(); 과 param.add(itemName) 이 부분이 JpaRepository 에서는 query.setParameter()로 파라미터값을 넘겨주고 있으니까 필요가 없는것 같아서요, 그건 아닐까요?

if (StringUtils.hasText(itemName)) {
jpql += " i.itemName like concat('%',:itemName,'%')";
param.add(itemName);
andFlag = true;
}
TypedQuery<Item> query = em.createQuery(jpql, Item.class);
if (StringUtils.hasText(itemName)) {
query.setParameter("itemName", itemName);
}

 

이 두개의 코드를 보신 것 같은데요,

두 코드 itemName이 존재할 때, 즉 검색을 이용할 때 동작합니다.

if (StringUtils.hasText(itemName)) 

이 조건을 만족하지 않으면

query.setParameter("itemName", itemName);

를 수행하지 않습니다.

 

TypedQuery<Item> query = em.createQuery(jpql, Item.class);

여기서 query는 jpql 변수로 만드는데, 추가적으로 

if (StringUtils.hasText(itemName)) 

이 조건을 만족해야 if문안의 query.setParameter가 수행됩니다.

임현석님의 프로필 이미지
임현석
질문자

    @Override
    public List<Item> findAll(ItemSearchCond cond) {
        String jpql = "select i from Item i";
        Integer maxPrice = cond.getMaxPrice();
        String itemName = cond.getItemName();
        if (StringUtils.hasText(itemName) || maxPrice != null) {
            jpql += " where";
        }
        boolean andFlag = false;
        List<Object> param = new ArrayList<>(); // 여기
        if (StringUtils.hasText(itemName)) {
            jpql += " i.itemName like concat('%',:itemName,'%')";
            param.add(itemName); // 여기
            andFlag = true;
        }
        if (maxPrice != null) {
            if (andFlag) {
                jpql += " and";
            }
            jpql += " i.price <= :maxPrice";
            param.add(maxPrice); // 여기
        }
        log.info("jpql={}", jpql);
        TypedQuery<Item> query = em.createQuery(jpql, Item.class);
        if (StringUtils.hasText(itemName)) {
            query.setParameter("itemName", itemName);
        }
        if (maxPrice != null) {
            query.setParameter("maxPrice", maxPrice);
        }
        return query.getResultList();
    }

음.. 그러면 저는 // 여기 라고 표시해놓은곳이 지워져도 된다고 생각하고, 잘못 들어간 부분이라고 생각하는데, 그건 아닌건가요??

주석으로 위치를 표기해주셔서 이해하였습니다.

param.add를 말씀해주셨는데, jpql 부분에만 신경을 썼네요..

 

네, 해당 코드는 지우셔도 상관없는 코드입니다.

JdbcTemplateItemRepositoryV1 코드를 복사해오는 과정에서 추가된 코드로 보이네요 ^^

JdbcTemplateItemRepositoryV1 여기서는 template에서 쿼리로 param을 넘기기 때문에 필요합니다.

 

  List<Object> param = new ArrayList<>();
        if (StringUtils.hasText(itemName)) {
            sql += " item_name like concat('%',?,'%')";
            param.add(itemName);
            andFlag = true;
        }

        if (maxPrice != null) {
            if (andFlag) {
                sql += " and";
            }
            sql += " price <= ?";
            param.add(maxPrice);
        }

        log.info("sql={}", sql);
        return template.query(sql, itemRowMapper(), param.toArray());

 

임현석님의 프로필 이미지
임현석
질문자

아 그렇군요 답변 감사합니다 ^^

임현석님의 프로필 이미지
임현석

작성한 질문수

질문하기