resultType
만 맞춰주면 별 문제없었던Mybatis
와 달리
JPA
는 왜...
int 변수에 따라 Qna
, Reply
, User
에서 각각 요소들을 조금씩 가져오고 싶다
컨트롤러와 서비스 파트는 Mybatis
, JPA
둘 다 똑같다고 생각하면 된다
@GetMapping
public ResponseEntity<Map<String, Object>> fundingQna(@RequestParam int fundingSeq){
logger.info("질문 목록 불러오기 " +fundingSeq);
String message = FAIL;
HttpStatus status;
Optional<List<FundingQnaInfo>> dto = qnaService.fundingQna(fundingSeq);
Map<String, Object> response = new HashMap<>();
if(dto.isPresent()){
message = SUCCESS;
response.put("data", dto);
status = HttpStatus.OK;
}
else{
status = HttpStatus.NOT_FOUND;
}
response.put("message", message);
return (new ResponseEntity<>(response, status));
}
@Override
public Optional<List<FundingQnaInfo>> fundingQna(int fundingSeq) {
return (qnaRepository.findByFundingSeq(fundingSeq));
}
@Query
에 SQL
과 JPQL
중 선택하여 사용할 수 있다
@Query
어노테이션에 두번째 파라미터로 nativeQuery = true
을 넣는다면 SQL
,
기본값인 nativeQuery=false
를 사용한다면 JPQL
해당 JPQL
을 사용하기 위해 반환값 DTO 객체는 반환받는 값들을 명시해주어야 한다
파라미터가 있을때, JPQL
에서 이름과 순서 총 두가지의 받는법이 존재한다
파라미터 이름으로 받기
where q.fundingSeq = :fundingSeq
파라미터 순서로 받기
where q.fundingSeq = :1
DTO interface 에서 정해진 요소들의 이름을 맞춰주기 위해 alias
를 설정해준다
SQL
와 비교해서 JPQL
은 그나마 IDE에서 자동완성을 지원한다
@Query(value = "select q.qnaText as qnaText, q.qnaCreatedDate as qnaCreatedDate, q.secret as secret, (select u.userNickname from User u) as userNickname," +
"(select r.replyCreatedDate from Reply r where r.qnaSeq=q.qnaSeq) as replyCreatedDate, (select r.replyText from Reply r where r.qnaSeq=q.qnaSeq) as replyText " +
"from Qna q where q.fundingSeq = :fundingSeq")
Optional<List<FundingQnaInfo>> findByFundingSeq(@Param("fundingSeq") Integer fundingSeq);
Entity
에서 받아야 하는 요소들을 getter를 사용한것 처럼 메서드를 구현해준다
public interface FundingQnaInfo {
String getUserNickname();
String getQnaText();
LocalDate getQnaCreatedDate();
String getReplyText();
LocalDate getReplyCreatedDate();
Boolean getSecret();
}