실전! 스프링 데이터 JPA 수업을 듣고 정리한 내용입니다.
프로젝트 생성은 수업내용 보기!
✔️ 스프링 부트 라이브러리 살펴보기
spring-boot-starter-web
spring-boot-starter-tomcat
: 톰캣 (웹서버) spring-webmvc
: 스프링 웹 MVCspring-boot-starter-data-jpa
spring-boot-starter-aop
spring-boot-starter-jdbc
HikariCP 커넥션 풀 (부트 2.0 기본)
hibernate + JPA
: 하이버네이트 + JPA spring-data-jpa
: 스프링 데이터 JPAspring-boot-starter(공통)
: 스프링 부트 + 스프링 코어 + 로깅
✔️ 테스트 라이브러리
spring-boot-starter-test
junit
: 테스트 프레임워크, 스프링 부트 2.2부터 junit5( jupiter
) 사용vintage
mockito
: 목 라이브러리assertj
: 테스트 코드를 좀 더 편하게 작성하게 도와주는 라이브러리spring-test
: 스프링 통합 테스트 지원
application.yml
spring:
datasource:
url: jdbc:h2:tcp://localhost//Users/leekyoungchang/Desktop/Study/Computer/Spring/JPA(pdf, ppt)/스프링 데이터 JPA/db/datajpa
username: sa
password: 1234
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
# org.hibernate.type: trace
spring.jpa.hibernate.ddl-auto:create
: 애플리케이션 실행 시점에 테이블을 drop하고, 다시 생성한다.
logging.level:
org.hibernate.SQL: debug
show_sql
: 옵션은 System.out
에 하이버네이트 실행 SQL을 남긴다.org.hibernate.SQL
: 옵션은 logger를 통해 하이버네이트 실행 SQL을 남긴다.
Member - 회원 엔티티
@Entity
@Getter @Setter
public class Member {
@Id
@GeneratedValue
private Long id;
private String username;
protected Member() {
}
public Member(String username) {
this.username = username;
}
}
MemberJpaRepository - 회원 JPA 리포지토리
@Repository
public class MemberJpaRepository {
@PersistenceContext
private EntityManager em;
// 영속성 컨텍스트, 엔티티 매니저
public Member save(Member member) {
em.persist(member);
return member;
}
public Member find(Long id) {
return em.find(Member.class, id);
}
}
MemberJpaRepositoryTest - JPA 기반 테스트
@SpringBootTest
@Transactional
@Rollback(value = false)
class MemberJpaRepositoryTest {
@Autowired MemberJpaRepository memberJpaRepository;
@Test
public void testMember() {
Member member = new Member("memberA");
Member saveMember = memberJpaRepository.save(member);
Member findMember = memberJpaRepository.find(saveMember.getId());
assertThat(findMember.getId()).isEqualTo(member.getId());
assertThat(findMember.getUsername()).isEqualTo(member.getUsername());
assertThat(findMember).isEqualTo(member);
}
}d
실행 결과
MemberRepository - 스프링 데이터 JPA 리포지토리
public interface MemberRepository extends JpaRepository<Member, Long> {
}
JpaRepository<T, ID>
T
: 엔티티 타입ID
: ID 필드 타입id
는 Long
타입이므로 Long
MemberRepositoryTest - 스프링 데이터 JPA 기반 테스트
@SpringBootTest
@Transactional
@Rollback(value = false)
class MemberRepositoryTest {
@Autowired MemberRepository memberRepository;
@Test
public void testMember() {
Member member = new Member("memberA");
Member saveMember = memberRepository.save(member);
Member findMember = memberRepository.findById(saveMember.getId()).get();
assertThat(findMember.getId()).isEqualTo(member.getId());
assertThat(findMember.getUsername()).isEqualTo(member.getUsername());
assertThat(findMember).isEqualTo(member); // JPA 엔티티 동일성
}
}
실행 결과
MemberJpaRepositoryTest
와 거의 동일한 코드로 테스트를 돌려보면 실행이 잘되며, 결과가 같다.
신기하게 MemberRepository
에는 interface
밖에 없는데 잘 실행된다.
MemberJpaRepository
와 MemberRepository
가 거의 동일한 것이라고 보면 된다!
✔️ 쿼리 파라미터 로그 남기기
로그에 org.hibernate.type
을 추가하면 SQL 실행 파라미터를 로그로 남긴다.
외부 라이브러리 : https://github.com/gavlyukovskiy/spring-boot-data-source-decorator를 사용
스프링 부트를 사용하면 이 라이브러리를 추가하면 된다.
implementation 'com.github.gavlyukovskiy:p6spy-spring-boot-starter:1.5.7'
💡 참고
- 쿼리 파라미터를 로그로 남기는 외부 라이브러리는 시스템 자원을 사용하므로, 개발 단계에서는 편하게 사용해도 된다.
- 하지만 운영시스템에 적용하려면 꼭 성능테스트를 하고 사용하는 것이 좋다.