본문 바로가기
JPA

[JPA] Spring 에서 JPA 사용하기

by kdohyeon (김대니) 2023. 2. 11.
반응형

JPA 개념에 대해서는 이해하고 있다고 가정을 하고 이번 글에서는 JPA 의 기본 사용법에 대해 알아보고자 한다.

의존성 추가

아래 의존성을 추가해주자.

dependencies {
    implementation("org.springframework.boot:spring-boot-starter-data-jpa") // JPA 의존성

    testImplementation("org.springframework.boot:spring-boot-starter-test") // 테스트를 위한 의존성
    runtimeOnly("com.h2database:h2") // 테스트를 위한 의존성
}

도메인 객체 생성

예시로 상품 (Product) 에 대한 객체를 생성해보자. 간단하게 id, name, description 3개의 필드만 가지고 있다.

@Entity
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Product {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column
    private String name;

    @Column
    private String description;

    public Product(String name, String description) {
        this.name = name;
        this.description = description;
    }
}

JPA Repository 생성

  • JpaRepository<T, ID> 인터페이스를 상속받는 인터페이스를 만든다.
  • T 에는 도메인 객체 클래스를 입력하고, ID 에는 도메인 객체의 ID 에 대한 데이터 타입을 입력한다.
    • 도메인 객체는 Product 이고, Product 의 ID 는 Long 으로 구성되어 있다.
public interface ProductJpaRepository extends JpaRepository<Product, Long> {
}

 

여기까지 하면 준비 완료이다. 상당히 간단하다. 해당 인터페이스를 빈으로 주입받고, 지원되는 메소드가 어떤 것들이 있는지 확인해보자. 조회는 findAll(), findAllById(), findById() 등 기본적인 쿼리를 지원하고, save(), delete() 등 쿼리도 지원한다.

커스텀 쿼리 작성

실무에서는 좀 더 복잡한 쿼리를 작성해야 한다. 이럴 땐 어떻게 해야 할까? JPA 에서 제공하는 기본 문법을 지켜서 JpaRepository 에 메소드를 만들어주면 된다. 예를 들어, description 으로 조회를 해보고 싶은 경우에는 어떻게 메소드 명을 지정해줘야 할까?

찾고자 하는 엔티티가 products 이기 때문에 findProducts 이고, 조건은 description 이기 때문에 findProductsByDescription 으로 정해주면 된다. description 이 조건이기 때문에 조건을 파라미터로 입력받아야 한다.

public interface ProductJpaRepository extends JpaRepository<Product, Long> {
    List<Product> findProductsByDescription(String description);
}

테스트 해보기. application.yml 파일 수정

테스트를 해보려면 설정을 조금 더 해줘야 한다.

JpaRepository 테스트는 h2 데이터베이스와 스프링 컨텍스트가 필요하기 때문에 integration test 로 진행하는 것이 좋다. 스프링 어플리케이션이 시작될 때 h2 데이터베이스도 함께 실행시키기 위해 application.yml 파일을 수정한다.

spring:
  jpa:
    show-sql: true
  datasource:
    name: SampleDatasource
    url: jdbc:h2:mem:sample
    driver-class-name: org.h2.Driver
    username: sa
    password:
    platform: h2

테스트 케이스 작성

@SpringBootTest // integration test 를 위해 @SpringBootTest 어노테이션을 활용한다. 
class SampleApplicationTests {

    @Autowired
    private ProductJpaRepository productJpaRepository; // productJpaRepository 를 주입해준다.

    @Test
    void test1() {
        // 조회하기 이전에 save 를 활용하여 객체 3개를 저장한다.
        productJpaRepository.save(new Product("모니터", "27인치"));
        productJpaRepository.save(new Product("키보드", "리얼포스 키보드"));
        productJpaRepository.save(new Product("휴대폰", "iPhone 11"));

        List<Product> products = productJpaRepository.findAll(); // findAll 을 통해 저장된 모든 객체를 조죄한다.

        assertThat(products).hasSize(3); // 제대로 저장이 되었다면 저장된 3개의 객체가 그대로 조회되어야 한다.
    }
    
    @Test
    void test2() {
        productJpaRepository.save(new Product("모니터", "27인치"));
        productJpaRepository.save(new Product("키보드", "리얼포스 키보드"));
        productJpaRepository.save(new Product("휴대폰", "iPhone 11"));

        List<Product> products = productJpaRepository.findProductsByDescription("27인치"); // 27인처로 equal 검색

        assertThat(products).hasSize(1) // 1개만 존재하며
                .element(0) // 첫 번째 아이템은
                .hasFieldOrPropertyWithValue("name", "모니터") // name 필드에는 "모니터"라는 값이,
                .hasFieldOrPropertyWithValue("description", "27인치"); // description 필드에는 "27인치" 라는 값이 저장되어 있음을 체크한다.
    }
}

디렉토리 및 패키지 구조

  • domain 패키지 아래의 Product 클래스
  • repository 패키지 아래의 ProductJpaRepository 인터페이스
  • resources 아래의 application.yml 파일
  • test 아래의 SampleApplicationTests

반응형

'JPA' 카테고리의 다른 글

[JPA] @ManyToOne, @OneToMany 를 활용하기  (0) 2023.02.10
[JPA] @EnableJpaAuditing 활용하기  (2) 2023.02.03
[JPA] @OrderBy  (0) 2023.02.03

댓글