스프링부트 JPA 웹 앱 구축 - JPA와 DB 설정과 동작

agugu95·2020년 7월 29일
0

목표

  • 실전! 스프링 부트와 JPA를 활용한 웹 애플리케이션 구축 1을 공부하며 기록
  • 도메인 주도 설계를 통한 스프링 starter 웹 앱을 구성

H2 DB와 JPA 연결

spring: // 스프링과 연결 될 DB 설정
      datasource: 
        url: jdbc:h2:tcp://localhost/~/jpashop
        username: sa
  	password:
  	driver-class-name: org.h2.Driver
jpa: // JPA 설정
  hibernate: // 하이버네이트 구현체
    ddl-auto: create 
  properties: // 하이버네이트 프로퍼티(설정)
    hibernate:
#      show_sql: true 
      format_sql: true
    logging.level:
      org.hibernate.SQL: debug
      org.hibernate.type: trace
  • 스프링부트 구동 시 DB나 JPA를 찾을 수 있게 하려면 application 파일에 작성 필요
  • properties 방식과 yml 방식이 있음
  • yml 방식은 2칸 기준으로 뎁스를 결정, 아주아주 유의해야 함

키워드

  • datasource
    스프링이 JDBC를 통해 DB 드라이버와 연결되기 위해선 데이터 소스 빈을 통해 DB에 대한 참조를 주입 받아야 함.
    결론적으로 JDBC에 대한 DB 참조를 받는 연결 팩토리, DB Connection과 설정 정보를 담고 있으며 이를 빈으로 등록하여 넘겨줌
    스프링은 이를 통해 DB 연결 획득, 스프링부트는 starter 모듈을 통해서 설정을 도와줄 뿐 근본은 스프링임
  • show_sql
    sysout을 통해 로깅, 이거보다는 로거를 통해 디버그 태깅이 가능한 org.hibernate.SQL을 많이 사용

JUnit 테스팅

실습 중 해결한 에러(?)

file:///Users/lagoon/Documents/%EB%B2%A4%EC%B2%98/learnWebApp/jpashop/build/reports/tests/test/index.html

JUnit의 역할인지 확실하지 않은데 에러 발생 시 index.html 파일로 에러 로그를 만들어 준다.
에러 로그를 각 클래스 별로 확인 가능한데 쭉 확인하다보니 잘 모르겠지만 눈에 띈게

Access to DialectResolutionInfo cannot be null when 'hibernate.dialect' not set

이 에러는

  • DB 커넥팅이 제대로 되지 않는 경우
  • application 파일에서 DB를 로드하지 못한 경우, 혹은 찾지 못한 경우

같은 상황에서 뜬다고 하니 바로 DB 연결부터 확인 했더니 접속이 안됨
DB 서버가 끊겨있어서 발생한 에러였음, DB 서버 다시 연결하니 해결

하이버네이트 동작 확인

2020-07-30 15:20:46.894 DEBUG 26551 --- [    Test worker] org.hibernate.SQL                        : 
    
    drop table member if exists
2020-07-30 15:20:46.898 DEBUG 26551 --- [    Test worker] org.hibernate.SQL                        : 
    
    drop sequence if exists hibernate_sequence
2020-07-30 15:20:46.902 DEBUG 26551 --- [    Test worker] org.hibernate.SQL                        : create sequence hibernate_sequence start with 1 increment by 1
2020-07-30 15:20:46.903 DEBUG 26551 --- [    Test worker] org.hibernate.SQL                        : 
    
    create table member (
       id bigint not null,
        username varchar(255),
        primary key (id)
    )
  • 하이버네이트 설정을 ddl-auto:create로 했기때문에 중복되는 테이블을 drop하고 새 테이블 생성
  • 하이버네이트가 SQL을 만들어줬음, 원본의 멤버 클래스는 아래와 같음
@Entity
@Getter @Setter
public class Member {
    @Id @GeneratedValue
    private Long id;
    private String username;
}
2020-07-30 15:28:30.977 DEBUG 26583 --- [    Test worker] org.hibernate.SQL                        : 
    insert 
    into
        member
        (username, id) 
    values
        (?, ?)
2020-07-30 15:28:30.979 TRACE 26583 --- [    Test worker] o.h.type.descriptor.sql.BasicBinder      : binding parameter [1] as [VARCHAR] - [memberA]
2020-07-30 15:28:30.980 TRACE 26583 --- [    Test worker] o.h.type.descriptor.sql.BasicBinder      : binding parameter [2] as [BIGINT] - [1]
  • 데이터 insert query

엔티티 동일성

member.setUsername("memberA");

Member findMember = memberRepository.find(savedId);

Assertions.assertThat(findMember).isEqualTo(member);
  • 조회가 이루어진 멤버와, 만들어진 멤버는 같을까?
  • JPA 표준 프로그래밍을 봐서 바로 알 수 있었음
    둘은 같음, 실제로 쿼리도 insert query 한번만 생성 됨
2020-07-30 15:38:45.080 DEBUG 26605 --- [    Test worker] org.hibernate.SQL                        : 
    insert 
    into
        member
        (username, id) 
    values
        (?, ?)
  • 이미 식별자가 주어진 엔티티는 영속성 컨텍스에 속하기 때문에 1차 캐시에 저장 됨
    동일 트랜잭션 내 동일한 내용이라면 1차 캐시에서 데이터를 가져오기 때문에 조회 쿼리도 필요없음

jar 파일 배포 실행

  • ./gradlew clean build
staff    37M  7 30 15:46 jpashop-0.0.1-SNAPSHOT.jar

jar 파일 잘 만들어지고 잘 실행 됨

쿼리 파라미터 로그 남기기

SQL 쿼리는 기본적으로 <?>로 뜸, 쿼리가 제대로 날아갔는지 남기기

    values
        (?, ?)
2020-07-31 18:56:08.365 TRACE 28160 --- [    Test worker] o.h.type.descriptor.sql.BasicBinder      : binding parameter [1] as [VARCHAR] - [memberA]
2020-07-31 18:56:08.366 TRACE 28160 --- [    Test worker] o.h.type.descriptor.sql.BasicBinder      : binding parameter [2] as [BIGINT] - [1]
  • 하이버네이트가 제공하는 트레이스 로그

2020-07-31 18:56:08.366  INFO 28160 --- [    Test worker] p6spy                                    : #1596189368366 | took 0ms | statement | connection 4| url jdbc:h2:tcp://localhost/~/jpashop
insert into member (username, id) values (?, ?)
insert into member (username, id) values ('memberA', 1);
  • p6spy가 제공하는 쿼리 파라미터 로그

0개의 댓글