도입 API 명세서는 각 API가 어떻게 동작하는지 설명하는 문서로, 프론트엔드와 서버 간 협업에서 필수적이다. 나는 기존 프로젝트들에서 명세서 작성 도구로 Swagger를 사용했었다. 그러다 최근에 Spring Rest Docs로도 API 명세서를 작성할 수 있음을 알게 되었다. Spring Rest Docs는 스프링 프레임워크에서 제공하는 API 문서 자동화 도구이다. Swagger VS Rest Docs Swagger와 Rest Docs는 각각 장단점이 존재한다. Swagger는 적용이 쉽고, 해당 문서에서 API 호출 테스트를 직접 해볼 수 있다. 그러나 프로덕션 코드에 Swagger 문서 관련 코드가 포함되어 가독성이 떨어진다. Rest Docs는 Swagger에 비해 적용이 어렵지만 프로덕션 ..
# 2023/5/15에 작성했던 글입니다. # 해당 인스턴스는 삭제한 상태입니다. EC2 인스턴스를 생성해보자 우분투를 선택하였다. AMI는 프리티어 중에서 선택하였다. 인스턴스 유형은 따로 건들지 않았다. 키 페어는 인스턴스에 접속할 때 필요하다. 새로운 키페어를 생성하거나 기존 키페어를 사용할 수 있는데 나는 새로 만들었다. 키 페어 이름만 입력하고, 나머지 설정은 건들지 않았다. 키페어 생성을 누르면 내가 생성한 키페어가 다운로드된다. 키페어를 저장하고, 해당 경로를 기억하자. 명령 프롬프트에서 해당 경로로 이동해 EC2 서버에 접속하게 된다. 새 보안 그룹을 생성해주자. 스토리지는 50GB로 설정하였다. 용량이 부족하면 나중에 깃에서 프로젝트를 클론할 때 문제 생길 수 있다. (경험담) 보안 그룹..
@MappedSuperClass는 공통 매핑 정보가 필요할 때 사용한다. 테이블에 매핑되지 않고, 단순히 엔티티가 공통으로 사용하는 매핑 정보를 모으는 역할을 한다. 예를 들어 모든 엔티티에 생성 시간, 수정 시간이 들어간다고 해보자. 각 엔티티에 해당 필드를 추가한다면 코드 중복이 발생한다. 이때 부모 클래스를 선언하고 속성만 상속받아 사용할 수 있다. BaseEntity에 @MappedSuperClass를 선언 후 필드들을 넣고 다른 엔티티들이 상속받도록 하자. BaseEntity는 상속해주는 클래스라 단독으로 쓰지 않으므로 추상 클래스로 만드는 것이 좋다. 객체와 테이블의 필드명을 다르게 사용하고 싶다면 @Column의 name 속성을 사용하면 된다. @MappedSuperClass public a..
상속관계 매핑 정의 관계형 데이터베이스는 상속관계가 존재하지 않는다. 대신 DB의 슈퍼-서브타입 모델링 기법이 객체 상속 관계와 유사하기 때문에 매핑해서 쓸 수 있다. 한 마디로 상속 관계 매핑은 상속 관계와 슈퍼-서브 타입 관계를 매핑하는 것이다. 아래 그림처럼 음반, 영화, 책에서 공통적인 속성을 뽑아내어 물품을 만들 수 있다. 슈퍼-서브타입 논리 모델을 실제 물리 모델로 구현하는 방법은 총 3가지가 있다. 아래에서 하나씩 살펴보자. 조인 전략 조인으로 데이터를 정규화하여 구성하는 전략이다. 공통 속성인 name, price는 Item 테이블에 저장되고, 나머지 속성들은 각 테이블에 저장된다. 코드 각 엔티티를 생성해준다. Item엔티티는 상속해 주는 용도로만 쓰이므로 추상 클래스로 정의했다. @Di..
다대다 매핑 관계형 데이터베이스는 정규화된 테이블 2개로 다대다 관계를 표현할 수 없다. 중간에 테이블을 추가해서 일대다, 다대일 관계로 풀어내야 한다. 이와 달리 객체는 컬렉션을 사용해서 객체 2개로 다대다 관계를 표현할 수 있다. Member는 productList를 가지고, Product는 memberList를 가진다. 다대다는 @ManyToMany를 사용하고, @JoinTable로 연결 테이블을 지정한다. 양쪽 테이블의 PK가 FK가 된다. //Member.java @ManyToMany @JoinTable(name = "MEMBER_PRODUCT") private List products = new ArrayList(); 다대다 매핑도 단방향, 양방향 매핑이 모두 가능하다. 양방향 매핑을 하고 싶..
일대일 관계 일대일 관계는 대칭적이다. 따라서 주 테이블이나 대상 테이블 중에 외래키를 넣을 곳을 선택할 수 있다. 예를 들어, 주테이블인 Member에 외래키를 넣을 수 있고, 대상 테이블인 Team에 외래키를 넣을 수 있다. 외래키에 데이터베이스 유니크 제약 조건을 추가해야 한다. 유니크의 유무가 일대일과 다대일을 구분 짓는 차이점이 된다. 일대일 - 주 테이블에 외래키 단방향 Member를 주 테이블로 설정했기 때문에 Member에 외래키를 놓았다. Locker 테이블을 주 테이블로 정할 수도 있다. 그때는 Locker 테이블에 MEMBER_ID(FK, UNI)를 추가해야 한다 다대일 단방향 매핑과 유사하며, 어노테이션 차이만 있다. 아래는 주 테이블에 일대일 단방향을 설정하는 코드이다. //Mem..
앞에서 다대일 연관관계를 살펴보았다. 다대일 이번 글에서는 일대다 연관관계를 알아볼 것이다. 일대다 단방향 일대다에서 일이 연관관계의 주인이다. 객체에서는 연관관계의 주인인 Team이 members로 외래키를 관리한다. 테이블에서는 무조건 다쪽인 Member에 외래키가 들어간다. 이러한 객체와 테이블 간 차이 때문에 Team 객체는 반대편 테이블의 외래키를 관리한다. Team.members 값을 바꿨을 때 TEAM_ID가 업데이트 된다. 아래 코드를 통해 일대다 관계를 설정할 수 있다. 이때 @JoinColumn을 꼭 사용해야 한다. 사용하지 않으면, Member_Team 조인 테이블이 추가로 생기므로 비효율적이다. //Team.java @OneToMany @JoinColumn(name = "TEAM_I..
연관관계 매핑 시 고려사항 3가지 1. 다중성 다대일: @ManyToOne 일대다: @OneToMany 일대일: @OneToOne 다대다: @ManyToMany 2. 단방향, 양방향 테이블은 외래키 하나로 양쪽 조인이 가능하므로 방향의 개념이 없다. 객체는 참조용 필드가 있는 쪽으로만 참조할 수 있다. 예를 들어, Member에서 Team을 참조하고 싶으면 참조 필드 Member.team이 필요하다. 한쪽만 참조하면 단방향이고, 양쪽이 서로를 참조하면 양방향이다. 사실 객체 입장에서는 양방향이 아니라 단방향 2개이다. 3. 연관관계의 주인 테이블은 외래키 하나로 두 테이블이 연관관계를 맺는다. 객체 양방향 관계는 A->B, B->A로 참조가 2개이다. 두 참조 중에 테이블 외래키를 관리할 참조를 지정해야..
객체 연관관계와 테이블 연관관계의 차이 테이블 연관관계는 1개로 방향 개념이 없다. 테이블은 외래키 하나로 두 테이블의 연관관계를 관리한다. 외래키 Member.TEAD_ID로 Member, Team 양쪽을 조인할 수 있다. 객체는 연관관계가 2개이다. 객체를 양방향으로 참조하려면, 단방향 연관관계 2개를 만들어야 한다. Member와 Team 객체에 각각 참조값을 넣어 양쪽으로 참조를 할 수 있다. 양방향 매핑 규칙 두 개의 참조값 중 하나로 외래키를 관리해야 한다. Member.team이 바뀌었을 때 TEAM_ID를 바꿔야 할지, Team.Members가 바뀌었을 때 TEAM_ID를 바꿔야 할지 정해야 한다. 두 객체의 관계 중 하나를 연관관계 주인으로 지정한다. 연관관계 주인만이 외래키를 수정할 수..
학습 목표 객체와 테이블 연관관계 간의 차이를 이해 객체의 참조와 테이블의 외래키를 매핑 용어 이해 방향: 단방향, 양방향 다중성: 다대일, 일대다, 일대일, 다대다 연관관계 주인: 양방향 연관관계는 관리하는 주인이 필요 연관관계의 필요성 객체를 테이블에 맞추어 모델링 객체를 테이블에 맞춰서 데이터 중심으로 모델링하면 협력 관계를 만들 수 없다. 테이블과 객체 사이에는 큰 차이가 있기 때문이다. 테이블은 외래키로 조인을 사용해서 연관된 테이블을 찾는다면, 객체는 참조를 사용해서 연관된 객체를 찾는다. 객체 간에 양방향 연관관계를 만들고 싶으면, 두 객체에 필드를 추가해서 참조를 보관해야 한다. 참조를 통한 연관관계는 항상 단방향이기 때문이다. 이와 달리 테이블은 외래키 하나로 양방향 조인이 가능하다. M..