RestTemplate, Naver Open API, Entity 연관 관계

김재현·2023년 11월 14일
0

TIL

목록 보기
30/88
post-thumbnail

밥먹고 공부만 할 수 있다니 좋네~

RestTemplate

RestTemplate이란, 간편하게 Rest방식의 API를 호출할 수 있는 Spring 내장 클래스이다.


RestTemplate의 Get 요청

• Client 입장 서버

  1. RestTemplate을 주입 받습니다.(RestTemplateBuilder의 build()를 사용하여 RestTemplate을 생성하여 주입받음)

  2. 요청 받은 검색어를 Query String 방식으로 Server 입장의 서버로 RestTemplate를 사용하여 요청.

• Spring의 UriComponentsBuilder를 사용해서 URI를 손쉽게 만들 수 있습니다.
• RestTemplate의 getForEntity는 Get 방식으로 해당 URI의 서버에 요청을 진행합니다.

  • 첫 번째 파라미터에는 URI, 두 번째 파라미터에는 전달 받은 데이터와 매핑하여 인스턴스화할 클래스의 타입을 주면됩니다.

• 요청의 결과값에 대해서 직접 JSON TO Object를 구현할 필요없이 RestTemplate을 사용하면 자동으로 처리 해줍니다.

  • 따라서 response.getBody() 를 사용하여 두 번째 파라미터로 전달한 클래스 타입으로 자동 변환된 객체를 가져올 수 있습니다.

• Server 입장 서버

  • Server 입장의 서버에서 itemList를 조회하여 요청받은 검색어에 맞는 Item을 반환합니다.

요청한 Item이 여러 개라면??

• Client 입장 서버

• 결과 값이 다중 JSON으로 넘어오기 때문에 JSON To Object를 사용하지 않고 일단 String 값 그대로를 가져옵니다.

  • Server 입장 서버의 ItemResponseDto는 아래의 JSON 형태로 변환되어 전달됩니다.

• JSON 처리를 도와주는 라이브러리를 추가하여 받아온 JSON 형태의 String을 처리


RestTemplate의 Post 요청

• Client 입장 서버

  • 요청 받은 검색어를 Query String 방식으로 Server 입장의 서버로 RestTemplate를 사용하여 요청합니다.

Java 객체를 두 번째 파라미터에 넣으면 자동으로 JSON 형태로 변환

• Server 입장 서버

  • Server 입장의 서버에서 itemList를 조회하여 요청받은 검색어에 맞는 Item을 반환합니다.

전달 받은 HTTP Body의 User 데이터를 확인


RestTemplate의 exchange

(요청 Header에 정보를 추가하고 싶다면)

• Client 입장 서버

-RestTemplate의 exchange를 사용합니다.

exchange 메서드의 첫 번째 파라미터에 RequestEntity 객체를 만들어 전달해주면 uri, header, body의 정보를 한번에 전달.

• Server 입장 서버

  • 전달된 header와 body의 정보를 확인할 수 있습니다.

Naver Open API

네이버 서비스를 코드로 이용할 수 있는 서비스입니다.

동작 순서 이해하기

(그 중 "상품 검색 API"로 본다)

상품 검색 API 구현

  • 검색한 상품을 반환하는 API 생성 -> 네이버 패키지를 만들어서 dto, entity, controller 만듦

service에서 URL 요청 만드는법


Entity 연관 관계

DB table간의 연관 관계

고객 1명은 음식 N개를 주문할 수 있습니다.

  • 고객 : 음식 = 1 : N 관계

음식 1개는 고객 N명에게 주문될 수 있습니다.

  • 음식 : 고객 = 1 : N 관계

결론적으로 고객과 음식은 N : M 관계입니다.

  • 고객 : 음식 = N : M 관계

이렇듯 N : M 관계인 테이블들의 연관 관계를 해결하기 위해 orders 테이블처럼 중간 테이블을 사용할 수 있습니다.

  • 고객 1명은 주문을 여러번 할 수 있습니다.
    고객 : 주문 = 1 : N
  • 음식 1개는 주문이 여러번 될 수 있습니다.
    음식 : 주문 = 1 : N

DB table간의 방향

방향에는 크게 단방향과 양방향을 생각해 볼 수 있습니다.

  • 예를 들어 단방향은 users 테이블에서만 food 테이블을 참조할 수 있을 때를 의미합니다.
  • 양방향은 users 테이블과 food 테이블이 서로를 참조할 수 있을 때를 의미합니다.
  • 그렇다면 DB 테이블간의 방향이 있는 게 맞을까요?

DB에서는 어떤 테이블을 기준으로 하든 원하는 정보를 JOIN을 사용하여 조회할 수 있습니다.
이처럼 DB 테이블간의 관계에서는 방향의 개념이 없습니다.

음식 : 고객 = N : 1 관계를 표현

user라는 상대방 E의 필드를 가짐.
음식이 많은 쪽이니까 @ManyToOne
Food라는 상대방 E의 필드를 가짐
고객이 1인 쪽이니까 @OneToMany

여기서 한명의 고객은 여러번 주문이 가능한 상황이다.

  • 이를 Entity에서 여러번 가능함을 표현하기 위해 Java 컬렉션을 사용하여
List<Food> foodList = new ArrayList<>()

이처럼 표현할 수 있습니다.

