프로젝트 환경설정

프로젝트 생성

https://start.spring.io/

image
image


Lombok 테스트 해보기

Hello.java


package jpabook.jpashop;

import lombok.Getter;
import lombok.Setter;

@Getter @Setter
public class Hello {
    private String data;
}

JpashopApplication.java


package jpabook.jpashop;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class JpashopApplication {

    public static void main(String[] args) {
        // Hello 객체 생성하기
        Hello hello = new Hello();
        hello.setData("hello");
        String data = hello.getData();
        System.out.println("data = " + data);

        SpringApplication.run(JpashopApplication.class, args);
    }
}
  • 실행결과
    image

라이브러리 살펴보기

image


View 환경 설정

  • thymeleaf 템플릿 엔진: https://www.thymeleaf.org/
  • 스프링 공식 튜토리얼: https://spring.io/guides/gs/serving-web-content
  • 스프링 부트 매뉴얼: https://docs.spring.io/spring-boot/reference/web/servlet.html#web.servlet.spring-mvc.template-engines

HelloController.java


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";
    }
}

hello.html


<!DOCTYPE HTML>


  Hello
  


  

안녕하세요. 손님

  • 실행결과
    image

H2 데이터베이스 설치

다운로드 및 설치: https://www.h2database.com/html/main.html

image
image

생성된 것을 확인했으면 아래와 같이 접속한다:
jdbc:h2:tcp://localhost/~/jpashop

image


JPA와 DB 설정, 동작확인

application.properties 삭제 후 application.yml 생성


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

Member.java


package jpabook.jpashop;

import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;

@Entity
public class Member {

    @Id @GeneratedValue
    private Long id;
    private String username;

    public Long getId() { return id; }
    public String getUsername() { return username; }
    public void setId(Long id) { this.id = id; }
    public void setUsername(String username) { this.username = username; }
}

Member (Lombok 버전)


package jpabook.jpashop;

import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import lombok.Getter;
import lombok.Setter;

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

MemberRepository.java


package jpabook.jpashop;

import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import org.springframework.stereotype.Repository;

@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);
    }
}

MemberRepositoryTest.java


package jpabook.jpashop;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.transaction.annotation.Transactional;

import static org.junit.jupiter.api.Assertions.*;

@ExtendWith(SpringExtension.class)
@SpringBootTest
class MemberRepositoryTest {

    @Autowired MemberRepository memberRepository;

    @Test
    @Transactional
    public void testMember() throws Exception {
        //given
        Member member = new Member();
        member.setUsername("memberA");

        //when
        Long savedId = memberRepository.save(member);
        Member findMember = memberRepository.find(savedId);

        //then
        assertEquals(member.getId(), findMember.getId());
        assertEquals(member.getUsername(), findMember.getUsername());
    }
}
  • 실행결과
    image

왜 데이터가 안 남는가?

  • @Transactional 테스트는 실행 시 항상 롤백이 기본값이다.
  • 테스트 안에서는 조회가 되지만, DB에는 남지 않는다.
  • ddl-auto: create 설정으로 컨텍스트 뜰 때마다 스키마가 재생성된다.

→ 따라서 @Rollback(false)를 추가해야 한다.


@Test
@Transactional
@Rollback(false)
  • 실행결과
    image

쿼리 파라미터 로그 남기기

외부 라이브러리: https://github.com/gavlyukovskiy/spring-boot-data-source-decorator


돌아가기: 2025 하반기 TAVE 16기 활동