인프런 커뮤니티 질문&답변

양치잘하기님의 프로필 이미지

작성한 질문수

스프링 DB 2편 - 데이터 접근 활용 기술

ORM 개념1 - SQL 중심적인 개발의 문제점

DB강의 듣다 강이ppt의 외래키 부분을 보고 궁금증이 생겨 질문 남깁니다.

해결된 질문

작성

·

200

0

 

웹 개발을 할 때 DDL을 통해 생성되는 테이블들은 모두 서비스에서 사용되는 객체들을 보고 만드는것 같은데 (예를 들면 Member 클래스, Item클레스들을 생각했습니다)

만약 어떤 회원 A가 아이템A를 등록하였으면 데이터 베이스의 회원과 아이템 사이에는 등록이라는 관계가 생성이 되고

회원 1명은 아이템을 여러개 등록이 가능하다면 Member 테이블의 PK를 Item 테이블의 FK로 등록되며 Item 테이블의 속성들은 (id, item_name, price, quantity, member_id)로 설정이 될것 같은데 이런 경우 Item 클레스의 멤버변수로

Member member_id; 를 생성해주어야 할것 같은데 이런 외래키 값은 도메인을 설계할때 어떻게 처리해야 하나요?

그리고 api로 통신할 때 클라이언트 에게 데이터를 넘겨줄 때 스프링 입문 강의에서 hello 객체자체를 return 하면 스프링의 잭슨라이브러리가 json포멧으로 변환해서 넘겨준다고 해주셨는데 여러개의 테이블이 조인된 결과를 json으로 반환 해주려면

(예를 들어서 멤버 A가 등록한 아이템의 이름과 가격, 멤버의 이름을 요청한다면 반환되는 튜플이 item_name, price, member_name) 이것들은 하나의 객체가 아닌 Member클래스와 Item클래스의 일부 변수들을 사용한 새로운 값들인데 이럴때는 어떤 방법으로 return해주어야 하나요?

클라이언트측과 조율을 하여 검색되는 조건을 설정하여 조인검색의 제약을 설정하나요? 제약을 설정한다면 반환할 때

(item_name, price, member_name)

이 3개의 속성들을 멤버변수로 사용하는 새로운 클래스를 생성하여 반환해 주어야 하나요?

 

답변 2

1

안녕하세요. 양치잘하기님, 공식 서포터즈 y2gcoder입니다.

  1. 만약 1:N 관계가 필요하고 위의 Member : Item 으로 관계를 만들어준다면, Item에 외래키에 대한 memberId 필드를 만들어주면 될 것 같습니다. 이렇게 하면 간접적으로 Item 객체와 Member 객체가 함께 필요할 때는 그 결과값을 받을 수 있는 DTO를 따로 만드셔야 합니다.

  2. JPA가 정말 편리하게 @ManyToOne, @OneToMany 등으로 조회할 수 있게 해줘서 그렇지, JdbcTemplate이나 Mybatis로 구현한다면 위와 같이 외래키 필드만 추가하거나, 아니면 JPA 와 같이 Item 안에 Member member 필드를 만들고 Item을 조회하는 쿼리에 조인을 걸어 항상 같이 조회하는 방법이 있을 것 같습니다. JPA의 즉시로딩과 같은 느낌이라고 생각하시면 될 것 같습니다. (항상 같이 조인하는 이유는 그렇지 않을 경우 member field가 조건에 따라 null이 될 수도 있기 때문입니다.) (여담으로 Member 와 Item의 관계는 N:M이 될 수도 있습니다!)

  3. 사실 JPA를 배우기 전에는 저도 위와 같이 조회 결과에 따라 DTO를 만들어 개발했습니다. 현업에 따라서는 해당 객체 타입을 VO 타입이라고 부르기도 하면서 많이 만들기 귀찮을 때는 하나의 VO에 몰아 넣어 필드가 50개가 넘어가는 VO가 생기기도 했습니다 4. 튜플로 받지 말고 DTO로 받으시면 됩니다. 그리고 그 DTO를 JSON으로 반환해도 됩니다! 아니면 엔티티로 받아서 JSON으로 반환할 때는 DTO로 파싱 해서 반환하셔도 됩니다.

 

감사합니다.

JPA를 사용하지 않을시 Item 클래스에 외래키로 사용될 Member의 기본키를 필드로 등록하여 관리한다 그리고 조인의 결과를 반환할 때는 반환될 결과를 객체로 관리할 DTO를 만들면 된다로 이해하였습니다.

