본문 바로가기
강의 실습/스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술

JPA

by jint 2026. 3. 15.

1. JPA
· 기존 반복 코드와 기본적인 SQL도 직접 만들어서 실행
· SQL과 데이터 중심의 설계에서 객체 중심의 설계로 패러다임 전환
· 개발 생산성 크게 향상

JPA는 자바 진영 표준 인터페이스이고, 여러 업체에서 구현했다.
주로 JPA 인터페이스의 hibernate 를 쓴다.
ORM은 객체와 관계형 데이터베이스 테이블을 매핑한다는 뜻이다. 매핑은 어노테이션으로 한다.

트래픽이 큰 곳에서 과연 JPA가 쓰일 수 있을까?
해외 은행에서도 쓰고, 조 단위 거래하는 결재 및 정산 및 주문 시스템에서도 사용된다. 큰 회사들이나 큰 스타트업에서도 사용한다.

1) build.gradle
build.gradle 파일에 JPA 관련 라이브러리 추가

- build.gradle

...
dependencies {
    ...
    // implementation 'org.springframework.boot:spring-boot-starter-jdbc'
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    ...
}
...


"spring-boot-starter-data-jpa" 내부에 JDBC 관련 라이브러리를 포함하므로, JDBC 라이브러리는 제거

2) application.properties
스프링 부트에 JPA 설정 추가

- src/main/resources/application.properties

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


· show-sql : JPA가 생성하는 SQL 출력
· ddl-auto : 엔티티 정보를 바탕으로 테이블 자동 생성 (none: 기능OFF / create: 기존 매핑 테이블 있다면 삭제 후 테이블 자동 생성)

3) JPA 엔티티 매핑
@Entity 어노테이션이 있으면 JPA가 관리하는 엔티티가 된다.
@Id : PK
IDENTITY 전략 : DB가 알아서 PK를 생성

만약 필드 변수가 name 인데 DB의 컬럼명이 username 으로 다르지만 매핑하고 싶다면, @Column(name = "username")

- src/main/java/hello/hello_spring/domain/Member.java

package hello.hello_spring.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)
    private Long id;
    ...

}


* 참고
스프링 부트 3.0 이상이라면 javax.persistence 는 사용되지 않는다. 따라서 javax 패키지 명을 jakarta 로 반드시 변경한다.

4) JPA 회원 리포지토리
JPA는 EntityManager 로 모든게 동작
JPA 라이브러리를 받으면 스프링 부트가 자동으로 EntityManager 생성한다. 이것을 주입받으면 된다.
EntityManager 내부적으로 DataSource 를 가지고 있다.

- src/main/java/hello/hello_spring/repository/JpaMemberRepository.java

package hello.hello_spring.repository;

import hello.hello_spring.domain.Member;
import jakarta.persistence.EntityManager;

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); // INSERT 후 id도 넣어줌
        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) {
        // JPQL : 객체(엔티티) 대상으로 쿼리 날림 - SQL로 번역됨
        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();
    }

}


5) 서비스 계층에 트랜잭션 추가
- src/main/java/hello/hello_spring/service/MemberService.java

...
import org.springframework.transaction.annotation.Transactional;
...
@Transactional
public class MemberService {
    ...
}


· jakarta.transaction.Transactional 이 아닌, org.springframework.transaction.annotation.Transactional 사용
· 스프링은 해당 클래스 메서드 실행시 트랜잭션을 시작하고, 메서드 정상 종료시 트랜잭션 커밋
런타임 예외 발생시 롤백
-> 메서드에 @Transactional 을 직접 넣을 수도 있다.

★ JPA를 통한 모든 데이터 변경은 트랜잭션 안에서 실행해야 한다!

6) JPA를 사용하도록 스프링 설정 변경
- src/main/java/hello/hello_spring/SpringConfig.java

...
    private final DataSource dataSource;
    // @PersistenceContext
    private final EntityManager em;

    @Autowired
    public SpringConfig(DataSource dataSource, EntityManager em) {
        this.dataSource = dataSource;
        this.em = em;
    }
...
    @Bean
    public MemberRepository memberRepository() {
        // return new MemoryMemberRepository();
        // return new JdbcMemberRepository(dataSource);
        // return new JdbcTemplateMemberRepository(dataSource);
        return new JpaMemberRepository(em);
    }
...


원래 @PersistenceContext 로 받아야 하지만, 스프링에서 DI 해준다.

@PersistenceContext 참고 : https://drg2524.tistory.com/172

 

[ JPA ] 영속성 컨텍스트(Persistence Context) 개념 정리 및 사용법

영속성 컨텍스트(Persistence Context) 영속성 컨텍스트(Persistence Context)란 엔티티를 영구 저장하는 환경이라는 뜻으로, 애플리케이션과 데이터베이스 사이에서 객체를 보관하는 가상의 데이터베이스

drg2524.tistory.com


소스 구현 후, MemberServiceIntegrationTest 를 통해 통합 테스트를 진행한다.

- 콘솔

Hibernate: select m1_0.id,m1_0.name from member m1_0 where m1_0.name=?
Hibernate: insert into member (name,id) values (?,default)


콘솔을 확인하면 "Hibernate:"가 나오는데, JPA가 Hibernate 구현체를 사용하기 때문이다.

* 참고
스프링 부트 3.0 이상이라도 javax.sql.DataSource 는 jakarta 로 변경하지 않고 그대로 유지한다.


참고링크 : https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%EC%9E%85%EB%AC%B8-%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8?cid=325630

 

[지금 무료]스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술| 김영한 - 인프런 강의

현재 평점 5.0점 수강생 120,756명인 강의를 만나보세요. 스프링 입문자가 예제를 만들어가면서 스프링 웹 애플리케이션 개발 전반을 빠르게 학습할 수 있습니다. 예제를 만들면서 자연스럽게 스

www.inflearn.com

댓글