JPA는 Java Persistence API 의 약자로, Java 객체와 DB 테이블을 매핑해주는 기술이다.
JPA를 쓰면 SQL을 직접 작성하지 않아도 Java 코드로 DB를 다룰 수 있게 된다.
// SQL 직접 작성 방식
SELECT * FROM member WHERE id = 1;
// JPA 방식
memberRepository.findById(1L);
JPA는 인터페이스고, 실제 구현체는 Hibernate 이다.
Spring Boot에서 spring-boot-starter-data-jpa 를 추가하면 Hibernate가 자동으로 설정된다.
Member.java 만들기
com.seongmo.myshop.member 패키지에 Member.java 파일을 만들자.
// Member.java
package com.seongmo.myshop.member;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.NoArgsConstructor;
@Entity
@Table(name = "member")
@Getter
@NoArgsConstructor
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false, unique = true)
private String email;
@Column(nullable = false)
private String password;
@Column(nullable = false)
private String nickname;
public Member(String email, String password, String nickname) {
this.email = email;
this.password = password;
this.nickname = nickname;
}
}
- @Entity 는 이 클래스가 DB 테이블과 매핑되는 엔티티임을 선언한다. Spring이 시작될 때 이 어노테이션을 보고 자동으로 테이블을 생성한다. (ddl-auto: create 설정 때문)
- @Table(name = "member") 는 매핑할 테이블의 이름을 지정한다. (생략 시 클래스 이름이 테이블 이름이 됨)
- @Id 는 이 필드가 PK(Primary Key)임을 선언한다.
- @GeneratedValue(Stratedy = GenerationType.IDENTITY) 는 PK 값을 DB가 자동으로 증가시키도록 한다. (MySQL의 AUTO_INCREMENT 와 동일)
- @Column(nullable = false) 는 이 컬럼이 NULL을 허용하지 않도록 한다.
- @Column(unique = true) 는 이 컬럼이 중복값을 허용하지 않도록 한다.
MemberRepository 만들기
com.seongmo.myshop.member 패키지에 MemberRepository.java 파일을 만들자
// MemberRepository.java
package com.seongmo.myshop.member;
import org.springframework.data.jpa.repository.JpaRepository;
public interface MemberRepository extends JpaRepository<Member, Long> {
boolean existsByEmail(String email);
}
JpaRepository<Member, Long> 에서 Member 는 엔티티 타입, Long 은 PK 타입이다.
JpaRepository 를 상속받으면 아래 메서드들이 자동으로 생긴다.
- save(member) : 저장
- findById(id) : ID로 조회
- findAll() : 전체 조회
- deleteById(id) : ID로 삭제
- existsById(id) : 존재 여부 확인
existsByEmail 은 직접 선언한 메서드인데, 메서드 이름만으로 JPA가 자동으로 쿼리를 만들어준다.
SELECT EXISTS (SELECT 1 FROM member WHERE email = ?)
MemberService.java 수정
이전에 Map으로 구현했던 MemberService 를 실제 DB와 연결되도록 교체하다.
// MemberService.java
package com.seongmo.myshop.member;
import com.seongmo.myshop.member.dto.MemberJoinRequest;
import com.seongmo.myshop.member.dto.MemberJoinResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@RequiredArgsConstructor
public class MemberService {
private final MemberRepository memberRepository;
@Transactional
public MemberJoinResponse join(MemberJoinRequest request) {
if (memberRepository.existsByEmail(request.getEmail())) {
throw new IllegalArgumentException("이미 사용 중인 이메일입니다.");
}
Member member = new Member(
request.getEmail(),
request.getPassword(),
request.getNickname()
);
Member savedMember = memberRepository.save(member);
return new MemberJoinResponse(
savedMember.getId(),
savedMember.getEmail(),
savedMember.getNickname()
);
}
public MemberJoinResponse getMember(Long id) {
Member member = memberRepository.findById(id)
.orElseThrow(() -> new IllegalArgumentException("존재하지 않는 회원입니다."));
return new MemberJoinResponse(
member.getId(),
member.getEmail(),
member.getNickname()
);
}
}
- @Transactional 은 메서드 실행 중 오류가 발생하면 DB 작업을 전부 롤백한다. 데이터를 저장하거나 수정하는 메서드에는 반드시 붙여야 한다.
- orElseThrow 는 findById 의 결과가 없을 때 예외를 던진다. findById 는 결과가 없을 수도 있어서 Optional 로 감싸서 반환하는데, orElseThrow 로 없을 때의 처리를 지정한다.
실행 및 확인
Intellij 에서 프로젝트를 실행해보면 콘솔에서 테이블 생성 SQL이 출력되는 것을 확인할 수 있다.

Postman으로 회원가입 요청을 보낸 뒤 DBeaver로 myshop DB의 member 테이블을 직접 확인할 수도 있다.

'Backend > Spring' 카테고리의 다른 글
| [Backend/Spring] Spring Boot - @OneToMany 와 N+1 문제 (0) | 2026.03.29 |
|---|---|
| [Backend/Spring] Spring Boot - JPA 연관관계 (0) | 2026.03.29 |
| [Backend/Spring] Spring Boot - MVC 계층 구조와 API (0) | 2026.03.29 |
| [Backend/Spring] Spring Boot - IoC/DI/Bean 개념과 MySQL 연결 (0) | 2026.03.29 |
| [Backend/Spring] Spring Boot - 프로젝트 생성과 구조 이해 (0) | 2026.03.29 |