사이먼's 코딩노트

[SpringBoot] DB 테이블 매핑 / Repository로 DB 관리하기(1) 본문

Java/SpringBoot

[SpringBoot] DB 테이블 매핑 / Repository로 DB 관리하기(1)

simonpark817 2024. 5. 7. 12:15

[테이블 매핑하기]

  • JPA 적용을 마쳤다면, 이번에는 엔티티로 DB 테이블을 매핑해보도록 합시다.
  • 여기서 말하는 엔티티는 DB 테이블과 매핑되는 Java 클래스를 말한다.
  • 현재 진행하고있는 sbb는 질문과 답변을 할 수 있는 게시판 서비스이기 때문에 sbb의 질문과 답변 데이터를 저장할 DB 테이블과 매핑되는 질문과 답변 엔티티가 있어야한다.
  • 각 엔티티에는 속성이 필요하는데, 이는 DB로 생각했을 때 컬럼과 같은 의미라고 생각하면 좋다.

 

[질문 엔티티 생성]

  • 질문과 관련된 엔티티를 생성하기 위해 Question.java 클래스를 하나 생성한 다음 아래와 같은 코드를 작성한다.
package com.sbs.sbb;

import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;

import java.time.LocalDateTime;
import java.util.List;

@Getter
@Setter
@Entity                                                    
public class Question {
    @Id                                                   
    @GeneratedValue(strategy = GenerationType.IDENTITY)      
    private Integer id;

    @Column(length = 200)                                     
    private String subject;

    @Column(columnDefinition = "TEXT")                        
    private String content;

    private LocalDateTime createDate;

    @OneToMany(mappedBy = "question", cascade = CascadeType.REMOVE)
    private List<Answer> answerList;
}
  • @Entity라는 어노테이션을 적용함으로써, 스프링 부트가 Question.java 클래스를 엔티티로 인식한다.
  • 엔티티의 속성으로는 id, subject, content, createDate, answerList가 있다.
  • @Id 어노테이션은 id 속성을 Primary key로 지정하는 역할을 한다. id를 기본키로 지정한 이유는 id 속성의 고유 번호들은 엔티티에서 각 데이터들을 구분하는 유효한 값으로, 중복되면 안되기 때문이다.
  • @GeneratedValue 어노테이션은 id 속성에 Auto_increment을 적용하여 자동으로 1씩 증가하도록 하는 역할을 한다.
  • @Column 어노테이션은 각 컬럼의 세부 설정을 위해 사용된다.
  • length = 200은 VACHAR(200)과 같은 설정이고, columnDefinition = "TEXT" 는 TEXT과 같은 설정이다.
  • 질문에서 답변을 참조하기 위해서 @OneToMany 어노테이션을 사용하는데, 이 때 질문 하나에 여러개의 답변을 가지는 방식이기 때문에 answerList는 List로 구성되어야되고, 실제 테이블의 컬럼으로는 생성되지 않는다.
  • OneToMany에서 One은 하나의 질문, Many는 여러개의 답변을 의미하고 1:N의 관계라고 생각하면 좋다.
  • OneToMany 어노테이션에 사용된 mappedBy는 참조 엔티티의 속성명을 정의하는데, 다시 말해서 Answer 엔티티에서 Question 엔티티를 참조한 속성인 question을 mappedBy에 전달해야한다.
  • cascade = CascadeType.REMOVE는 질문을 삭제할 때 답변들도 모두 삭제된다는 의미이다.
  • 아래는 실제로 Question.java 엔티티를 통해 question 테이블이 생성된 모습이다.

Question 테이블 생성

 

[답변 엔티티 생성]

  • 답변과 관련된 엔티티를 생성하기 위해 Answer.java 클래스를 하나 생성한 다음 아래와 같은 코드를 작성한다.
package com.sbs.sbb;

import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;

import java.time.LocalDateTime;

@Getter
@Setter
@Entity                                                   
public class Answer {
    @Id                                                   
    @GeneratedValue(strategy = GenerationType.IDENTITY)     
    private Integer id;

    @Column(columnDefinition = "TEXT")                   
    private String content;

    private LocalDateTime createDate;

