SpringBoot에서 JPA 사용하기(2) - SpringDataJpa 적용하기

dev_Shawn·2022년 3월 24일
0

SpringBoot

목록 보기
3/15
post-thumbnail

해당 내용은 이동욱님 저서 '스프링 부트와 AWS로 혼자 구현하는 웹 서비스'를 공부하며 정리한 내용입니다.

build.gradle

dependencies{
	compile('org.springframework.boot:spring-boot-starter-web')
	compile('org.projectlombok:lombok')
	compile('org.springframework.boot:spring-boot-starter-data-jpa')
	compile('com.h2database:h2')

	testCompile('org.springframework.boot:spring-boot-starter-test')
}

두개의 디펜던시 추가

  1. org.springframework.boot:spring-boot-starter-data-jpa
    • 스프링 부트용 Spring Data Jpa 추상화 라이브러리
    • 스프링 부트 버전에 맞춰 자동으로 JPA관련 라이브러리들의 버전을 관리
  2. com.h2database:h2
    • 인메모리 관계형 데이터베이스
    • 별도의 설치 필요 없이 의존성만으로 관리가 가능하다.
    • 메모리에서 실행되기 때문에 애플리케이션을 재시작할 때마다 초기화된다.
    • 위 특징을 활용하여 테스트용도로 많이 사용된다.

Posts

import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

import javax.persistence.*;

@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;
	}
}

실제 DB의 테이블과 매칭될 클래스. 주로 Entity 클래스라고 한다.

도메인 : 게시판, 회원, 결제 등 소프트웨어에 대한 요구사항 혹은 문제영역
xml에 쿼리를 담고, 클래스에 쿼리의 결과를 담던 것들이 모두 도메인 클래스에서 해결된다.

@Entity

  • 테이블과 링크될 클래스임을 나타낸다.
  • 기본값으로 클래스의 카멜케이스 이름을 언더스코어 네이밍으로 테이블 이름을 매칭한다.

@Id

  • 해당 테이블의 PK
    • 웬만하면 Entity의 PK는 Long타입 + Auto_increment로 사용

@GeneratedValue(strategy = GenerationType.IDENTITY)

  • PK의 생성 규칙.
  • Spring Boot 2.0에서는 GenerationType.IDENTITY 옵션을 추가해야 auto_increment가 된다.

@Column(length = 500, nullable = false)

  • 테이블의 컬럼을 나타내며, 굳이 선언하지 않더라도 해당 클래스의 필드는 모두 컬럼.
  • 변경이 필요한 옵션이 있을 경우 사용한다. (ex> 문자열 사이즈 변경, 타입 변경 등)

@Builder

  • 해당 클래스의 빌더 패턴 클래스를 생성한다.
  • 생성자 상단에 선언 시 생성자에 포함된 필드만 빌더에 포함한다.

서비스 초기 구축 단계에선 테이블(Entity 클래스) 설계가 빈번하게 변경되는데, 이때 롬복의 어노테이션이 코드 변경량을 최소화시켜준다.

Getter와 Setter를 무작성 생성하지 말자!

  • 무작정 생성하면 해당 클래스의 인스턴스 값들이 언제 어디서 변해야하는지 코드상으로 명확하게 구분이 어려워 추후 기능 변경 시 복잡하다.
  • Entity 클래스에서는 Setter를 만들지 않는다.
  • 값의 변경이 꼭 필요하다면 그 목적과 의도가 분명한 메서드를 생성하여 Setter의 역할을 대신 한다.
    ex) public void setStatus(boolean status){ this.status = status; } (X)
    public void cancleOrder() { this.status = false; } (O)

Setter가 없다면 필드에 값은 어떻게 채울 수 있나?

  • 생성자를 통해 최종값을 채운 후 DB에 삽입
  • 값의 변경이 필요하다면 위에서 말한 대로 해당 이벤트의 목적과 의도가 분명한 public메서드를 호출하여 변경

PostsRepository

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

public interface PostsRepository extends JpaRepository<Posts, Long> {

}

DB Layer 접근자(MyBatis에서 DAO)

  • 인터페이스를 생성 후 JpaRepository<Entity클래스, PK타입>을 implements하면 기본CRUD메서드가 자동으로 생성된다.
  • Entity 클래스와 같은 디렉토리에 있어야 Entity 클래스가 제 기능을 할 수 있다.

PostsRepositoryTest

import com.shawn.springboot.domain.posts.Posts;
import com.shawn.springboot.domain.posts.PostsRepository;
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 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 = "테스트 게시글";
	    	String content = "테스트본문";
	
	      
	      	postsRepository.save(Posts.builder()
										.title(title)
										.content(content)
										.author("shshhan@shawn.com")
										.build());
																
	        //when                      
		    List<Posts>postsList = postsRepository.findAll();

	    	//then
	        Posts posts = postsList.get(0);
			assertThat(posts.getTitle()).isEqualTo(title);
			assertThat(posts.getContent()).isEqualTo(content);
		}																		
	}

@SpringBootTest

  • 자동으로 H2 데이터베이스 실행

@After

  • 단위 테스트가 끝날 때 마다 수행되는 메서드로 지정
  • 주로 배포 전 전체 테스트 수행 중 테스트간 데이터 침범을 막기 위해 사용

@postsRepository.save()

  • 테이블 posts에 id 값이 있으면 update, 없으면 insert 수행

@postsRepository.findAll()

  • 테이블 posts에 있는 모든 데이터를 조회

application.properties

#JPA에서 실행한 SQL 로그 보기/안보기
spring.jpa.show_sql=true

#출력되는 SQL 로그를 MySQL 버전으로 출력
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect

#H2 데이터베이스에 직접 접근하기 위해 웹 콘솔 사용
spring.h2.console.enabled=true
profile
안주는 술 마실 때나

0개의 댓글