JPA

[JPA] 1 : N 구조의 외래키 설정 및 Entity 구조 알아보기 (2)

jongh0 2025. 8. 21. 19:25

이전 게시물에서는 외래키 제약조건 없이 로그인 기능에 대해서만 코드를 작성하고 예제를 연습했었는데,

 

이번 게시물에서는 서로 다른 테이블 간의 기본키와 외래키 제약조건을 설정하고 어떤식으로 테이블이 생성되어지고

외래키 참조에 있어서 JPA형식의 코드를 어떤식으로 작성해야하는지에 대해서 다루겠다.

 


[클래스 구조]

1. Member

- MemberApiController

- MemberService

- MemberRepository

- MemberEntity

- MemberDto

 

2. Board

- BoardApiController

- BoardService

- BoardRepository

- BoardEntity

- BoardDto

 

2가지의 테이블을 다루고 멤버테이블에서 MEMBER 테이블의 기본키(no)를 통해서 Board 테이블에 writerNo에 해당하는 외래키를 설정하는 방식으로 진행한다.

 

일단 Member와 Board 테이블 생성 및 JPA 컨텍스트 상호작용을 위한 Entity 클래스를 살펴보자

 


 

[MemberEntity]

MemberEntity

 

일단 MemberEntity 클래스 윗단에 작성되는 어노테이션으로,

 

- Entity : 해당 클래스가 JPA 형식에 있어서 이 클래스가 영속성 관리 대상임을 명시

- Table : 매핑할 테이블 이름을 지정함 (name = " ~~~ " )

- Getter : Lombok의 어노테이션으로 각 필드에 대한 자동 getter 메서드 생성을 위해서 사용

- Setter : 모든 필드에 대해서 private setter 메서드를 생성해주고, 외부에서 임의로 setter 호출이 불가능하도록 AccessLevel.PRIVATE를 설정

- SequenceGenerator : name 속성에는 JPA에서 사용할 시퀀스 제너레이터 이름, sequenceName에는 DB에서 실제로 사용할 시퀀스 이름, allocationSize는 시퀀스 값을 한 번씩 증가시키도록 설정 (default는 50)

 

 

MemberEntity 필드정의

 

 DB에 컬럼으로 들어갈 요소로 no, userId, userPwd, userNick, createAt, delYn이 있다.

해당 칼럼들 중에서 no의 경우에서 해당 테이블에 기본키가 되는 속성이므로 

@Id 어노테이션을 사용하고, @GeneratedValue 어노테이션의 경우 아까 생성했던 시퀀스에 대해서 해당 컬럼에 적용하기 위한 어노테이션이다. strategygenerator에 전략으로 시퀀스, JPA에서의 시퀀스 제너레이터 명을 적어주면된다.

 

각 필드에 대해서 위에 컬럼마다 조건을 달아주기 위해서 @Column 어노테이션을 붙혀놨는데,

nullable = false의 경우, 해당 칼럼이 not null 조건을 달아주고,

unique는 해당 컬럼의 값이 다른 rows 데이터와 중복되지 않도록,

length 말그대로 길이에 대한 조건이다.

 

MemberEntity 생성자 및 Dto -> Entity 변환 메서드 from

 

 MemberEntity 기본 생성자에서 기본적으로 Entity를 통해서 DB에 데이터가 생성되는 경우, createAt(등록일), delYn(소프트딜리트 여부) 에 대해서 default 값으로 값이 들어가야한다.

그래서 등록일의 경우 LocalDataTime 클래스의 now() 메서드를 통해서 등록될 때의 시간을 담아내고, delYn은 생성시 삭제되지 않았음을 표시하는 "N"으로 기본값을 설정하였다.

 

아래 from 메서드는 JPA형식의 V - C - S - R 구조에서 DTO클래스와 Entity 객체간의 데이터형 변환이 이루어져야하는데 매번 그때마다 서비스 클래스 등에서 setter/getter 를 사용해가며 변환하는것은 올바르지 않다.

 

그래서 메서드를 미리 정의(from)해두고 변환이 필요한 시점에 해당 메서드를 통해서 Dto -> entity 로의 변환이 가능하도록 만든 메서드이다. 유효성 검사를 service에서 해도 상관없지만 다음과 같은 메서드 안에서 진행하는것도 한가지 방법이다.

 

 

 


[BoardEntity]

BoardEntity

 

 BoardEntity 클래스의 어노테이션이다. Setter가 필요하다면 사용하고 필요없다면 적지 않는게 외부 접근에 있어서 방지되므로 안적을 수 있다면 안적는 것이 좋다. 이외의 어노테이션은 MemberEntity에서 사용했던 기능과 동일하다.

 

BoardEntity 필드

 

 BoardEntity의 필드로 no, title, content, writer, createAt, delYn이 있으며 여기서 중요한 필드는 MemberEntity 데이터형의 writer 필드이다. 

해당 필드는 MemberEntity의 객체 정보를 담기위한 필드로 "작성자"가 누구인지에 대한 정보가 담기는 MEMBER 외래키 속성이다. 외래키 설정과 외래키 컬럼에 대한 설정을 다루는 2가지 어노테이션에대해서 알아보자.

 

@manyToOne : 현재 클래스(BoardEntity)를 기점으로 해당 컬럼(writer)이 N : 1 구조일 때, 관계 매핑을 위한 어노테이션 ( ex 3번 작성자가 10개의 글을 썻다면 10가지 글에 대해서 3번 작성자 정보가 매핑되어있음 (N : 1) 구조)

 

@JoinColumn의 경우 단순히 Column 어노테이션이 아닌 테이블 간의 조인설정에 해당하는 컬럼에 대해서 외래키 매핑을 설정할 때 사용되어짐 안에 들어가는 name 속성을 통해서 테이블 컬럼 명을 직접 지정해줄 수 있음

 

 

BoardEntity 속성 default 값 설정 및 dto -> Entity 변환 메서드

 

 

 MemberEntity와 동일하게 createAt과 delYn에 대해서 기본 값 설정을 위해서 기본 생성자 내에서 값을 할당해주고,

from 메서드를 통해서 dto와 memberEntity를 입력받고, memberEntity를 통해서 외래키 설정된 writer 필드에 값을 할당한다. writer는 할당된 memberEntity 객체에서 기본키인 유저번호 (no)를 통해서 외래키 제약조건이 적용된다.