DTO로 받아야한다 이 말씀은 Member에서 클라이언트에 반환할 값 받아오고 Item에서 클라이언트에 반환할 값 받아온 후 DTO에 주입해주고 그 객체를 반환하면 잭슨 라이브러리가 json으로변환 해주는거로 이해하였습니다.

그리고 DTO는 등록되는 객체가 아닌 반환시에 사용되는 객체이기 때문에 DB에 테이블로 등록할 필요가 없는것으로 이해하였습니다.

잘 이해한것이 맞을까요?

JPA를 사용하지 않을시 Item 클래스에 외래키로 사용될 Member의 기본키를 필드로 등록하여 관리한다 그리고 조인의 결과를 반환할 때는 반환될 결과를 객체로 관리할 DTO를 만들면 된다로 이해하였습니다.

=> 외래키를 말씀하시는 거라면 맞습니다. 뒤의 말씀도 맞습니다.

DTO로 받아야한다 이 말씀은 Member에서 클라이언트에 반환할 값 받아오고 Item에서 클라이언트에 반환할 값 받아온 후 DTO에 주입해주고 그 객체를 반환하면 잭슨 라이브러리가 json으로변환 해주는거로 이해하였습니다.

=> 맞습니다!

그리고 DTO는 등록되는 객체가 아닌 반환시에 사용되는 객체이기 때문에 DB에 테이블로 등록할 필요가 없는것으로 이해하였습니다.

=> 본질적으로 DTO는 자바 객체입니다. DB 테이블과는 관계가 없습니다. ORM은 결국 DB 테이블의 데이터를 객체 지향적으로 관리해주기 위한 하나의 도구에 불과합니다

그리고 DTO는 등록되는 객체가 아닌 반환시에 사용되는 객체이기 때문에 DB에 테이블로 등록할 필요가 없는것으로 이해하였습니다

=> 조회에 대한 DTO를 말씀하시는 거라면 맞습니다.

 

0

안녕하세요, 인프런 AI 인턴입니다.

양치잘하기님의 질문에 대해, 스프링 데이터 접근과 관련하여 외래키 설정과 다수의 테이블로부터 데이터를 조회하여 JSON으로 반환하는 방법에 대해 유사한 내용을 다룬 정보를 찾았습니다.

  1. 엔티티 클래스 설계 시 외래키 처리: JPA와 스프링 데이터 JPA를 사용할 때, 특별히 연관된 여러 엔티티 간의 관계는 @ManyToOne과 같은 JPA의 연관관계 매핑 어노테이션을 사용하여 표현할 수 있습니다. 이는 단방향 또는 양방향 관계로 설정 가능하며, Member 엔티티의 PK를 Item 엔티티의 FK로 지정하여 Item 클래스 내에 Member member 필드를 추가하는 방식으로 설정할 수 있습니다. 관련된 내용은 “pk가 다른 테이블의 fk 2개이상으로 들어갈 경우는 어떻게 해야할까요?”에서 찾아볼 수 있습니다. 간단하게 이 솔루션은 JPA의 @ManyToOne@OneToMany 어노테이션을 활용하여 엔티티 간의 관계를 정의하는 방법을 제시합니다.

  2. 여러 엔티티로부터 조회한 데이터를 JSON으로 변환하여 반환하기: 요구사항에 대응하여 여러 테이블로부터 조회한 데이터를 단일 JSON 객체로 클라이언트에 반환하는 일반적인 방법 중 하나는, DTO(Data Transfer Object) 클래스를 생성하여 필요한 정보를 담아 반환하는 것입니다. 이 DTO는 클라이언트로부터 요청 받은 데이터를 가공하여 JSON 형태로 만들어 반환할 목적으로 사용됩니다. 예를 들어, item_name, price, member_name 등을 필드로 하는 ItemMemberInfoDTO 클래스를 생성하고, 이를 API 응답에서 반환할 객체로 사용할 수 있습니다. 관련된 내용은 “연관관계가 없는 테이블 조회 질문드립니다.”“객체들간의 연관관계 설정”에서 더 자세한 설명을 제공합니다. 이 글들은 객체 간의 연관관계 설정과 JPQL을 사용하여 연관관계가 없는 엔티티를 조회하는 방법을 설명하고 있습니다.

이러한 방법으로 엔티티 간의 관계를 설계하고, 필요한 정보를 조합하여 클라이언트에게 JSON 형태로 반환할 수 있습니다. 클라이언트측과의 조율을 통해 검색 조건을 명확히 설정하면, 의도하는 데이터 포맷을 생성하여 효율적이고 명확한 데이터 전달이 가능합니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

jpa를 사용한 방법이 아닌 jdbc템플릿과 마이바티스로는 해결을 못하는 건가요?