    @ManyToOne
    private Question question;
}
  • @Entity라는 어노테이션을 적용함으로써, 스프링 부트가 Answer.java 클래스를 엔티티로 인식한다.
  • 엔티티의 속성으로는 id, content, createDate, question가 있다.
  • @Id 어노테이션은 id 속성을 Primary Key로 지정하는 역할을 한다. id를 기본키로 지정한 이유는 id 속성의 고유 번호들은 엔티티에서 각 데이터들을 구분하는 유효한 값으로, 중복되면 안되기 때문이다.
  • @GeneratedValue 어노테이션은 id 속성에 Auto_increment을 적용하여 자동으로 1씩 증가하도록 하는 역할을 한다.
  • @Column 어노테이션은 각 컬럼의 세부 설정을 위해 사용된다.
  • columnDefinition = "TEXT" 는 TEXT과 같은 설정이다.
  • 게시판 서비스에서는 하나의 질문에 답변이 여러개 달릴 수 있기 때문에 답변은 많은 것이 되고, 질문은 하나가 된다.
  • @ManyToOne 어노테이션을 사용하면 N:1 관계를 나타낼 수 있다.
  • @ManyToOne 어노테이션을 설정하면 답변 엔티티의 question 속성과 질문 엔티티가 서로 연결된다.
  • 실제 DB에서는 외래키 관계가 생성된다. 여기서 말하는 외래키는 테이블과 테이블 사이의 관계를 구성할 때 연결되는 컬럼을 의미한다.
  • 아래는 실제로 Answer.java 엔티티를 통해 answer 테이블이 생성된 모습이다.

Answer 테이블 생성

 

 

 

[Repository로 DB 관리하기]

  • 앞선 작업으로, 엔티티로 테이블을 생성하여 데이터 관리할 준비를 마쳤다.
  • 하지만 엔티티만으로는 테이블의 데이터를 저장, 조회, 수정, 삭제등을 할 수 없기 때문에 이와 같이 데이터를 관리하려면 DB와 연동하는 리포지터리가 반드시 필요하다.
  • 여기서 말하는 리포지터리는 생성된 DB 테이블의 저장, 조회, 수정, 삭제 등을 할 수 있도록 도와주는 인터페이스이다.
  • 이 때, 리포지터리는 테이블에 접근하고, 데이터를 관리하는 메서드를 제공한다.
  • QuestionRepository.java와 AnswerRepository.java 클래스를 생성한 다음 아래와 같은 코드를 작성한다.
package com.sbs.sbb;

import org.springframework.data.jpa.repository.JpaRepository;

public interface QuestionRepository extends JpaRepository<Question, Integer> {

}
package com.sbs.sbb;

import org.springframework.data.jpa.repository.JpaRepository;

public interface AnswerRepository extends JpaRepository<Answer, Integer> {

}
  • 각 인터페이스를 리포지터리를 만들기 위해 JpaRepository 인터페이스를 상속한다.
  • JpaRepository는 JPA가 제공하는 인터페이스 중 하나로 CRUD 작업을 처리하는 메서드들을 이미 내장하고 있어, 데이터 관리 작업을 좀 더 편리하게 처리할 수 있다.
  • JpaRepository<Question(Answer), Integer> 는 Question나 Answer 엔티티로 리포지터리를 생성한다는 의미이고, Question과 Answer 엔티티의 기본키인 id가 Integer임을 이와 같이 추가로 지정해야 한다.

 

[질문 데이터 저장하기]

  • 리포지터리까지 생성되었다면, 이번에는 실제로 Question 테이블에 데이터를 생성하고 저장해보도록 합시다.
  • SbbApplicationTests.java인 테스트 클래스를 사용하여 데이터를 저장해봅시다.
package com.sbs.sbb;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.time.LocalDateTime;

@SpringBootTest
class SbbApplicationTests {
    @Autowired
    private QuestionRepository questionRepository;

    @Test
    void testJpa() {
       Question q1 = new Question();
       q1.setSubject("sbb가 무엇인가요?");
       q1.setContent("sbb에 대해서 알고 싶습니다.");
       q1.setCreateDate(LocalDateTime.now());
       this.questionRepository.save(q1);  // 첫번째 질문 저장

       Question q2 = new Question();
       q2.setSubject("스프링부트 모델 질문입니다.");
       q2.setContent("id는 자동으로 생성되나요?");
       q2.setCreateDate(LocalDateTime.now());
       this.questionRepository.save(q2);  // 두번째 질문 저장
    }

}
  • @SpringBootTest 어노테이션은 SbbApplicationTests.java 클래스가 스프링 부트의 테스트 클래스임을 의미한다.
  • 질문 엔티티의 데이터를 생성할 때 리포지터리가 필요하므로 @Autowired 어노테이션을 통해 스프링의 의존성 주입이라는 기능을 사용하여 QuestionRepository의 객체를 주입했다.
  • testJpa() 메서드 안에는 q1과 q2라는 객체를 생성하여 각 컬럼에 저장할 데이터 값을 작성한다.
  • 작성한 SbbApplicationTests.java 클래스를 실행해보면 아래와 같이 실제로 DB에 새로운 데이터들이 추가되고 저장된 모습을 볼 수 있다.

Question 테이블에 생성된 데이터

 

반응형

'Java > SpringBoot' 카테고리의 다른 글

[SpringBoot] Repository로 DB 관리하기(3)  (0) 2024.05.07
[SpringBoot] Repository로 DB 관리하기(2)  (0) 2024.05.07
[SpringBoot] Spring Security / JPA  (0) 2024.05.06
[SpringBoot] Java Spring Boot  (0) 2024.05.03
[SpringBoot] 개념 정리  (0) 2024.05.02