스프링 부트와 JPA 활용1 - 프로젝트 환경설정 6

JOY·2022년 3월 3일
0
post-thumbnail

📌 스프링 부트와 JPA 활용1 - 프로젝트 환경설정 6

인프런 - 스프링 부트와 JPA 활용1 by 김영한 을 기반으로 작성된 글입니다.
실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발


프로젝트 환경설정 목차

1. 프로젝트 생성

2. 라이브러리 살펴보기

3. View 환경설정

4. H2 데이터베이스 설치

5. JPA와 DB 설정, 동작 확인


프로젝트 환경설정

5. JPA와 DB 설정, 동작 확인

h2데이터베이스 서버모드로 실행해두기
JDBC URL : jdbc:h2:tcp://localhost/~/jpashop

resources>application.yml 파일 생성
resources>application.properties 삭제

1) application.yml (띄어쓰기 주의!)

yml 파일은 띄어쓰기(스페이스) 2칸으로 계층 만든다.
💻 코드

spring:
  datasource:
    url: jdbc:h2:tcp://localhost/~/jpashop
    username: sa
    password:
    driver-class-name: org.h2.Driver

  jpa:
    hibernate:
      ddl-auto: create
    properties:
      hibernate:
#        show_sql: true
        format_sql: true

logging:
  level:
    org.hibernate.SQL: debug
  • ddl-auto: create
    : 애플리케이션 실행시점에 가지고 있던 테이블을 drop 후 다시 create
  • show_sql : hibernate가 생성한 실행 SQL을 system.out에 출력
  • org.hibernate.SQL : hibernate가 생성한 실행 SQL을 logger에 출력
  • org.hibernate.SQL: debug
    : hibernate가 남기는 모든 로그는 debug 모드

2) 실제 동작 확인

💻 코드

  • 회원 엔티티 Member.java
@Entity
@Getter @Setter
public class Member {

    @Id @GeneratedValue
    private Long id;
    private String username;
  • 회원 리포지토리 MemberRepository.java
@Repository
public class MemberRepository {

    @PersistenceContext //엔티티 매니저
    private EntityManager em;

    public Long save(Member member){
        em.persist(member);
        return member.getId();
    }

    public Member find(Long id){
        return em.find(Member.class, id);
    }


}
  • 테스트하기 MemberRepositoryTest.java
    JUnit5 버전 사용
    단축키 : Ctrl + Shift + T

테스트
💻 초기 코드

package jpabook.jpashop;

import org.junit.Test;
import org.assertj.core.api.Assertions;
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.junit.jupiter.api.Assertions.*;

//SpringBoot로 Test
//RunWith : JUnit한테 Spring 과 관련해서 테스트 할것 이라고 알려줌
@RunWith(SpringRunner.class)
@SpringBootTest
public class MemberRepositoryTest {

    //@Autowired를 통해 MemberRepository 인젝션 받음
    @Autowired MemberRepository memberRepository;

    @Test
    public void testMember() throws Exception{
        //given
        Member member = new Member();
        member.setUsername("memberA");

        //when
        //Ctrl + Alt + V : 변수 자동 생성 단축키
        Long saveId = memberRepository.save(member);
        //save 한 것 이 잘 저장되었는지 확인
        Member findMember = memberRepository.find(saveId);

        //then
        //검증
        Assertions.assertThat(findMember.getId()).isEqualTo(member.getId());
        Assertions.assertThat(findMember.getUsername()).isEqualTo(member.getUsername());
    }
}

실행 1 👉 ❗ 에러

org.springframework.dao.InvalidDataAccessApiUsageException: No EntityManager with actual transaction available for current thread

❗ 해결
엔티티 매니저를 통한 모든 데이터 변경은 항상 transaction 안에서 이루어져야 한다.
테스트1 코드에 @Transactional 어노테이션 추가

실행 2 👉 성공
localhost:8082

member 테이블 만들어진것을 확인

그러나 왜 데이터가 없지?
👉 @Transactional 어노테이션이 테스트케이스에 있으면
테스트 종료 후 rollback하기 때문에 데이터를 확인할 수 없다.

이럴때는@Rollback(false) 어노테이션 추가 후 재실행!

insert 문 추가된 것 확인 후 h2 데이터베이스 실행 확인 데이터가 정상적으로 들어와있다! ( rollback 이 아닌 commit )
  • findMember와 member가 같은 entity 인지 확인하기
 Assertions.assertThat(findMember).isEqualTo(member);

JPA는 같은 영속성 콘텐츠 안에서 식별자가 같으면 같은 entity로 인식한다.

💻 최종 코드

package jpabook.jpashop;
//(생략)

@RunWith(SpringRunner.class)
@SpringBootTest
public class MemberRepositoryTest {
    @Autowired MemberRepository memberRepository;

    @Test
    @Transactional
    @Rollback(false)
    public void testMember() throws Exception{
        //given
        Member member = new Member();
        member.setUsername("memberA");

        //when
        Long saveId = memberRepository.save(member);
        Member findMember = memberRepository.find(saveId);

        //then
        Assertions.assertThat(findMember.getId()).isEqualTo(member.getId());
        Assertions.assertThat(findMember.getUsername()).isEqualTo(member.getUsername());
        Assertions.assertThat(findMember).isEqualTo(member);
    }
}

3) 쿼리 파라미터 로그 남기기

application.yml에 org.hibernate.type: trace 추가하기

logging:
  level:
    org.hibernate.type: trace
파라미터 값 확인 가능!

그러나 쿼리문에는 따로 나오지 않아서 확인하고 싶다면 외부라이브러리 활용하기
https://github.com/gavlyukovskiy/spring-boot-data-source-decorator

build.gradles 의 dependencies 에
implementation 'com.github.gavlyukovskiy:p6spy-spring-boot-starter:1.5.6'
코드 추가

제대로 실행되는 것을 확인! 😊
profile
Just Do IT ------- 🏃‍♀️

0개의 댓글