스프링데이터 + JPA/QueryDSL

30. 조회 API 컨트롤러 만들기

sdafdq 2023. 12. 3. 11:57

컨트롤러 자체 만드는 건 쉽다

 

@RestController
@RequiredArgsConstructor
public class MemberController {
    private final MemberJpaRepository memberJpaRepository;

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

이렇게. 그냥 condition하면 저거는 이제 setter로 자동으로 알아서 클라이언트에서 들어오는 파라미터의 변수명만 잘 맞는다면 알아서 들어간다.

 

리포지토리로 먼저 정의해뒀던 search

public List<MemberTeamDto> search(MemberSearchCondition condition){
    return query.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();
}

를 이용해서 return

 

저대로 리턴하면 이제 

postman으로 확인해 보면

잘 나옴.

 

 

조건 줬을 때

잘 나옴.

 

근데 저거는 테스트하려고 미리 넣어놓은 값.

 

@Profile("local")
@Component
@RequiredArgsConstructor
public class InitMember {
    private final InitMemberService initMemberService;

    @PostConstruct
    public void init(){
        initMemberService.init();
    }


    @Component
    @RequiredArgsConstructor
    static class InitMemberService{
        private final 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));
            }
        }
    }
}

되나 보려고 그냥 처음에 DB에 값을 넣어놓고 시작.

 

@Profile() 저거는, 저 프로파일로 실행한다는 뜻. 뭐 일종의 관리자명? 같은 거일듯.

spring:
  profiles:
    active: local

application.yml에서 설정.

 

저렇게 @PostConstruct와 함께 @Transactional 안하는 이유는,

누굴 더 먼저 실행해야 할 지 충돌나서? 문제가 있을 수 있나 봄.

그러니까, 더 정확히는 저게 @PostConstruct나 @Transactional이나 프록시인데,

프록시는 뭔가 외부에서 호출하면 호출한 메소드를 실행하기 전에 가로채서 프록시 함수를 실행하는 데,

저렇게 둘 다 써 놓으면 뭐를 실행해야 할 지 몰라서 그런 듯.

https://www.inflearn.com/questions/1091312

물어봄

 

여튼 저렇게 하면,

홀짝으로 Member마다 팀이 다르게 넣어짐.