-
Notifications
You must be signed in to change notification settings - Fork 6
Description
현재 테이블 구조
피드 테이블과 매칭하여 피드에 달린 댓글을 저장하는 테이블 'Comment'를 만들고 있습니다.
수정, 삭제기능을 고려하여 댓글 테이블 전용 ID를 따로 만들어서 PK로 지정하였고,
이 댓글 테이블은 피드 하나하나의 댓글 전체를 묶어서 보여줄 수 있어야 하기 때문에
feed 테이블의 피드 번호 컬럼을 외래 키(Foreign Key, 이하 FK)로 사용합니다.

(왼쪽은 MySQL DB에서, 오른쪽은 Java Entity에서)
JPA에서 테이블에 외래 키를 지정하는 방법
먼저, 위 그림에 나와있는 Comment 테이블의 Entity 클래스입니다.
@RequiredArgsConstructor
@AllArgsConstructor
@Table(name = "comment") // 테이블 이름
@Getter
@Builder
@Entity
public class Comment {
@Id
@Column(nullable = false)
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long commentid; // 댓글 테이블 고유 번호
@ManyToOne
@JoinColumn(nullable = false) // 외래키 이름
private Feed feed; // 피드 번호
@Column(nullable = false)
private String userid; // 작성자
@Column(nullable = false)
private int commentNo; // 해당 피드에서의 댓글 번호
@Column(nullable = false)
private LocalDateTime uploadTime; // 댓글 작성시각
@Column(nullable = false)
@ColumnDefault("0")
private int likeCount; // 좋아요 수
@Column(nullable = false, length = 1000)
private String article; // 댓글 내용
}여기서 외래 키를 지정하는 부분은 다음과 같습니다.
@ManyToOne
@JoinColumn(nullable = false) // 외래키 이름
private Feed feed; // 피드 번호@ManyToOne: 이 어노테이션이 붙은 필드의 Entity(여기서는 Feed)의 PK를 현재 Entity(Comment)의 FK로 사용합니다.
@JoinColumn: 이 어노테이션이 붙은 필드는 FK입니다.
외래 키로 지정한 필드는 연관되는 테이블의 Entity를 자료형으로 해야 합니다.
(여기서는 Feed 테이블의 PK를 FK로 불러오고자 하므로, Feed 테이블의 Entity 클래스인 Feed를 자료형으로 선언)
@ManyToOne
다대일 관계를 나타내는 어노테이션입니다.

1개의 Feed에는 여러 개의 Comment를 달 수 있지만, 1개의 Comment는 1개의 Feed에만 할당될 수 있습니다.
이 경우, 다대일 관계에서 "다"에 해당하는 Comment Entity의 FK 필드에 @ManyToOne 어노테이션을 지정합니다.
Foreign Key를 이용하여 피드 1개에 달린 댓글들 불러오기
1. FK만 사용하기 위해 FK만 들어있는 DTO 생성
@Getter
@Builder
public class CommentReadDto {
private long feedNo;
}FK인 FeedNo 하나만 사용하기 위해서 DTO를 만들어줍니다.
2. Comment Repository에 FeedNo만으로 검색하는 메서드 생성
Repository 클래스에 함수 이름을 지정해줍니다.
public interface CommentRepository extends JpaRepository<Comment, Long> {
Optional<List<Comment>> findByFeed_FeedNo (Long feedNo);
}JPA Repository 함수명 규칙은 다음과 같습니다.
"findBy" + 외래키가 있는 테이블 이름(Feed) + "_" + 외래키 Entity의 필드명(첫 글자만 대문자)
이렇게 선언할 경우, DB의 Comment 테이블에서 외래키로 지정한 FeedNo의 값이 같은 row들을 모아서 가져옵니다.
3. Repository 메서드를 실행할 Sevice 메서드 생성
Service 클래스에 1.의 DTO를 입력으로 받아서 2.의 Repository 메서드를 실행하는 메서드를 생성
public List<CommentListDto> getCommentsInFeed(CommentReadDto commentReadDto) {
return commentRepository.findByFeed_FeedNo(commentReadDto.getFeedid()).get()
.stream().map(CommentListDto::new).toList();
}현재 DB에서는 외래키가 feed_no라는 컬럼으로 저장되어 있으므로, 이 값이 파라미터로 들어온 값과 일치하는 row를 모두 가져옵니다.

(6번 FeedNo에 달린 댓글을 모두 가져온 모습)