본문 바로가기

컴퓨터/Spring Boot

[TIL] Spring Boot(intellij) - [DB-4] JPA와 스프링 데이터 JPA

* 인프런 김영한 강사님의 스프링 입문 강의 정리

JPA 와 스프링 데이터 JAP를 학습하였다.

이전 실무에서 Mybatis로 직접 쿼리를 작성하여 db 데이터를 처리하는 프로젝트를 많이 다뤘었는데

JPA는 직접 쿼리를 작성하지 않아도 알아서 해준다니..?

내용이 너무나도 방대하다고 하지만 잠깐 살펴본 것 만으로도 새로운 세계를 본 것만 같았다.

 

JPA(Java Persistent API)
- java ORM(Object Relational Mapping) 기술에 대한 api 표준 명세를 뜻한다.
- 인터페이스이므로 구현체가 필요하다.
- 대표적인 구현체로 Hibernate가 있다.
- 데이터 중심의 설계에서 객체 중심의 설계로 전환할 수 있다. -> 생산성을 높일 수 있다.

 

 Spring Data JPA
- JPA를 사용하기 편하도록 만들어놓은 스프링에서 제공하는 모듈이다.
- JPA를 추상화시킨 Repository 인터페이스를 제공한다.

 

5. JPA

5-1 환경 설정 

 

jpa를 사용하기 위해 환경설정을 진행한다.

[build.gradle]

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
	implementation 'org.springframework.boot:spring-boot-starter-web'
//	implementation 'org.springframework.boot:spring-boot-starter-jdbc'
	implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
	runtimeOnly 'com.h2database:h2'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

 

spring-boot-starter-data-jpa 라이브러리를 추가한다.

이는 jdbc 관련 라이브러리를 포함하기 때문에 이전에 jdbc 사용을 위해 추가했던 라이브러리를 지워도 상관 없다.

 

[application.properties]

spring.datasource.url=jdbc:h2:tcp://localhost/~/test
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.username=sa

spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=none

하단의 두 가지 설정을 추가한다.

 

show-sql은 jpa가 생성하는 sql문을 콘솔에 출력해 확인할 수 있다.

 

ddl-auto는 jpa가 테이블을 자동으로 생성하는 기능을 제공한다.

none을 사용하면 기능을 끄고 create를 사용하면 테이블을 직접 생성해준다.

 

예제에서는 이미 테이블을 생성했기 때문에 none으로 기능을 끄고 시작한다.

 

 

5-2 Entity 맵핑

 

jpa 사용을 위해서는 환경설정 이후 entity를 맵핑해야 한다.

 

[member Domain]

package myStudyspring.myStudyspring.domain;


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

@Entity
public class member {

    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    //db가 pk를 알아서 생성해주는 전략
    private Long id;
    private String name;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

@Entity 어노테이션으로 jpa가 관리하는 entity임을 알려준다.

@Id로 pk를 맵핑하고 생성 전략을 정의하는 @GeneratedValue 어노테이션으로 전략을 명시한다.

*Identity 전략 - db가 알아서 pk를 생성해주는 전략

 

 

5-2 Repository 생성

 

다음과 같이 repository 폴도 하위에 jpa 리포지토리를 생성한다.

 

[JpaMemberReository]

package myStudyspring.myStudyspring.repository;

import jakarta.persistence.EntityManager;
import myStudyspring.myStudyspring.domain.member;

import java.util.List;
import java.util.Optional;

public class JpaMemberRepository implements memberRepository
{
    private final EntityManager em;     //스프링부트가 자동으로 생성해줘서 주입받으면 된다.

    public JpaMemberRepository(EntityManager em) {
        this.em = em;
    }

    @Override
    public member save(member member) {
        em.persist(member);
        return member;
    }

    @Override
    public Optional<member> findById(Long id) {
        member member=em.find(member.class, id);
        return Optional.ofNullable(member);
    }

    @Override
    public Optional<member> findByName(String name) {
         List<member> result = em.createQuery("select m from member m where m.name = :name", member.class)
                .setParameter("name", name)
                .getResultList();
        return result.stream().findAny();
    }

    @Override
    public List<member> findAll() {
        return em.createQuery("select m from member m", member.class)
                .getResultList();
    }
}

 

jpa는 EntityManager를 주입받아야하는데

스프링부트가 자동으로 EntityManager를 생성해주기 때문에 바로 주입받으면 된다.

 

pk 기반이 아닌 컬럼들은 jpql을 작성해야 한다.

ex) findByName의 createQuery문

 

JPQL(Java Persistence Query language)
- 엔티티 객체를 조회하는 객체지향 쿼리이다.
- 테이블이 아닌 엔티티 객체를 대상으로 쿼리를 작성한다.
- sql로 변환된다.

 

 

5-3 Transaction 추가

 

jpa를 사용하기 위해서는 항상 Transaction이 필요하기 때문에

(= 모든 변경은 transaction 안에서 실행되어야 한다.)

서비스 계층에 @Transactional 어노테이션을 사용한다.

 

[MemberService]

@Transactional
public class MemberService {
	...
}

org.springframework.transaction.annotation.Transactional

 

 

 

5-4 스프링 설정 변경

 

jpa 사용을 위해 이전과 마찬가지로 springConfig 파일에서 스프링 설정을 변경해준다. 

 

[SpringConfig]

package myStudyspring.myStudyspring;

import myStudyspring.myStudyspring.repository.*;
import myStudyspring.myStudyspring.service.MemberService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class SpringConfig {

    private EntityManager em;

    @Autowired
    public SpringConfig(EntityManager em) {
        this.em = em;
    }

    @Bean
    public MemberService memberService(){
        return new MemberService(memberRepository);
    }

    @Bean
    public memberRepository memberRepository(){

        return new JpaMemberRepository(em);

    }
}

마찬가지로 EntityManager를 생성자로 주입받는다.

728x90