백엔드/JPA

[JPA 활용1] [1] 프로젝트 환경설정

RE-Heat 2023. 8. 19. 20:42

https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8-JPA-%ED%99%9C%EC%9A%A9-1/

 

실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발 - 인프런 | 강의

실무에 가까운 예제로, 스프링 부트와 JPA를 활용해서 웹 애플리케이션을 설계하고 개발합니다. 이 과정을 통해 스프링 부트와 JPA를 실무에서 어떻게 활용해야 하는지 이해할 수 있습니다., 스프

www.inflearn.com

인프런 김영한 님의 강의를 듣고 작성한 글입니다.

 

[1] 프로젝트 설정

https://start.spring.io/ 에서 프로젝트 생성

  • xml파일이 아닌 gradle로 세팅하기로 함

 

build.gradle

plugins {
   id 'java'
   id 'org.springframework.boot' version '2.7.14'
   id 'io.spring.dependency-management' version '1.0.15.RELEASE'
}

group = 'jpabook'
version = '0.0.1-SNAPSHOT'

java {
   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-web'

   testImplementation 'junit:junit:4.13.1'

   compileOnly 'org.projectlombok:lombok'
   runtimeOnly 'com.h2database:h2'
   annotationProcessor 'org.projectlombok:lombok'
   testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

tasks.named('test') {
   useJUnitPlatform()
}

 

애노테이션 활용을 위해 Enable하는 걸 잊지 말자

 

Whitelabel Error Page가 뜨면 기본 세팅은 성공

 

[2] 라이브러리 살펴보기

■ 의존관계 살펴보기

./gradlew dependencies —configuration compileClasspath

 

■ IntelliJ로 살펴보기

gradle에서 살펴볼 수 있다.

 

■ 스프링부트 라이브러리

  • spring-boot-starter-web
    • spring-boot-starter-tomcat: 톰캣 (웹서버)
    • spring-webmvc: 스프링 웹 MVC
  • spring-boot-starter-thymeleaf: 타임리프 템플릿 엔진(View)
  • spring-boot-starter-data-jpa
    • spring-boot-starter-aop
    • spring-boot-starter-jdbc
      • HikariCP 커넥션 풀 (부트 2.0 기본)
    • hibernate + JPA: 하이버네이트 + JPA
    • spring-data-jpa: 스프링 데이터 JPA
  • spring-boot-starter(공통): 스프링 부트 + 스프링 코어 + 로깅
    • spring-boot
      • spring-core
    • spring-boot-starter-logging
      • logback, slf4j

■ 테스트 라이브러리

  • spring-boot-starter-test
    • junit: 테스트 프레임워크
    • mockito: 목 라이브러리
    • assertj: 테스트 코드를 좀 더 편하게 작성하게 도와주는 라이브러리
    • spring-test: 스프링 통합 테스트 지원

 

■ 핵심 라이브러리

  • 스프링 MVC
  • 스프링 ORM
  • JPA, 하이버네이트
  • 스프링 데이터 JPA

■ 기타 라이브러리

  • H2 데이터베이스 클라이언트
  • 커넥션 풀: 부트 기본은 HikariCP
  • WEB(thymeleaf)
  • 로깅 SLF4J & LogBack
  • 테스트

 

[3] View 환경 설정

 

■ thymeleaf 템플릿 엔진 사용

 

타임리프는 마크업 상태를 깨지 않는다는 게 장점

자세한 내용은 밑에 링크 확인

스프링 MVC 2편 - [1] 타임리프 - 기본기능(상편)
스프링 MVC 2편 - [1] 타임리프 - 기본기능(하편)

 

■ 세팅

HelloController

 

@Controller
public class HelloController {

    @GetMapping("hello")
    public String hello(Model model){
        model.addAttribute("data", "hello!");
        return "hello";
    }
}

 

templates/hello.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Hello</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
</head>
<body>
<p th:text="'안녕하세요. ' + ${data}">안녕하세요. 손님</p>
</body>
</html>

 

▶ devtools를 쓰면 서버를 재시작하지 않고 변경 내역을 확인할 수 있다.

방법 1] build.gradle에 devtools 디펜던시 추가

