Back-End/스프링부트와 AWS로 구현하는 웹서비스

[스프링][Spring] - 4. 스프링부트와 JPA

얄루몬 2022. 1. 30. 16:47

1. 프로젝트에 spring Data JPA 적용하기

package com.yeomyaloo.book.springboot.domain.posts;


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

import javax.persistence.*;

//클래스 내의 모든 필드의 Getter 메소드를 자동 생성
@Getter

//public Posts()와 같은 효과
@NoArgsConstructor

//테이블과 링크될 클래스임을 나타낸다.
@Entity
public class Posts {
    
    //해당 테이블의 PK 필드를 나타낸다. Primary key
    @Id
    //PK 생성규칙을 나타낸다.
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    //칼럼 선언이 없어도 해당 클래스의 필드는 모두 칼럼이 된다.
    @Column(length = 500, nullable = false)
    private String title;

    @Column(columnDefinition = "TEXT", nullable = false)
    private String author;

    
    //해당 클래스의 빌더 패턴 클래스를 생성. 
    //생성자 상단에 선언 시 생성자에 포함된 필드만 빌더에 포함
    @Builder
    public Posts(Long id, String title, String author) {
        this.id = id;
        this.title = title;
        this.author = author;
    }
}

 

[참고]
웬만하면 Entity의 PK는 Long타입의 Auto.increment를 추천한다.
조합이 복잡한 키로 PK를 잡으면 난감한 상황이 발생할 수 있기 때문이다. 

 

 

 

2. Setter 메소드가 없을 때 값 변경

 

[잘못된 사용 예]

public class Order{
    public void setStatus(Boolean status) {
        this.status = status;
    }
}
public void 주문서비스의_취소이벤드(){
    order.setStatus(false);
}

 

[올바른 사용 예]

public class Order{
    public void cansleOrder() {
        this.status = false;
    }
}
public void 주문서비스의_취소이벤드(){
    order.cansleOrder();
}

 

[설명]

setter가 없는 상황에서 DB에 값을 넣기 위해서는?

  • 생성자를 통해 최종값을 채운 뒤 DB에 삽입하는 방법으로 진행해야 한다.
  • 값 변경이 필요하다면 해당 이벤트에 맞는 public 메소드를 호출하여 변경하는 것을 전제로 합니다.

 

[Builder 패턴의 사용]

  • 어느 필드에 어떤 값을 넣어야 할지 명확하게 해주기에 빌더 패턴을 적극 활용해서 진행할 예정

 

 

 

3. spring Data JpaRepository

package com.yeomyaloo.book.springboot.domain.posts;

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


//Posts 클래스로 데이터베이스를 접근하게 해줄 JpaRepository를 생성
public interface PostsRepository extends JpaRepository<Posts,Long> {
    
  
    

}
  •  단순 인터페이스르 생성 후 JpaRepository를 상속 받아주면 기본적인 CURD 메소드가 자동으로 생성된다.
  • 스프링에서 Repository라고 불리는 이것은 아이베티, MyBatis에서는 DB Layer 접근자입니다.

[디렉토리 현황]

 

 

 

 

4. spring Data JPA 테스트 코드 작성하기

package com.yeomyaloo.book.springboot.web.domain.posts;

import com.yeomyaloo.book.springboot.domain.posts.Posts;
import com.yeomyaloo.book.springboot.domain.posts.PostsRepository;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit.jupiter.SpringExtension;

import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;


@ExtendWith(SpringExtension.class)
@SpringBootTest
public class PostsRepositoryTest {

    @Autowired
    PostsRepository postsRepository;


    //단위 테스트가 끝날 때마다 수행되는 메소드를 지정.
    // 매 테스트가 끝날 때마다 모두 지우는 작업을 해준다는 의미
    @AfterEach
    public void cleanup(){
        postsRepository.deleteAll();
    }

    @Test
    public void 게시글저장_불러오기(){

        //given
        String title = "테스트 게시글";
        String content = "테스트 본문";

        //테아블 posts에 insert/update 쿼리를 실행한다.
        postsRepository.save(Posts.builder()
                        .title(title)
                        .author("yeomyaloo@naver.com")
                        .content(content)
                        .build());

        //when
        //테이블 posts에 있는 모든 데이터를 조회해오는 메소드
        List<Posts> postsList = postsRepository.findAll();

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


    }

}
  • 이때 실제로 실행된 쿼리의 형태를 보고 싶다면?

 

[쿼리의 형태를 보고 싶다면 아래와 같이 설정해주세요.]

spring.jpa.show_sql = true

 

  • 이렇게 설정해주었다면 콘솔창에서 쿼리의 형태를 확인할 수 있습니다.

 

 

[MySQL 버전으로 쿼리 로그를 출력해보자]

spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL57Dialect
spring.jpa.properties.hibernate.dialect.storage_engine=innodb
spring.datasource.hikari.jdbc-url=jdbc:h2:mem:testdb;MODE=MYSQL
spring.datasource.hikari.username=sa
  • 위에서 살펴 본바와 같이 어플리케이션 프로퍼티의 위의 문장을 입력해주면 기존 H2 쿼리 문법으로 나오던 로그를 MySQL 버전으로 바꿔서 출력시킬 수 있다.

 

 

 

5. 출처

📖본 포스팅은 '스프링부트와 aws로 혼자 구현하는 웹서비스 - 이동욱 저자'를 보고 포스팅 되었습니다.