댓글 기능의 개요
1. 댓글과 게시글의 관계
- 엔티티: DB 데이터를 담는 자바 객체로, 엔티티 기반으로 테이블 생성
- 리파지터리: 엔티티를 관리하는 인터페이스로, 데이터 CRUD 등의 기능 제공
2. 댓글 엔티티와 리파지터리 설계
- 각 인터페이스의 기능
- Repository: 최상위 리파지터리 인터페이스
- CrudRepository 및 ListCrudRepository: 엔티티의 CRUD 기능 제공
- PagingAndSortingRepository 및 ListPagingAndSortingRepository: 엔티티의 페이징 및 정렬 기능 제공
- JpaRepository: 엔티티의 CRUD 기능, 페이징 및 정렬 기능, JPA에 특화된 기능을 추가로 제공
댓글 엔티티 만들기
1. 댓글 엔티티 만들기
@Entity // 해당 클래스가 엔티티임을 선언, 클래스 필드를 바탕으로 DB에 테이블 생성
@Getter // 각 필드 값을 조회할 수 있는 getter 메서드 자동 생성
@ToString // 모든 필드를 출력할 수 있는 toString 메서드 자동 생성
@AllArgsConstructor // 모든 필드를 매개변수로 갖는 생성자 자동 생성
@NoArgsConstructor // 매겨변수가 아예 없는 기본 생성자 자동 생성
public class Comment {
@Id // 대표키 지정
@GeneratedValue(strategy= GenerationType.IDENTITY) // DB가 자동으로 1씩 증가
private Long id; // 대표키
@ManyToOne // 이 엔티티(Comment)와 부모 엔티티(Article)를 다대일 관계로 설정
@JoinColumn(name="article_id") // 외래키 생성, Article 엔티티의 기본키(id)와 매핑
private Article article; // 해당 댓글의 부모 게시글
@Column // 해당 필드를 테이블의 속성으로 매핑
private String nickname; // 댓글을 단 사람
@Column // 해당 필드를 테이블의 속성으로 매핑
private String body; // 댓글 본문
}
2. 더미 데이터 추가하기
-- 기존 데이터
INSERT INTO article(title, content) VALUES('가가가가', '1111');
INSERT INTO article(title, content) VALUES('나나나나', '2222');
INSERT INTO article(title, content) VALUES('다다다다', '3333');
-- article 테이블에 데이터 추가
INSERT INTO article(title, content) VALUES('당신의 인생 영화는?', '댓글 고');
INSERT INTO article(title, content) VALUES('당신의 소울 푸드는?', '댓글 고고');
INSERT INTO article(title, content) VALUES('당신의 취미는?', '댓글 고고고');
-- 4번 게시글의 댓글 추가
INSERT INTO comment(article_id, nickname, body) VALUES(4, 'Park', '굿 윌 헌팅');
INSERT INTO comment(article_id, nickname, body) VALUES(4, 'Kim', '아이 엠 샘');
INSERT INTO comment(article_id, nickname, body) VALUES(4, 'Choi', '쇼생크 탈출');
-- 5번 게시글의 댓글 추가
INSERT INTO comment(article_id, nickname, body) VALUES(5, 'Park', '치킨');
INSERT INTO comment(article_id, nickname, body) VALUES(5, 'Kim', '샤브샤브');
INSERT INTO comment(article_id, nickname, body) VALUES(5, 'Choi', '초밥');
-- 6번 게시글의 댓글 추가
INSERT INTO comment(article_id, nickname, body) VALUES(6, 'Park', '조깅');
INSERT INTO comment(article_id, nickname, body) VALUES(6, 'Kim', '유튜브 시청');
INSERT INTO comment(article_id, nickname, body) VALUES(6, 'Choi', '독서');
3. 댓글 조회 쿼리 연습하기
- 특정 게시글의 모든 댓글 조회:
SELECT * FROM comment WHERE article_id = 4;
- 특정 닉네임의 모든 댓글 조회:
SELECT * FROM comment WHERE nickname = 'Park';
댓글 리파지터리 만들기
1. 댓글 리파지터리 만들기
public interface CommentRepository extends JpaRepository<Comment, Long> {
// 특정 게시글의 모든 댓글 조회
@Query(value = "SELECT * FROM comment WHERE article_id = :articleId",
nativeQuery = true) // value 속성에 실행하려는 쿼리 작성
List<Comment> findByArticleId(Long articleId);
// 특정 닉네임의 모든 댓글 조회
List<Comment> findByNickname(String nickname);
}
<?xml version="1.0" encoding="utf-8" ?>
<entity-mappings xmlns="<https://jakarta.ee/xml/ns/persistence/orm>"
xmlns:xsi="<http://www.w3.org/2001/XMLSchema-instance>"
xsi:schemaLocation="<https://jakarta.ee/xml/ns/persistence/orm>
<https://jakarta.ee/xml/ns/persistence/orm/orm_3_0.xsd>"
version="3.0">
<named-native-query
name="Comment.findByNickname"
result-class="com.example.firstproject.entity.Comment">
<query>
<![CDATA[
SELECT * FROM comment WHERE nickname = :nickname
]]>
</query>
</named-native-query>
</entity-mappings>
2. 댓글 리파지터리 테스트 코드 작성하기