implementation 'org.springframework.boot:spring-boot-devtools'

방법 2] build에 Recomplile 사용

방법 3] 확인

서버를 껐다 켰다하지 않아도 바로 확인 가능

 

 

[4] H2 데이터베이스 설치

 

H2 데이터베이스 버전은 강의에 맞게 1.4.199 버전을 사용했다.

  • 최초 접속 시 jdbc:h2:~/jpashop후 루트 폴더에 ~/jpashop.mv.db 파일 생성 확인
  • 이후 접속 시 jdbc:h2:tcp://localhost/~/jpashop

윈도우는 설치 파일경로로 들어가 bin/h2.bat를 실행해야 한다.

 

application.yaml

MVCC=TRUE를 쓰니 오류가 발생함.

이유 : H2 데이터베이스의 MVCC 옵션은 H2 1.4.198 버전부터 제거되었습니다. 1.4.200 버전에서는 
MVCC 옵션을 사용하면 오류가 발생합니다.

 

 

[5] JPA와 DB 설정, 동작 확인

application.yaml

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 #스프링 부트 2.x, hibernate5
#  org.hibernate.orm.jdbc.bind: trace #스프링 부트 3.x, hibernate6

① ddl-auto

② show_sql vs org.hibernate.type

  • show_sql은 system.out에 하이버네이트 실행 SQL을 남긴다.
  • org.hibernate.type은 logger로 하이버네이트 실행 SQL을 남긴다.(개발자는 logger)

Member

@Entity
@Getter
@Setter
public class Member {
    @Id @GeneratedValue
    private Long id;
    private String username;

}

 

MemberRespository (DAO와 비슷)

@Repository
public class MemberRepository {

    @PersistenceContext
    private EntityManager em;

    public Long save(Member member){
        em.persist(member);
        return member.getId();
    }

    public Member find(Long id){
        return em.find(Member.class, id);
    }
}
  • @PersistenceContext를 쓰면 스프링부트가 EntityManager를 자동으로 생성해 준다.
  • save와 find만 구현

 

MemberRepositoryTest

@RunWith(SpringRunner.class)
@SpringBootTest
public class MemberRepositoryTest {
    @Autowired
    MemberRepository memberRepository;

    @Test
    @Transactional
    @Rollback(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);

        System.out.println("findMember == member" + (findMember == member));
    }
}
  • @Transactional을 사용해야 실제 DB에 접근할 수 있다. 
  • @Rollback(false)로 rollback을 막는다.
    • @Transactional이 테스트에 있으면 테스트 종료 후 rollback하기 때문에 이를 막는 설정을 해야 한다.
  • @RunWith : JUnit5로 넘어오면서 @ExtendWith로 변환됨. @SpringBootTest를 쓰면 이미 적용돼 있어 생략 가능
  • assertThat(findMember).isEqualTo(member);
    • 1차 캐시를 통해 영속성 엔티티의 동일성 보장. 영속성 컨텍스트 안에 식별자가 같으면 같은 Entity로 인식

 

참고] 테스트 코드 만드는 단축키 : ctrl + shift + T

참고 2] 스프링부트를 통해 복잡한 설정이 다 자동화되었다. persistence.xml도 없고, LocalContainerEntityManagerFactoryBean도 없다.

 

■ jar 빌드해서 동작 확인

① ./gradlew clean build로 build clean

 

② build/libs로 이동  

③ java -jar jpashop-0.0.1-SNAPSHOT.jar로 실행

 

■ 쿼리 파라미터 로그 남기기

① application.yml에 org.hibernate.type: trace 추가하기

 

② 외부 라이브러리 활용

build.gradle의 dependencies에 implementation 'com.github.gavlyukovskiy:p6spy-spring-boot-starter:1.5.6' 추가

이 라이브러리는 개발 단계에선 편하게 사용해도 되지만, 운영시스템에 적용하려면 꼭 성능테스트를 하고 사용하는 게 좋다.