3. Spring 게시판 무작정 따라하기

글쓰기 기능 개발 및 단위 테스트 방법
HootJem's avatar
Aug 16, 2024
3. Spring 게시판 무작정 따라하기
 

1. 리포지토리(Repository) 생성

💡
리포지토리란? 엔티티에 의해 생성된 데이터베이스 테이블에 접근하는 메서드들을 사용하기 위한 인터페이스
notion image
notion image
  • @Repositort 어노테이션을 사용하여 레포지토리를 생성한다. 이 어노테이션을 붙이면 Spring이 자동으로 해당 클래스를 빈으로 등록하고, IoC 컨테이너에 저장한다.
 
notion image
  • @Autowired를 사용하여 EntityManager를 주입받는다. 이를 통해 데이터베이스와 상호작용할 수 있다.
  • 직후 실행해 보면 콘솔에서 다음과 같은 로그를 확인할 수 있다. 테이블이 생성되고 리포지토리 코드가 실행되었다.
notion image
 

1.1 테이블 명을 변경하고 싶을 때

notion image
Table(name = "테이블_이름")
private 데이터타입 컬럼이름
컬럼 이름이 변경되면 @Builder 의 생성자 명도 변경이 되어야 한다.
 
프로젝트를 다시 시작한 뒤 http://localhost:8080/h2-console 콘솔에 접속하여
설정한 테이블명, 컬럼명으로 변경 되었는지 확인한다.
notion image
👍 변경이 잘 된 모습

2. 리포지토리(Repository) 쿼리 작성 및 테스트

import jakarta.persistence.EntityManager; import jakarta.persistence.Query; import jakarta.transaction.Transactional; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; @Repository // @Repository 를 붙이면 스프링이 new 해서 IoC(컬렉션 List 자료형 같은거) 에 저장한다 public class BoardRepository { @Autowired // IoC에 있는 객체를 찾아온다. private EntityManager em; public BoardRepository() { System.out.println("BoardRepository 생성자"); } //1. insert 하기 @Transactional public void save(String subtitle, String postContent) { Query query = em.createNativeQuery("insert into board_tb (subtitle, post_content, created_at) values (?, ?,now())"); query.setParameter(1, subtitle); // position : ? 의 순서 query.setParameter(2, postContent); query.executeUpdate(); } }
 
DB와 Repository 가 잘 작성되었는지 확인하기위해 단위 테스트를 실행한다.
notion image
레포지토리+Test 인 클래스 생성 후
package shop.mtcoding.blog.board; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; import org.springframework.context.annotation.Import; //@SpringBootTest // C R em h2 -> 모든 레이어를 메모리에 올리고 테스트 할 때 사용 @DataJpaTest // h2, em @Import(BoardRepository.class) // br public class BoardRepositoryTest { @Autowired private BoardRepository boardRepository; //테스트메서드에서는 매개변수를 사용할 수 없다 // 메서드명_test : 컨벤션 @Test public void save_test() { // 1. given (매개변수를 강제로 만들어주는것) String subtitle = null; String postContent = "내용 1"; // 2. when boardRepository.save(subtitle, postContent); // 3. eye(눈으로 확인) } }
 
notion image
작성한 테스트 코드를 실행할 수 있다.
실행을 하면 에러 메세지를 마주하게 되는데 천천히 읽어보자.
notion image
subtitle 컬럼을 찾을 수 없고 SQL 문법 오류 가 발생했다.
 
Hibernate: create table board_tb (id integer generated by default as identity, created_at timestamp(6), content varchar(255) not null, title varchar(255) not null, primary key (id)) insert into board_tb (subtitle, post_content, created_at) values (?, ?,now()) 위는 프로젝트 실행과 함께 만들어진 테이블, 아래의 쿼리문이 테스트코드이다. 컬럼명이 일치하지 않는 것을 확인할 수 있다 따라서 테스트 코드의 컬럼 명을 수정한다.
@Test public void save_test() { // 1. given (매개변수를 강제로 만들어주는것) String subtitle = null; String postContent = "내용 1"; // 2. when boardRepository.save(subtitle, postContent); // 3. eye(눈으로 확인) }
@Test public void save_test() { // 1. given (매개변수를 강제로 만들어주는것) String title = null; String content = "내용 1"; // 2. when boardRepository.save(title, content); // 3. eye(눈으로 확인) }
컬럼명을 올바르게 수정했으나 위와 똑같은 에러가 발생한다.
이는 전달하는 인자의 이름은 변경을 했으나 save 하는 리포지토리의 쿼리문 수정이 이루어져있지 않기 때문이다.
 
BoardRepository 로 이동한다.
 
notion image
호출하는 save 의 인자이름은 테이블의 컬럼명과 동일해야 한다.
이때 엔티티에는 CreatedAt 으로 작성했지만 테이블 상에서는 created_at 으로 생성되므로
쿼리문은 테이블 명을 따라간다.
 
@Transactional public void save(String title, String content) { Query query = em.createNativeQuery("insert into board_tb (title, content, created_at) values (?, ?,now())"); query.setParameter(1, title); // position : ? 의 순서 query.setParameter(2, content); query.executeUpdate(); }
이렇게 코드와 쿼리문 수정을 한 뒤 다시 단위테스트를 수행한다.
 
결과는?
notion image
실패지만 에러 메세지가 아까와 다르다.
NULL not allowed for column "TITLE"; title 컬럼에는 null 이 입력될 수 없다는건데
 
이는 엔티티에서 적은 @Column(nullable = false) 때문이다. (빈 값이 들어가는 현상을 막기위해 설정함)
null 이 들어가 있는 String title 을 String title = "내용"; 으로 변경한 뒤 테스트를 실행하면
notion image
성공했음을 볼 수 있다.
이렇게 db 는 테스트가 완료 되었다.
 

Share article

[HootJem] 개발 기록 블로그