[JPA] 테이블간의 관계표현

LDB·2025년 1월 9일
0

JPA 기본

목록 보기
8/10
post-thumbnail

연관관계

현재 서비스되고 있는 웹 어플리케이션중에 테이블을 단일 테이블로 사용하는 서비스는 별로 없을 것이다. 그렇기에 보통은 테이블끼리 연관을 지어서 사용하여 효율성을 높이는 방식을 많이 사용한다. 그래서 MyBatis같은 Mapper는 사용자가 직접 연관관계를 DBeaver같은 도구로 관계를 설정할 수 있다.

하지만 JPA를 사용한 경우에는 Entity객체끼리 연관을 지정해두면 자동으로 Key가 DB에 생성이 된다.

이 글에서는 OneToManyManyToOne에 대해서만 말하겠다.

OneToMany VS ManyToOne

데이터베이스의 1:N / N:1 두 개의 의미를 알고있으면 이해하기 쉬울 것이다.

  • OneToMany : @JoinColumn을 사용하는 Entity의 반대 Entity가 연관관계의 주인, 즉 FK를 가진다. (테이블상에서는 반대 테이블에 컬럼과 FK가 생긴다.)

  • ManyToOne : @JoinColumn을 사용하는 Entity가 연관관계의 주인, 즉 FK를 가진다. (테이블상에서는 대상 테이블에 컬럼과 FK가 생긴다.)

가상 시나리오

호텔에 손님(member)이 왔고 방(room)을 등록한다, 방을 등록했고, 호텔에 막 도착한 고객은 아침식사를 안해서 룸서비스(roomservice)를 주문했고 커피와 토스트를 주문했다.

이시나리오를 테이블로 구성해보면 간략하게 이렇게 나올 수 있겠다.

  • member 테이블
    투숙객의 고유번호(seq), 지내는방의 일련번호(room_seq), 투숙객의 성함(name), 나이(age)가 있어야 한다.

  • room 테이블
    지내는방의 이름(name), 방의 고유의 일련번호(seq)가 있어여 한다.

  • roomservice 테이블
    서비스 주문번호(seq), 드링크(drink), 음식(food), 어느방에서 시켰는지에 대한 방의 일련번호(room_seq) 그리고 이건 선택적인데 누가 시켰는지에 대한 고객번호(member_seq)가 필요하다.

JPA Entity 작성

Member Entity

@Getter
@Entity
@ToString
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Member {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "SEQ")
    @Comment(value = "일련번호")
    private int seq;                    

    @Column(name = "NAME", length = 50)
    @Comment(value = "이름")
    private String name;

    @Column(name = "AGE")
    @Comment(value = "나이")
    private int age;

    public Member(String name, int age){
        this.name = name;
        this.age = age;
    }

}

Room Entity

@Getter
@Entity
@ToString
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Room {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "seq")
    @Comment(value = "일련번호")
    private int seq;                    
    
    @Column(name = "room_name", length = 50)
    @Comment(value = "이름")
    private String roomname;

    @Comment(value = "멤버번호")
    @OneToMany(fetch = FetchType.LAZY)
    @JoinColumn(name = "room_seq")
    private List<Member> member;
    
    public Room(String roomname, List<Member> member){
        this.roomname = roomname;
        this.member = member;
    }
}

Roomsercie Entity

@Getter
@Entity
@ToString
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Roomservice {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "SEQ")
    @Comment(value = "일련번호")
    private int seq;   

    @Column(name = "food", length = 50)
    @Comment(value = "주문음식")
    private String food;

    @Column(name = "drink", length = 50)
    @Comment(value = "주문드링크")
    private String drink;

    @Comment(value = "숙소번호")
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "room_seq")
    private Room room;
    
    @Comment(value = "투숙객번호")
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "member_seq")
    private Member member;

    public Roomservice(String food, String drink, Room room, Member member){
        this.food = food;
        this.drink = drink;
        this.room = room;
        this.member = member;
    }

일단 이렇게 세 가지 타입의 Entity를 만들었고 공통적으로 생성자를 넣었다. 그리고 실행을 하면 테이블이 생성이 되고 외래키가 만들어진다.

테이블 생성

외래키 생성

DBeaver로 보는 연관관계



실제로 데이터 넣어보기

public void insertRoom() {
    // Room에 등록할 용도로 Member Type의 ArrayList생성
    List<Member> memberList = new ArrayList<>();

    for(int i = 0; i < 3; i++){ // 고객등록
        String people = "people_"+i;
        Member member = new Member(people,20); // Member Entity객체 생성 
        memberList.add(member); // 리스트에 Member객체 추가

        em.persist(member); // Member 테이블에 insert 쿼리추가
    }

    // Room 테이블에 normalRoom 등록쿼리 및 member 테이블에 등록된 사용자의 Room_seq 수정 쿼리추가 
    Room room = new Room("normalRoom",memberList); 
    em.persist(room);

    // 등록된 Room, 등록된 Member, 음식, 드링크 추가하는 쿼리추가
    Roomservice rooomservice = new Roomservice("toast", "coffee",  room, memberList.get(0));                                     
    em.persist(rooomservice);
}

시나리오작성 내용대로 프로그램을 작성해보았다.

  1. 손님(member)의 정보 등록
  2. 방(room)등록 및 손님(member)이 머무를 방(Room)등록
  3. 손님(member)가 룸서비스(roomservice)를 주문

결론

이런식으로 테이블간의 관계를 간략하게나마 설명하고 예시를 작성해보았는데 확실히 테이블 관계 표현을 나타내보고 싶으면 가상의 시나라오를 작성하고 테이블을 작성해보는게 나의 기준에서는 최고의 공부방법인거 같았다. 이 방법은 다른 사람들에게도 알려주고 싶다.

참고 사이트

https://dev-coco.tistory.com/106

https://ksh-coding.tistory.com/105

https://soojong.tistory.com/entry/JPA-ManyToOne-OneToMany-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0

(항상 감사합니다.)

profile
가끔은 정신줄 놓고 멍 때리는 것도 필요하다.

0개의 댓글

관련 채용 정보