본문 바로가기
JAVA

QueryDsl 동적쿼리 사용 (SpringBoot, JPA)

by fouink 2022. 11. 25.

 

  

Tag 테이블에는 team_id가 외래키로 존재한다.

즉, 하나의 Team은 다수의 Tag를 가질 수 있다.

 

 

 

 

 

 

-RequestBody (Rest API)

 

-RequestTags

@Data
public class RequestTags {
    private List<String> tags;
}

 

-TeamController

/**
 * 태그로 전체 게시판 검색
 */
@ApiOperation(value = "태그로 전체 게시판 조회 URL")
@PostMapping("/api/tags")
public ResponseTagsInTeam tagsInTeam(
        @RequestBody RequestTags requestTags,
        @PageableDefault(size = 10, sort = "createdDate", direction = Sort.Direction.DESC) Pageable pageable) {
    ResponseTagsInTeam tagsInTeam = teamService.getTagsInTeam(requestTags, pageable);

    return tagsInTeam;
}

 

서비스 로직을 건너뛰고 Tag, TeamRepository의 QueryDSL을 활용해서 구현만 생각해보자면 List로 태그가 몇개 들어올지 모른다 

들어올 수도 있고 안 들어올 수도 있다 그걸 가정해서 쿼리문을 작성해보자.

 

 

-TagQueryDslRepositoryImpl

/**
 * 들어온 태그들을 한번에 검색
 */
@Override
public List<Tag> searchTagInTeam(List<String> tags) {
    if (tags.size() > 0) {
        return queryFactory
                .select(tag)
                .from(tag)
                .where(tagsNameEq(tags))
                .fetch();
    } else {
        return null;
    }
}

public BooleanBuilder tagsNameEq(List<String> tags) {
    BooleanBuilder builder = new BooleanBuilder();
    for (int i = 0; i < tags.size(); i++) {
        builder.or(tag.tagName.eq(tags.get(i)));
    }
    return builder;
}

 

들어온 태그들을 전부 BooleanBuilder에 or 연산자로 담아준다. 만약 tags List가 size가 0이라면 ? null이 들어가게 된다.

그런 경우에는 where문에서 알아서 없는 것으로 인식하고 where쿼리를 안날린다.

 

이렇게 데이터베이스에서 뽑은 데이터로 엔티티의 Tag.getTeamId 들을 얻을 수 있다.

 

 

-TeamQueryDslRepositoryImpl

/**
 * 들어온 팀아이디들을 한번에 검색
 */
@Override
public Page<Team> searchTeams(List<Long> teamIds, Pageable pageable) {

    if (teamIds.size() > 0) {
        QueryResults<Team> results = queryFactory
                .select(team)
                .from(team)
                .orderBy(team.id.desc())
                .offset(pageable.getOffset())
                .limit(pageable.getPageSize())
                .where(teamIdEq(teamIds))
                .fetchResults();

        long total = results.getTotal();                    //총 페이지 수

        List<Team> content = results.getResults();          //실제 내용

        return new PageImpl<>(content, pageable, total);
    } else {
        return null;
    }
}

public BooleanBuilder teamIdEq(List<Long> tags) {
    BooleanBuilder builder = new BooleanBuilder();
    for (int i = 0; i < tags.size(); i++) {
        builder.or(team.id.eq(tags.get(i)));
    }
    return builder;
}

 

마지막으로 얻을 팀들의 데이터도 동일하게 teamId값이 동적으로 바뀔 것을 고려해서 동일하게 작성해준다.

 

-쿼리 결과

댓글