지난 시간에 작성했던 글에서 request된 데이터는 어디로 갔을까?
그럼 spring boot는 전달받은 Json 형태의 데이터를 어떻게 처리할까?
썸네일의 사진과 같이 클라이언트에서 들어온 데이터는 Controller를 통하여 분류되고 Service로 이동한 후 Repository로 가서 Query문을 실행 한 후 DB에 있는 데이터를 가지고 역순으로 돌아가 반환된다.
@POST("/members/findMyAccountByNickname")
fun getMyAccountByNickname(@Body reqdata: SendNicknameRequestData): Call<resdata>
@Post안에 있는 주소를 확인해보면
members에 findMyAccountByNickname으로 데이터를 보낸다는것을 알 수 있다.
스프링에는 MemberController를 통해 데이터는 제어하는데
@RequiredArgsConstructor
@RestController
@RequestMapping(value = "/members")
public class MemberController {
@Autowired
MemberServiceImpl service;
private final ResponseService responseService;
@PostMapping("/findMyAccountByNickname")
public ResponseEntity<findMyAccountByNicknameResponseDto> findByNameAndNickname(@RequestBody findMyAccountByNicknameDto dto) {
findMyAccountByNicknameResponseDto responsedto = new findMyAccountByNicknameResponseDto();
responsedto.setEmail(service.findEmailByNickname(dto));
return ResponseEntity.ok().body(responsedto);
}
}
class 위에 @RequestMapping 어노테이션을 보면 기본적으로 members를 가리키고 있다.
ResponseEntity를 반환하는 함수 findByNameAndNickname의 맵핑 주소는 findMyAccountByNickname을 가리키고 있다.
안드로이드에서 넘어온 데이터는
@RequestBody에 의해
자동으로 findMyAccountByNicknameDto dto에 parsing되어 mapping된다.
@Data @Setter @Getter
public class findMyAccountByNicknameDto {
private String realName;
private String nickName;
}
findMyAccountByNicknameDto는 data클래스이다.
response할 data class findMyAccountByNicknameResponseDto인스턴스를 생성하고
mapping된 dto를 service에 인자로 넘긴다.
service의 구조는 아래와 같다.
public interface MemberService {
public String findEmailByNickname(findMyAccountByNicknameDto dto);
}
interface MeberService를 구현한 구현체의 구조는 아래와 같다.
@Service
@RequiredArgsConstructor
public class MemberServiceImpl implements MemberService {
private final MemberRepository memberRepository;
@Override
public String findEmailByNickname(findMyAccountByNicknameDto dto) {
return memberRepository.findByRealNameAndNickName(dto.getRealName(), dto.getNickName()).getEmail();
}
}
service로 넘어간 dto는 MemberRepository에 정의된 findByRealNameAndNickName메서드 안에 인자에 맞게 dto의 속성들이 인자로 넘어가게된다.
MemberRepository의 구조는
public interface MemberRepository extends JpaRepository<Member, Long> {
Member findByRealNameAndNickName(String realName, String nickName);
}
이렇게 되어있다.
JpaRepository를 상속받고 있는데
위 사진과 같이 Repository가 최상위 클래스임을 알 수있다.
JpaRepository를 상속받음으로써 PagingAndSoryRepository, CrudRepository, Repository의 모든 기능을 다 이용할 수 있는것이다.
SpringBootJPADocs에 가면 더 자세한 정보를 얻을 수 있다.
상속 하나 받는 것만으로도 적게는 수십줄 많게는 수백줄이 넘는 코드들을 적지 않아도 쿼리문을 호출 할 수 있게된다.
특히, JPA의 구현체 Hibernate는 메소드명으로 쿼리를 호출 할 수 있는 기능까지 갖춰져 있어 더욱 편리하다.
Member findByRealNameAndNickName(String realName, String nickName);
단순 메소드 호출만으로
"select m from Member m where m.realname=:realName and m.nickname=:nickName"
과 같은 Query문을 호출 할 수 있다.
이렇게 호출된 쿼리문은 DB에서 가져온 후 역순으로 다시 돌아가서 반환된다.
실제로 잘 작동되는지 확인해보겠다.
실명과 닉네임을 입력하고 확인버튼을 누른다.
실제 DB에 저장되어있는 내역이다.
hjkwon0814@daum.net이 출력되야 한다.
성공!!