H2 데이터베이스 설치
개발이나 테스트 용도로 가볍고 편리한 DB, 웹 화면 제공
- 다운로드 및 설치
- 스프링 부트 2.x를 사용하면 1.4.200 버전을 다운로드 받으면 된다.
- 스프링 부트 3.x를 사용하면 2.1.214 버전 이상 사용해야 한다.
- 데이터베이스 파일 생성 방법
- jdbc:h2:~/jpashop (최소 한번)
- ~/jpashop.mv.db 파일 생성 확인
- 이후 부터는 jdbc:h2:tcp://localhost/~/jpashop 이렇게 접속
주의: H2 데이터베이스의 MVCC 옵션은 H2 1.4.198 버전부터 제거되었다.
최신 버전에서는 MVCC 옵션을 사용하면 오류가 발생한다.
JPA와 DB 설정
spring:
datasource:
url: jdbc:h2:tcp://localhost/~/jpashop
username: sa
password: sa
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
- properties
- 하이버네이트 관련된 특정한 properties을 사용할 수 있다.
- spring.jpa.hibernate.ddl-auto: create
- 이 옵션은 애플리케이션 실행 시점에 테이블을 drop 하고, 다시 생성한다.
참고: 모든 로그 출력은 가급적 로거를 통해 남겨야 한다
show_sql: 옵션은 System.out 에 하이버네이트 실행 SQL을 남긴다.
org.hibernate.SQL: 옵션은 logger를 통해 하이버네이트 실행 SQL을 남긴다.
로직 & 테스트 코드 팁
public Long save(Member member) {
em.persist(member);
return member.getId();
}
id를 반환하는 이유는 커맨드랑 쿼리를 분리하기 위해서다.
저장을 하면 사이드 이펙트를 일으키는 커맨드성이기 때문에 리턴값을 거의 안 만든다.
대신 id정도 있으면 다음에 다시 조회할 수 있으니까 id 정도만 조회하는 식으로 설계한다.
@SpringBootTest
class MemberRepositoryTest {
@Autowired
MemberRepository memberRepository;
@Test
@Transactional
@Rollback(false)
public void testMember() {
Member member = new Member();
member.setUsername("memberA");
Long savedId = memberRepository.save(member);
Member findMember = memberRepository.find(savedId);
Assertions.assertThat(findMember.getId()).isEqualTo(member.getId());
Assertions.assertThat(findMember.getUsername()).isEqualTo(member.getUsername());
Assertions.assertThat(findMember).isEqualTo(member); //JPA 엔티티 동일성 보장 }
}
}
- @Transactional 이 테스트 케이스에 있으면 테스트가 끝난 다음에 바로 롤백 한다.
- @Rollback(false) 옵션을 넣으면 테스트가 끝나도 롤백을 하지 않고 커밋 한다.
참고: 스프링 부트를 통해 복잡한 설정이 다 자동화되었다.
persistence.xml 도 없고, LocalContainerEntityManagerFactoryBean도 없다.
스프링 부트를 통한 추가 설정은 스프링 부트 매뉴얼을 참고하고, 스프링 부트를 사용하지 않고 순수 스프링과 JPA 설정 방법은 자바 ORM 표준 JPA 프로그래밍 책을 참고하자.
쿼리 파라미터 로그 남기기
Hibernate:
insert
into
member
(username, id)
values
(?, ?)
- org.hibernate.type: trace #스프링 부트 2.x, hibernate5
- org.hibernate.orhttp://m.jdbc.bind: trace #스프링 부트 3.x, hibernate6
위 옵션을 넣으면 ?에 실제 어떤 값이 들어가는지 아래와 같이 로그를 찍어준다.
2024-08-20T10:23:17.142+09:00 TRACE 3606 --- [ Test worker] org.hibernate.orm.jdbc.bind : binding parameter (1:VARCHAR) <- [memberA]
2024-08-20T10:23:17.142+09:00 TRACE 3606 --- [ Test worker] org.hibernate.orm.jdbc.bind : binding parameter (2:BIGINT) <- [1]
쿼리 파라미터 로그 남기기 - 스프링 부트 3.0
스프링 부트 3.0 이상을 사용하면 라이브러리 버전을 1.9.0 이상을 사용해야 한다.
implementation 'com.github.gavlyukovskiy:p6spy-spring-boot-starter:1.9.0'
위 옵션을 넣으면 아래와 같이 출력이 나온다.
2024-08-20T10:31:28.621+09:00 INFO 3682 --- [ Test worker] p6spy : #1724117488621 | took 0ms | statement | connection 3| url jdbc:h2:tcp://localhost/~/jpashop
insert into member (username,id) values (?,?)
insert into member (username,id) values ('memberA',1);
2024-08-20T10:31:28.622+09:00 INFO 3682 --- [ Test worker] p6spy : #1724117488622 | took 0ms | commit | connection 3| url jdbc:h2:tcp://localhost/~/jpashop
첫 번째는 원본이 출력되고 두 번째는 파라미터 바인딩이 출력된다.
참고: 쿼리 파라미터를 로그로 남기는 외부 라이브러리는 시스템 자원을 사용하므로, 개발 단계에서는 편하게 사용해도 된다.
하지만 운영시스템에 적용하려면 꼭 성능테스트를 하고 사용하는 것이 좋다.
'JPA > JPA 활용 1' 카테고리의 다른 글
7. 웹 계층 개발 (0) | 2024.08.22 |
---|---|
6. 주문 도메인 개발 (0) | 2024.08.21 |
5. 상품 도메인 개발 (0) | 2024.08.20 |
4. 회원 도메인 개발 (0) | 2024.08.20 |
2. 도메인 분석 설계 (0) | 2024.08.20 |