1. @SpringBootTest 으로 시작
@SpringBootTest
class SbbApplicationTests {
@Autowired
private QuestionRepository questionRepository; // 생성자
2. testJpa
@Test
void testJpa() {
Question q1 = new Question(); // Question class 의 q1 인스턴스 생성
q1.setSubject("sbb가 무엇인가요?"); // question entity내 신규 subject 값 지정
q1.setContent("sbb에 대해서 알고 싶습니다."); // question entity내 신규 content 값 지정
q1.setCreateDate(LocalDateTime.now()); // question entity내 신규 createDate 값 지정
this.questionRepository.save(q1); // insert into question entity
Question q2 = new Question();
q2.setSubject("스프링부트 모델 질문입니다.");
q2.setContent("id는 자동으로 생성되나요?");
q2.setCreateDate(LocalDateTime.now());
this.questionRepository.save(q2); // 두번째 질문 저장
/*
questionRepository는 JpaRepository를 상속받은 인터페이스로,
save() 메서드를 통해 Question 객체 q1을 데이터베이스에 저장합니다.
JpaRepository는 Spring Data JPA에서 제공하는 인터페이스로,
기본적인 CRUD 메서드들을 이미 정의하고 있습니다.
*/
}
- @SpringBootTest는 Spring Boot에서 통합 테스트를 할 때 사용하는 어노테이션. 테스트 클래스가 실제 애플리케이션처럼 동작하는 환경에서 실행
자주 함께 쓰는 어노테이션
- @Transactional : 테스트 후 DB 롤백
- @Test : JUnit 테스트 메서드
- @Autowired : 테스트 대상 주입
- @Autowired : pring 프레임워크에서 의존성(Dependency) 주입을 위해 사용하는 어노테이션. Spring이 관리하는 빈(Bean) 중에서 타입에 맞는 객체를 자동으로 찾아 등록.
- @Test : JUnit 프레임워크에서 테스트 메서드임을 표시하기 위해 사용되는 어노테이션. 선언된 다음 메서드는 테스트 실행 시 자동으로 호출되어 검증 로직 수행.
3. QuestionRepository 인터페이스
@Repository
public interface QuestionRepository extends JpaRepository<Question, Integer> { // id 자료형을 선언
Question findBySubject(String subject);
Question findBySubjectAndContent(String subject, String content);
List<Question> findBySubjectLike(String subject);
}
- @Repository 인터페이스가 Spring의 Repository 컴포넌트임을 선언. 생략해도 자동으로 인식되지만 명시적 등록권고.
- extends JpaRepository<Question, Integer> : Question 엔티티를 대상으로 하고, 기본 키(id)의 자료형은 Integer임을 명시.
- Question findBySubject(String subject) : 엔터티 내 subject 값이 정확히 일치하는 Question을 하나 반환.
- Question findBySubjectAndContent(String subject, String content); : subject와 content가 모두 일치하는 Question을 하나 반환
- List findBySubjectLike(String subject) : subject가 특정 패턴과 유사한 Question 목록을 반환합니다. 예: "Spring%" → "Spring Boot", "Spring Data" 등
4. Quesition 클래스
Question q1 = new Question();
@Entity // db
@Getter
@Setter
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)
@OneToMany(mappedBy = "question", cascade = CascadeType.REMOVE, fetch = FetchType.EAGER)
private List<Answer> answerList;
}
- @Id : JPA에서 @Id는 엔티티의 기본 키(Primary Key) 필드를 지정하는 어노테이션입니다. 이 어노테이션이 붙은 필드는 데이터베이스 테이블의 PK 컬럼과 매핑.
- @GeneratedValue는 JPA에서 엔티티의 @Id 필드에 대한 키 생성 방식을 지정하는 어노테이션. strategy = GenerationType.IDENTITY를 사용하면 데이터베이스가 제공하는 자동 증가(Identity) 컬럼 기능을 통해 기본 키 값을 생
- @OneToMany(mappedBy = "question", cascade = CascadeType.REMOVE, fetch = FetchType.EAGER)
- @OneToMany는 RDB에서 1:다 FK 관계를 설정을 위한 선언임
- mappedBy = "question" 은 현재 entity.question 이 설정 대상, 다시 말해서 Answer 내에 question 컬럼이 존재하며, Answer.question은 Question.quesiont의 FK임을 명시.
- 하단에 위치한 private List answerList; 선언에서 Answer 엔터티에 다수의 관계가 있음을 설명하고 있다.
5. testJpa2()
@Test
void testJpa2() {
List<Question> all = this.questionRepository.findAll();
assertEquals(2, all.size());
Question q = all.get(0);
assertEquals("sbb가 무엇인가요?", q.getSubject());
}
- @Test : Junit 테스트 선언
- findAll()은 JpaRepository가 제공하는 기본 메서드. List all = this.questionRepository.findAll() 은 question entity에 모든 정보를 조회한다는 뜻
- assertEquals(2, all.size()); 조회된 Question 객체의 수가 2개인지 확인합니다. 아닌 경우 오류 발생.
- Question q = all.get(0); : Question 클래스 객체를 선언하여 db에서 가져온 객체 리스트에서 1 번째 값들을 부여