제육's 휘발성 코딩
반응형

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

스프링 부트와 JPA를 통해 생산성 높은 웹 애플리케이션을 개발해보자. 도메인 모델 설계, 엔티티 설계, 테이블 설계를 하고 ORM으로 JPA를 매핑하는 과정을 거쳐 핵심 비즈니스 로직을 개발해보자.

프로젝트 생성

image

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 은 다음과 같다.

라이브러리

image

  • 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 환경 설정

image

  • 뷰 렌더링 테스트 페이지
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는 실제 서버를 돌리는 상황처럼 톰캣을 실행해서 테스트를 할 수 있도록 지원해준다.

image

  • 실제 디비에 정상적으로 저장된 것을 볼 수 있다.

스프링 부트를 통해 복잡한 설정이 자동화 되어서 기존의 persistence.xml, LocalContainerEntityManagerFactoryBean 없이 사용 가능하다.

쿼리 파라미터 로그 남기기

application.yml에서 적용한 org.hibernate.type 이 부분을 통해 SQL 로그를 남겨도 파라미터는 ?로 나온다.

implementation 'com.github.gavlyukovskiy:p6spy-spring-boot-starter:1.5.6'

image

  • 다음과 같이 실행 시 로그가 보이는 것을 알 수 있다.

본 포스팅은 인프런 - 김영한님의 '실전! 스프링 부트와 JPA 활용 1'편을 참고하여 정리했습니다.

반응형
profile

제육's 휘발성 코딩

@sasca37

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요! 맞구독은 언제나 환영입니다^^