-
#Spring boot-5 JPA와 DB 설정, 동작확인SPRING-BOOT 2021. 3. 1. 19:04
[출처] 인프런 김영한 강사님 -실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
JPA와 DB 설정, 동작확인
application.properties를 지우고 application.yml을 생성한다.
yml은
main/resources/application.yml
spring: datasource: # MVCC=TRUE 그나마 여러개가 접근했을때 한번에 처리 넣는것을 권장 #주의: H2 데이터베이스의 MVCC 옵션은 H2 1.4.198 버전부터 제거되었습니다. #1.4.200 버전에서는 MVCC 옵션을 사용하면 오류가 발생합니다. url: jdbc:h2:tcp://localhost/~/jpashop username: sa password: driver-class-name: org.h2.Driver # 이렇게까지만 해도 hikariCP를 써서 커넥션 풀이랑 이런게 다 스프링부트가 세팅을 다 걸어줌 jpa: hibernate: ddl-auto: create #자동으로 테이블을 만들어줌. application 실행시점에 내가 가지고 있는 entity정보를 지우고 다시 생성 properties: hibernate: # show_sql: true format_sql: true #이런 속성들은 spring boot 공홈에서 찾아서 공부해야한다. #로그레벨 logging.level: org.hibernate.SQL: debug #jpa나 hibernate가 생성하는 sql로그를 디버그 모드로 쓰겠다. # org.hibernate.type: trace
· spring.jpa.hibernate.ddl-auto: create
· 이 옵션은 애플리케이션 실행 시점에 테이블을 drop 하고, 다시 생성한다.
참고: 모든 로그 출력은 가급적 로거를 통해 남겨야 한다.
show_sql : 옵션은 System.out 에 하이버네이트 실행 SQL을 남긴다.
org.hibernate.SQL : 옵션은 logger를 통해 하이버네이트 실행 SQL을 남긴다.
주의! application.yml 같은 yml 파일은 띄어쓰기(스페이스) 2칸으로 계층을 만듭니다. 따라서 띄어쓰 기 2칸을 필수로 적어주어야 합니다.
예를 들어서 아래의 datasource 는 spring: 하위에 있고 앞에 띄어쓰기 2칸이 있으므로
spring.datasource 가 됩니다. 다음 코드에 주석으로 띄어쓰기를 적어두었습니다.
yml 띄어쓰기 주의
spring: #띄어쓰기 없음 datasource: #띄어쓰기 2칸 url: jdbc:h2:tcp://localhost/~/jpashop #4칸 username: sa password: driver-class-name: org.h2.Driver jpa: #띄어쓰기 2칸 hibernate: #띄어쓰기 4칸 ddl-auto: create #띄어쓰기 6칸 properties: #띄어쓰기 4칸 hibernate: #띄어쓰기 6칸 # show_sql: true #띄어쓰기 8칸 format_sql: true #띄어쓰기 8칸 logging.level: #띄어쓰기 없음 org.hibernate.SQL: debug #띄어쓰기 2칸 # org.hibernate.type: trace #띄어쓰기 2칸
실제 동작하는지 확인하기
@Entity @Getter @Setter public class Member { @Id @GeneratedValue private Long id; private String username; ... }
회원 리포지토리
@Repository public class MemberRepository { @PersistenceContext EntityManager em; public Long save(Member member) { em.persist(member); return member.getId(); } public Member find(Long id) { return em.find(Member.class, id); } }
tdd custom 함수 만들기
방법 1 . live templates
setting -> live Templates -> + new group custom -> new live template 방법 2 자체 Test Method를 Endit Template을 통해서 변경
alt+insert tdd기본 메서드 수정 인프런강의와 동일하게 생성 tdd -> tab
tdd에서 tab을 누르면? 위와같이 custom함수가 생성된다. 테스트
MemberRepositoryTest class
package jpabook.jpashop; import org.assertj.core.api.Assertions; 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.junit.Assert.*; @RunWith(SpringRunner.class) //junit한태 spring 과 관련된걸로 테스트 할거야라는 것을 알려줘야한다. @SpringBootTest// spring boot로 테스트 public class MemberRepositoryTest { @Autowired MemberRepository memberRepository; @Test 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()); } }
위같이 검증할 경우 발생하는 에러이다. 트랜잭션이 없다는 것이다. 모든 entityManager를 통한 변경은 항상 트랜잭션 안에서 이루어져야하기 때문이다.
그래서 트랜잭션 어노테이션을 사용해야하는데
Spring framework에서 제공하는 어노테이션이 있고 javax에서 제공하는 것이 있는데
우리는 spring framework에 종속적으로 설계하기 때문에 @Transactional 스프링 어노테션을 사용하면 된다.
@Transactional 로 정상 test되는 것을 확인 할 수 있다. DB - SELECT * FROM MEMBER;
데이터를 넣었는데도 불과하고 데이터가 없는이유는
@Transactional이 test case에 있으면 테스트가 끝난다음에 rollback을 해버린다.
-> 데이터가 들어가 있으면 반복적인 테스트를 못하기 때문에
일반적으로 TEST가 아닌곳에 있으면 정상적으로 잘동작한다.
개발을 하다보면 Assert만 가지고는 내 테스트를 의심할 수 있다. 그때 사용하는 것이 @Rollback(value=false)이다
@Rollback(value=false) data가 잘들어와있는것을 확인 할 수있다. 저장한거랑 조회한거랑 데이터가 같은지 비교
package jpabook.jpashop; import org.assertj.core.api.Assertions; import org.junit.Assert; 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.annotation.Rollback; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.transaction.annotation.Transactional; import static org.junit.Assert.*; @RunWith(SpringRunner.class) //junit한태 spring 과 관련된걸로 테스트 할거야라는 것을 알려줘야한다. @SpringBootTest// spring boot로 테스트 public class MemberRepositoryTest { @Autowired MemberRepository memberRepository; @Test @Transactional @Rollback(value = 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); //JPA 엔티티 동일성 보자 System.out.println("findMember == member : " + (findMember == member)); //같은 트랜잭션안에서 저장하고 조회하면 영속성컨텍스트가 똑같기때문에 같은 entity로 식별하기때문에 true이다. } }
같은 트랜잭션안에서 저장하고 조회하면 영속성컨텍스트가 똑같다. 이로 인해 같은 entity로 식별하기때문에 true이다.
주의! @Test는 JUnit4를 사용하면 org.junit.Test를 사용하셔야 합니다. 만약 JUnit5 버전을 사용하면 그 것에 맞게 사용하면 된다.
· Entity, Repository 동작 확인
· jar 빌드해서 동작 확인
start gradlew clean build 명령어를 입력하여 깔끔하게 지우고 다시 빌드한다. (그런데 여기서 에러발생)
빌드중 에러 발생 자바 버전이 일치하지 않는다는 에러이다. 이때는 아래의 이미지와 같은 환경설정을 살펴보면 된다.
위와같이 버전을 11로 맞춰주었다.
그리고 빌드 성공시
· 오류: 테스트를 실행했는데 다음과 같이 테스트를 찾을 수 없는 오류가 발생하는 경우
· No tests found for given includes: [jpabook.jpashop.MemberRepositoryTest] (filter.includeTestsMatching)
· 해결: 스프링 부트 2.1.x 버전을 사용하지 않고, 2.2.x 이상 버전을 사용하면 Junit5가 설치된다. 이때는 build.gradle 마지막에 다음 내용을 추가하면 테스트를 인식할 수 있다. Junit5 부터는 build.gradle 에 다음 내용을 추가해야 테스트가 인식된다
build.gradle 마지막에 추가
test { useJUnitPlatform() }
참고: 스프링 부트를 통해 복잡한 설정이 다 자동화 되었다. persistence.xml 도 없 고, LocalContainerEntityManagerFactoryBean 도 없다. 스프링 부트를 통한 추가 설정은 스프링 부트 메뉴얼을 참고하고, 스프링 부트를 사용하지 않고 순수 스프링과 JPA 설정 방법은 자바 ORM 표준 JPA 프 로그래밍 책을 참고하자.
쿼리 파라미터 로그 남기기
· 로그에 다음을 추가하기 org.hibernate.type : SQL 실행 파라미터를 로그로 남긴다.
이런 ??말고 파라미터가 보고싶을때 org.hibernate.type: trace 추가 parameter를 확인 가능하다. · 외부 라이브러리 사용
· https://github.com/gavlyukovskiy/spring-boot-data-source-decorator
스프링 부트를 사용하면 이 라이브러리만 추가하면 된다.
implementation 'com.github.gavlyukovskiy:p6spy-spring-boot-starter:1.5.6'
참고: 쿼리 파라미터를 로그로 남기는 외부 라이브러리는 시스템 자원을 사용하므로, 개발 단계에서는 편하 게 사용해도 된다. 하지만 운영시스템에 적용하려면 꼭 성능테스트를 하고 사용하는 것이 좋다.
build.gradlew에 추가 얘는 버전을 명시 해주는 이유
스프링 부트가 2.1.7부터 나한태 궁합이 맞는 라이브러리들이 뭐야하고 다 세팅을 해놓았다.
스프링부트가 세팅해놓지않은 것은 직접 명시해야줘야한다.
파라미터 바인딩이 출력되는거을 확인할수 있다. 'SPRING-BOOT' 카테고리의 다른 글
#Spring boot-7 애플리케이션 구현 준비 (0) 2021.03.03 #Spring boot-6 도메인 분석 설계 (0) 2021.03.01 #Spring boot-4 H2 데이터베이스 설치 (0) 2021.02.26 #Spring boot-3 View 환경설정 (0) 2021.02.26 #Spring boot-2 라이브러리 살펴보기 (0) 2021.02.26