ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Querydls 동적 쿼리 활용
    JPA/Querydsl 2023. 8. 13. 17:29

    엔티티 및 Dto 설정을 해준 다음에 검색을 하는 동적 쿼리를 테스트가 아니라 실제로 활용해볼 것이다.

    @Data
    public class MemberTeamDto {
        private Long memberId;
        private String username;
        private int age;
        private Long teamId;
        private String teamName;
    
        @QueryProjection
        public MemberTeamDto(Long memberId, String username, int age, Long teamId, String teamName) {
            this.memberId = memberId;
            this.username = username;
            this.age = age;
            this.teamId = teamId;
            this.teamName = teamName;
        }
    }

    MemberTeamDto는 select 해서 가지고 올 Dto이다. @QueryProjection을 통해 Q파일을 만들어준다.

     

     

    @Data
    public class MemberCond {
        // 회원명, 팀명, 나이(ageGoe, ageLoe)
    
        private String username;
        private String teamName;
        private Integer ageGoe; // 크거나 같거나
        private Integer ageLoe; // 작거나 같거나
    }

    MemberCond는 where절에서 user의 조건을 맞추는 엔티티이다.

     

     

     

    MemberRepository에서의 Querydsl

    public List<MemberTeamDto> search(MemberCond condition) {
        return queryFactory
                .select(new QMemberTeamDto(
                        member.id,
                        member.username,
                        member.age,
                        team.id,
                        team.name))
                .from(member)
                .leftJoin(member.team, team)
                .where(
                        usernameEq(condition.getUsername()),
                        teamNameEq(condition.getTeamName()),
                        ageGoe(condition.getAgeGoe()),
                        ageLoe(condition.getAgeLoe()))
                .fetch();
    }
    
    private BooleanExpression usernameEq(String username) {
        return isEmpty(username) ? null : member.username.eq(username);
    }
    private BooleanExpression teamNameEq(String teamName) {
        return isEmpty(teamName) ? null : team.name.eq(teamName);
    }
    private BooleanExpression ageGoe(Integer ageGoe) {
        return ageGoe == null ? null : member.age.goe(ageGoe);
    }
    private BooleanExpression ageLoe(Integer ageLoe) {
        return ageLoe == null ? null : member.age.loe(ageLoe);
    }

    이전에 사용했던 where 절에서의 동적 쿼리를 응용해서 쿼리를 작성했다. null이면 조건에 null을 보내고 아니면 where절에 조건을 걸어주는 것이다.

     

     

     

     

    조회용 API 컨트롤러

    @Profile("local")
    @Component
    @RequiredArgsConstructor
    public class InitMember {
    
        private final InitMemberService initMemberService;
        
        @PostConstruct
        public void init() {
            initMemberService.init();
        }
        
        @Component
        static class InitMemberService {
        
            @PersistenceContext
            EntityManager em;
            
            @Transactional
            public void init() {
                Team teamA = new Team("teamA");
                Team teamB = new Team("teamB");
                em.persist(teamA);
                em.persist(teamB);
                for (int i = 0; i < 100; i++) {
                    Team selectedTeam = i % 2 == 0 ? teamA : teamB;
                    em.persist(new Member("member" + i, i, selectedTeam));
                }
            }
        }
    }

    다음과 같이 초기 데이터를 만들고 컨트롤러를 만들어준다.

     

     

    @GetMapping("v1/members")
    public List<MemberTeamDto> searchMemberV1(MemberCond condition) {
        return memberJpaRepository.search(condition);
    }

    파라미터에 조건을 설정해주면 해당하는 데이터들만 select해서 가져와 주는 것을 확인할 수 있다.

Designed by Tistory.