작성
·
1.7K
1
안녕하세요. 기선님 강의 너무 재밌게 잘 보고 있습니다.
질문드릴것이 있는데요 그전에 상황을 설명하면 이렇습니다.
(이해하기 쉬우시게 한글로 적겠습니다)
'병원' , '환자' 라고 하는 두 엔티티가 있습니다.
환자는 병원을 참조하고 있습니다(FK)
@Entity
@Getter @Setter
@Builder @EqualsAndHashCode(of = "id")
@AllArgsConstructor @NoArgsConstructor
public class 병원 {
@Id @GeneratedValue
private Long id;
private String name;
. . . .
// 환자 수
@Transient
private Integer 환자수;
}
@Entity
@Getter @Setter
@EqualsAndHashCode(of = "id")
@AllArgsConstructor
@NoArgsConstructor
public class 환자 {
// 환자 아이디
@Id @GeneratedValue
@Column(name = "PAT_ID")
private Long id;
// 병원
@ManyToOne
@JoinColumn(name = "HOSP_ID")
private 병원 병원;
. . . .
}
위와 같이 두 엔티티가 존재하는데
병원 리스트를 검색하면서 각 병원에서 수용중인 환자 수를 같이 하고 불러오고 싶습니다.
이를테면 환자수가 1명이상인 병원목록을 불러온다했을때
이걸 SQL로 작성하면
SELECT h.*,
( SELECT COUNT(*) FROM patient WHERE hosp_id = h.hosp_id ) as '환자수'
FROM hospital h
WHERE ( SELECT COUNT(*) FROM patient WHERE hosp_id = h.hosp_id ) > 1;
(사실 이게 효율적인 SQL인지도 모르겠습니다만, 전 이렇게 보통 씁니다..)
처럼 작성할 수 있을건데요
이럴때 세가지 질문이 있습니다.
1. 병원 엔티티 클래스에 '환자수' 라는게 있는게 일단 맞는지 부터가 문제입니다. 병원 리스트를 조회할때 환자수가 몇명인지 정보도 같이 필요한 페이지도 있고 필요가 없는 페이지도 있습니다.
단, 환자수 정보가 필요할때는 '몇명 이상의 환자가 있는 병원 목록'과 같이 (위 SQL과 같이) where 절에 조건도 같이 붙게 됩니다.
환자수는 DTO로 따로 빼는게 맞을까요?
2. (1번질문에서 따로 빼는게 좋겠다고 하였을때)
환자수를 포함하는 병원DTO를 만든다고 했을때 사실 그 DTO는 병원의 모든 필드가 필요 합니다.
그래서 하려면 아래처럼 병원을 상속받는 식이 되어야 할텐데 이렇게 DTO 클래스가 엔티티 클래스를 상속받아도 문제가 없고, 이렇게 사용하는게 일반적으로 현업에서도 많이 있는 일인가요?
public class 병원출력DTO extends 병원 {
private Integer 환자수;
}
3. 제가 하고자하는 것 ( 엔티티에 있는 모든 정보 + 서브쿼리를 통한 추가정보를 같이 불러오고 서브쿼리를 이용한 WHERE절 ) 이 굉장히 일반적으로 많이 쓰이는 것이라 분명 JPA 프로그래밍으로 충분히 쉽게 하는 방법이 이미 있을것 같은데 지식의 끊이 짧다보니
어떤 방법을 써야하는지 감을 못잡겠습니다.
SELECT h.*,
( SELECT COUNT(*) FROM patient WHERE hosp_id = h.hosp_id ) as '환자수'
FROM hospital h
WHERE ( SELECT COUNT(*) FROM patient WHERE hosp_id = h.hosp_id ) > 1;
이런 것을 하기위해 제가 뭘 찾아보고 공부하면 되는지 키워드나 팁를 알려주실수 있을까요 (QueryDsl을 활용하면 될것 같긴한데.. )
답변 1
1
안녕하세요. 좋은 질문 감사합니다.
"환자수"를 "병원"이라는 엔티티에서 관리할 것인가 DTO에 둘 것인가는 정답이 있는 문제가 아닌것 같습니다. "환자수"를 실제로 비즈니스 로직에서 중요하게 사용한다면 엔티티에 두는 것이 맞을 것이고, 단순히 참조하는 값이라면 DTO에 두어도 좋을것 같습니다.
그리고 DTO가 엔티티에 있는 모든 필드를 전부 가지고 있으며 거기에 추가 필드를 가져야 한다면 상속이 맞는 답이겠지만 정말 그런 경우인가요? 그런 경우라면 굳이 DTO를 만들기 보다 엔티티에 해당 필드를 추가하는게 낫지 않나요? DTO가 왜 필요한 것이죠?
JPA를 사용해서 쿼리를 작성하는 방법은 크게 Criteria API와 JPQL이 있는데, QueryDSL은 JPQL을 타입 세이프하게 작성하는 방법을 제공해주는 유틸리티입니다. JPQL을 공부하시기 바랍니다.
감사합니다.