JPA 란
- JPA는 인터페이스로서 자바 표준명세서이다
- 따라서 인터페이스인 JPA를 사용하기 위해서는 구현체가 필요하다
- 대표적인 구현체로는 Hibernate, Eclipse Link 등이 있는데, 이걸 직접 사용하진 않는다.
- 아래의 이유로, 위 구현체를 좀 더 쉽게 추상화시킨 Spring Data JPA 라는 모듈을 사용함.
- 구현체 교체의 용이성
- 저장소 교체의 용이성
build.gradle 에 JPA 관련 의존성 추가
//jpa
implementation('org.springframework.boot:spring-boot-starter-data-jpa')
implementation('com.h2database:h2')
- h2 는 인메모리 관계형 데이터베이스로, 별도로 설치가 필요하지 않다. 이 프로젝트에서는 테스트용, 로컬 환경에서의 구동용으로 사용할 예정.
Posts 엔티티 클래스 작성
package com.example.boilerplate.domain.posts;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Getter
@NoArgsConstructor
@Entity
public class Posts {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(length=500, nullable=false)
private String title;
@Column(columnDefinition = "TEXT", nullable = false)
private String content;
private String author;
@Builder
public Posts(String title, String content, String author) {
this.title = title;
this.content = content;
this.author = author;
}
}
@Entity
• 테이블과 링크될 클래스임을 나타냅니다.
• 기본값으로 클래스의 카멜케이스 이름을 언더스코어 네이밍(_)으로 테이블 이름을 매 칭합니다.
• ex) SalesManager.java > sales_manager table
@Id
• 해당 테이블의 PK 필드를 나타냅니다.
@GeneratedValue
• PK의 생성 규칙을 나타냅니다.
• 스프링 부트 2.0 에서는 GenerationType.IDENTITY 옵션을 추가해야만 auto_ increment가 됩니다.
@Column
• 테이블의 칼럼을 나타내며 굳이 선언하지 않더라도 해당 클래스의 필드는 모두 칼럼 이 됩니다.
• 사용하는 이유는, 기본값 외에 추가로 변경이 필요한 옵션이 있으면 사용합니다.
• 문자열의 경우 VARCHAR(255)가 기본값인데, 사이즈를 500으로 늘리고 싶거나(ex: title), 타입을 TEXT로 변경하고 싶거나(ex: content) 등의 경우에 사용됩니다.
@NoArgsConstructor
• 기본 생성자 자동 추가
• public Posts () {} 와 같은 효과
@Builder
• 해당클래스의빌더패턴클래스를생성
• 생성자 상단에 선언 시 생성자에 포함된 필드만 빌더에 포함
Builder 패턴
JpaRepository 생성
import org.springframework.data.jpa.repository.JpaRepository;
public interface PostsRepository extends JpaRepository<Posts, Long> {
}
- interface 로 생성된다.
- JpaRepository<Entity 클래스, PK 타입>를 상속하면 기본 적인 CRUD 메소드가 자동으로 생성된다.
Repository Test 코드 작성 : save(), findAll() 기능 테스트
package com.example.boilerplate.domain.posts;
import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
@RunWith(SpringRunner.class)
@SpringBootTest
public class PostsRepositoryTest {
@Autowired
PostsRepository postsRepository;
@After
public void cleanup() {
postsRepository.deleteAll();
}
@Test
public void 게시글저장_불러오기() {
//given
String title = "test post";
String content = "test content";
postsRepository.save(Posts.builder()
.title(title)
.content(content)
.author("jojoldu@gmail.com")
.build());
//when
List<Posts> postsList = postsRepository.findAll();
//then
Posts posts = postsList.get(0);
assertThat(posts.getTitle()).isEqualTo(title);
assertThat(posts.getContent()).isEqualTo(content);
}
}
@After
• Junit에서 단위 테스트가 끝날 때마다 수행되는 메소드를 지정
•보통은 배포전 전체테스트를 수행할 때 테스트간 데이터침범을 막기 위해 사용합 니다.
• 여러 테스트가 동시에 수행되면 테스트용 데이터베이스인 H2에 데이터가 그대로 남아있어 다음 테스트 실행시 테스트가 실패할 수 있습니다.
postsRepository.save()
• 테이블 posts에 insert/update 쿼리를 실행합니다.
• id 값이 있다면 update가, 없다면 insert 쿼리가 실행됩니다.
postsRepository.findAll()
• 테이블 posts에 있는 모든 데이터를 조회해오는 메소드입니다.
'WEB > Java' 카테고리의 다른 글
static, final 키워드에 대하여 - ② final 키워드 (0) | 2022.02.12 |
---|---|
static, final 키워드에 대하여 - ① static 키워드 (0) | 2022.02.08 |
스프링 부트와 AWS로 혼자 구현하는 웹 서비스 - 02-2 lombok 적용 (0) | 2022.01.22 |
스프링 부트와 AWS로 혼자 구현하는 웹 서비스 - 02-1 테스트코드 작성 (0) | 2022.01.16 |
스프링 부트와 AWS로 혼자 구현하는 웹 서비스 - 01 gradle 설정 (0) | 2022.01.08 |