그렇다면 Entity에서 이렇게까지 해서 표현을 하는 이유가 무엇일까요?

  • DB 테이블에서는 고객 테이블 기준으로 음식의 정보를 조회하려고 할 때 JOIN을 사용하여 바로 조회가 가능하지만 고객 Entity 입장에서는 음식 Entity의 정보를 가지고 있지 않으면 음식의 정보를 조회할 방법이 없습니다.
  • 따라서 DB 테이블에 실제 컬럼으로 존재하지는 않지만 Entity 상태에서 다른 Entity를 참조하기 위해 이러한 방법을 사용합니다.
    현재 음식 Entity와 고객 Entity는 서로를 참조하고 있습니다.

    이러한 관계를 다대일 양방향 관계라 부릅니다.

단방향 관계

음식쪽에서만 고객을 조회 할 수 있음. 고객은 음식의 정보가 없음.

<정리>

  • DB 테이블에서는 테이블 사이의 연관관계를 FK(외래 키)로 맺을 수 있고 방향 상관없이 조회가 가능합니다.
  • Entity에서는 상대 Entity를 참조하여 Entity 사이의 연관관계를 맺을 수 있습니다.
  • 하지만 상대 Entity를 참조하지 않고 있다면 상대 Entity를 조회할 수 있는 방법이 없습니다.

    따라서 Entity에서는 DB 테이블에는 없는 방향의 개념이 존재합니다.


1대1관계

@OneToOne애너테이션은 1 대 1 관계를 맺어주는 역할을 합니다.
(고객 Entity와 음식 Entity가 1 대 1 관계라 가정)

1대1 단방향 관계

외래 키의 주인 정하기

  • Entity에서 외래 키의 주인은 일반적으로 N(다)의 관계인 Entity 이지만 1 대 1 관계에서는 외래 키의 주인을 직접 지정해야합니다.
    -외래 키 주인만이 외래 키 를 등록, 수정, 삭제할 수 있으며, 주인이 아닌 쪽은 오직 외래 키를 읽기만 가능합니다.
  • @JoinColumn()은 외래 키의 주인이 활용하는 애너테이션입니다.
    -컬럼명, null 여부, unique 여부 등을 지정할 수 있습니다.

음식 Entity가 외래 키의 주인인 경우!

고객 Entity가 외래 키의 주인인 경우!

양방향 관계

JPA의 외래키 주인 지정 옵션이 있다 -> 외래키의 주인이 아닌 쪽에서 mappedBy 옵션을 지정을 해줘야함. (mappedBy = "상대 엔터티의 FK 필드명") -> 상대 엔터티의 @JoinColumn 으로 연결됨

<주의점>

  • 이 때 @JoinColumn 생략은 가능함 -> 하지만 만약 모호해지면 중간 테이블을 생성해서 거기에 저장해버리기 때문에 어노테이션 넣어주는게 좋음.)
  • mappedBy 옵션 생략하면 JPA가 FK를 인식하지 못함.

음식 엔터티가 외래키의 주인인 경우

고객 Entity가 외래 키의 주인인 경우!


N대 1관계

@ManyToOne

  • @ManyToOne 애너테이션은 N 대 1 관계를 맺어주는 역할을 합니다.
  • 음식 Entity와 고객 Entity가 N 대 1 관계라 가정하여 관계를 맺어보겠습니다.

단방향 관계

양방향관계

양방향 참조를 위해 고객 Entity에서 Java 컬렌션을 사용하여 음식 Entity 참조


1대 N관계

@OneToMany

  • @OneToMany 애너테이션은 1 대 N 관계를 맺어주는 역할을 합니다.
  • 음식 Entity와 고객 Entity가 1 대 N 관계라 가정하여 관계를 맺어보겠습니다.

단방향관계

(주의) 고객 엔터티에는 food_id가 없음. 실제 DB 테이블의 컬럼에 이렇게 나온다고 그림으로 보여줬을 뿐.

• 외래 키를 관리하는 주인은 음식 Entity이지만 실제 외래 키는 고객 Entity가 가지고 있습니다.

1 : N에서 N 관계의 테이블이 외래 키를 가질 수 있기 때문에 외래 키는 N 관계인 users 테이블에 외래 키 컬럼을 만들어 추가하지만 외래 키의 주인인 음식 Entity를 통해 관리합니다.
@JoinColumn --> 외래키의 주인이 씀 --> DB 테이블에서 Users 테이블에 추가돼서 food의 PK 참조해야하기 때문에 "food_id" 를 넣어줌

• 외래 키를 음식 Entity가 직접 가질 수 있다면 INSERT 발생 시 한번에 처리할 수 있지만 실제 DB에서 외래 키를 고객 테이블이 가지고 있기 때문에 추가적인 UPDATE가 발생된다는 단점이 존재
--> 단점이 꽤 많다. 하지만 상황에 따라 이렇게 할 수 밖에 없을 수도 있으니 알아둬야 한다.

양방향 관계

  • 1 대 N 관계에서는 일반적으로 양방향 관계가 존재하지 않습니다.
  • 1 대 N 관계에서 양방향 관계를 맺으려면 음식 Entity를 외래 키의 주인으로 정해주기 위해 고객 Entity에서 mappedBy 옵션을 사용해야 하지만 @ManyToOne 애너테이션은 mappedBy 속성을 제공하지 않습니다

일반적으로 추천하진 않음.

profile
I live in Seoul, Korea, Handsome

0개의 댓글