반응형
JPA 활용 1 - 프로젝트 환경 설정
스프링 부트와 JPA를 통해 생산성 높은 웹 애플리케이션을 개발해보자. 도메인 모델 설계, 엔티티 설계, 테이블 설계를 하고 ORM으로 JPA를 매핑하는 과정을 거쳐 핵심 비즈니스 로직을 개발해보자.
프로젝트 생성
- https://start.spring.io/ 에서 프로젝트 생성
plugins {
id 'org.springframework.boot' version '2.6.6'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'java'
}
group = 'jpabook'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
runtimeOnly 'com.h2database:h2'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
tasks.named('test') {
useJUnitPlatform()
}
- build.gradle 은 다음과 같다.
라이브러리
- IDE 에서 Gradle 라이브러리 정보를 볼 수 있다.
spring-boot-starter-web
- 톰캣, 스프링 웹 MVC 등 지원
spring-boot-starter-thymeleaf
- 뷰 단을 SSR로 제공하는 타임리프 템플릿 엔진
Spring-boot-starter-data-jpa
- aop, jdbc (HikariCP 커넥션 풀), 하이버네이트 , 스프링 데이터 jpa 등 지원
spring-boot-starter(공통)
- 스프링 부트 + 스프링 코어 + 로깅 등 지원
테스트 라이브러리
- spring-boot-starter-test
- junit, mockito, assertj, spring-test
핵심 라이브러리
- 스프링 MVC
- 스프링 ORM
- JPA, 하이버네이트
- 스프링 데이터 JPA
기타 라이브러리
- H2 데이터베이스 클라이언트
- 커넥션 풀 : 기본은 HikariCP
- WEB (thymeleaf)
- 로깅 SL4FJ & LogBack
- 테스트
View 환경 설정
- 뷰 렌더링 테스트 페이지
package jpabook.jpashop;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class HelloController {
@GetMapping("hello")
public String hello(Model model) {
model.addAttribute("data", "hello!");
return "hello";
}
}
- 뷰 화면 테스트를 위한 컨트롤러 생성
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Hello</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<p th:text="'안녕하세요. ' + ${data}" >안녕하세요. 손님</p>
</body>
</html>
- Thymeleaf 템플릿엔진 방식으로 적용, 템플릿 엔진은 기본적으로
resources/templates
가 기본 경로이다.
H2 데이터베이스 설치
H2 데이터베이스 버전은 1.4.200을 사용했다. 맥환경에서는 설치 후 bin 폴더에서 ./h2.sh
를 통해 실행
https://sasca37.tistory.com/13?category=1218302 를 참고하자.
- 최초 접속시
jdbc:h2:~/jpashop
후 루트 폴더에~/jpashop.mv.db
파일 생성 확인 - 이후 접속시
jdbc:h2:tcp://localhost/~/jpashop
JPA와 DB 설정
프로젝트 설정
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
# org.hibernate.type: trace
- application.yml 파일에 DB 접속 정보 설정
- spring.jpa.hibernate.ddl-auto :create
- 애플리케이션 실행 시점에 테이블을 drop하고 다시 생성
show_sql 옵션은 System.out에 하이버네이트 실행 SQL을 남기고, org.hibernate.SQL 은 logger를 통해 하이버네이트 실행 SQL을 남긴다. 자세한 내용은 스프링 부트 메뉴얼을 참고하자.
yml파일은 띄어쓰기 2칸으로 계층을 만든다.
회원 엔티티
package jpabook.jpashop;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
@Getter @Setter
public class Member {
@Id @GeneratedValue
private Long id;
private String username;
}
회원 리포지토리
package jpabook.jpashop;
import org.springframework.stereotype.Repository;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
@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);
}
}
- 스프링 부트 starter-jpa가 em을 자동 생성해줘서
@PersistenceContext
을 통해 가져다 쓰면 된다.
테스트
package jpabook.jpashop;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.annotation.Rollback;
import org.springframework.transaction.annotation.Transactional;
import static org.assertj.core.api.Assertions.*;
@SpringBootTest
class MemberRepositoryTest {
@Autowired MemberRepository memberRepository;
@Test
@Transactional
@Rollback(value = false)
public void testMember() {
// given
Member member = new Member();
member.setUsername("memberA");
// when
Long savedId = memberRepository.save(member);
Member findMember = memberRepository.find(savedId);
// then
assertThat(findMember.getId()).isEqualTo(member.getId());
assertThat(findMember.getUsername()).isEqualTo(member.getUsername());
assertThat(findMember).isEqualTo(member);
}
}
@Transactional
을 사용해야 실제 디비에 접근할 수 있다. 테스트 동작 하면서 커밋, 끝나면서 롤백시켜준다. 롤백을 하고 싶지 않다면@Rollback(false)
로 설정할 수 있다.@SprinBootTest
는 실제 서버를 돌리는 상황처럼 톰캣을 실행해서 테스트를 할 수 있도록 지원해준다.
- 실제 디비에 정상적으로 저장된 것을 볼 수 있다.
스프링 부트를 통해 복잡한 설정이 자동화 되어서 기존의 persistence.xml, LocalContainerEntityManagerFactoryBean 없이 사용 가능하다.
쿼리 파라미터 로그 남기기
application.yml
에서 적용한 org.hibernate.type
이 부분을 통해 SQL 로그를 남겨도 파라미터는 ?
로 나온다.
implementation 'com.github.gavlyukovskiy:p6spy-spring-boot-starter:1.5.6'
- 다음 라이브러리를 추가하면 파라미터로 들어오는
?
도 로그에 같이 보여준다. 자세한 정보는 https://github.com/gavlyukovskiy/spring-boot-data-source-decorator 를 참고하자.
- 다음과 같이 실행 시 로그가 보이는 것을 알 수 있다.
본 포스팅은 인프런 - 김영한님의 '실전! 스프링 부트와 JPA 활용 1'편을 참고하여 정리했습니다.
반응형