Spring_23_JPA

OngTK·2025년 11월 3일

Spring

목록 보기
23/25

📘 Spring Boot JPA 정리 — 도서 CRUD 예제 기반


🧠 0️⃣ JPA란 무엇인가?

항목설명
정의Java 진영의 ORM(Object Relational Mapping) 표준 명세 (API)
풀네임Java Persistence API
역할자바 객체(클래스)와 관계형 데이터베이스의 테이블을 자동으로 매핑해주는 인터페이스
핵심 구현체Hibernate, EclipseLink, TopLink 등
Spring Boot에서의 사용spring-boot-starter-data-jpa 의존성 추가 시 Hibernate 자동 사용

✅ 요약하자면

JPA = ORM의 표준 명세,
Hibernate = JPA의 대표 구현체


⚙️ JPA의 주요 특징

특징설명
객체 중심 설계SQL 대신 Entity(객체)를 직접 다룸
SQL 자동 생성save(), findAll() 등 CRUD 시 SQL 자동 실행
트랜잭션 관리 통합@Transactional 기반 자동 Commit/Rollback
캐싱 기능동일 트랜잭션 내 동일 Entity는 1차 캐시에 보관되어 중복 쿼리 방지
변경 감지 (Dirty Checking)Entity의 필드 값이 변경되면 JPA가 자동으로 UPDATE SQL 수행
데이터베이스 독립성DBMS(MySQL, Oracle 등) 변경 시에도 코드 수정 최소화

🔄 JPA의 동작 구조

[1] EntityManagerFactory 생성
      ↓
[2] EntityManager (트랜잭션 단위)
      ↓
[3] EntityManager가 Entity를 영속성 컨텍스트에 저장
      ↓
[4] EntityManager.flush() → SQL 생성 및 DB 반영
      ↓
[5] Commit / Rollback 처리
단계설명
EntityManagerFactoryJPA의 핵심 매니저를 생성하는 팩토리 객체 (애플리케이션 전역 1개)
EntityManager실제 CRUD 작업 담당 (트랜잭션 단위로 생성)
영속성 컨텍스트 (Persistence Context)Entity 객체를 1차 캐시 형태로 관리하며 변경 감지 수행

1️⃣ 데이터베이스 분류

구분설명예시
SQL (관계형)스키마 기반, 정형 데이터MySQL, Oracle
NoSQL (비관계형)Key-Value / Document 구조Redis, MongoDB

2️⃣ JDBC → ORM 관련 수강 과정

시기기술특징
7~8월JDBC / DAO수동 SQL 작성, ResultSet 수작업
9~10월MyBatisSQL 분리(XML/Annotation), 반자동 매핑
11월JPA (Hibernate 기반)SQL 없이 Java 객체로 CRUD 수행

3️⃣ ORM (Object-Relational Mapping)

  • 정의 : 객체지향 언어(Java)의 클래스와 DB의 테이블을 매핑하는 기술
  • 목적 : SQL 작성 없이 객체 중심의 데이터 접근 제공
  • 주요 구현체 : MyBatis, Hibernate, JPA 등

4️⃣ Hibernate vs JPA

항목HibernateJPA
정의ORM 프레임워크 (구현체)Java ORM의 표준 명세 (API)
역할실제 데이터베이스 처리 로직 담당Hibernate 등의 구현체가 따라야 할 인터페이스
설치spring-boot-starter-data-jpa 추가 시 자동 포함

5️⃣ JPA 핵심 구성요소

구성요소설명
EntityDB 테이블과 매핑되는 클래스
RepositoryCRUD를 담당하는 인터페이스
Service비즈니스 로직 처리 계층
ControllerREST API 요청/응답 처리 계층

6️⃣ Gradle & properties 설정

Gradle

implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'mysql:mysql-connector-j'

application.properties

# JPA DDL 설정
# Entity 테이블 CUD

# [8-1] Entity 테이블 삭제 후 생성
# spring.jpa.hibernate.ddl-auto=create

# [8-2] Entity 테이블이 존재하면 수정 / 존재하지 않으면 생성
spring.jpa.hibernate.ddl-auto=update

# [8-3] Entity 테이블을 직접관리하기 위해, CRUD 기능을 부여하지 않음
# spring.jpa.hibernate.ddl-auto=none

# [8.4] JPA가 처리한 SQL 문을 console에 출력
spring.jpa.show-sql=true

# [8.5] console에 출력된 SQL을 줄바꿈 처리하여 가독성을 높임
spring.jpa.properties.hibernate.format_sql=true

7️⃣ Entity 클래스 (BookEntity.java)

@Entity
@Table(name = "book")
public class BookEntity {

    @Id // 기본키
    @GeneratedValue(strategy = GenerationType.IDENTITY) // AUTO_INCREMENT
    private Integer id;

    @Column(nullable = false, length = 100)
    private String title;

    @Column(length = 50)
    private String author;

    @Column(length = 100)
    private String publisher;

    // 기본 생성자 (JPA 필수)
    public BookEntity() {}

    // 생성자 및 Getter/Setter
    public BookEntity(String title, String author, String publisher) {
        this.title = title;
        this.author = author;
        this.publisher = publisher;
    }

    // Getter & Setter 생략
}

8️⃣ Repository 인터페이스 (BookRepository.java)

@Repository
public interface BookRepository extends JpaRepository<BookEntity, Integer> {
    // JpaRepository<Entity 타입, PK 타입>
    // findAll(), findById(), save(), deleteById() 등 기본 CRUD 자동 제공
}

9️⃣ Service 클래스 (BookService.java)

@Service
@RequiredArgsConstructor
public class BookService {

    private final BookRepository bookRepository;

    // [1] 도서 등록
    public BookEntity createBook(BookEntity book) {
        return bookRepository.save(book);
    }

    // [2] 도서 전체 조회
    public List<BookEntity> getAllBooks() {
        return bookRepository.findAll();
    }

    // [3] 특정 도서 수정
    @Transactional
    public BookEntity updateBook(Integer id, BookEntity newBook) {
        BookEntity book = bookRepository.findById(id)
                .orElseThrow(() -> new IllegalArgumentException("해당 도서 없음"));

        book.setTitle(newBook.getTitle());
        book.setAuthor(newBook.getAuthor());
        book.setPublisher(newBook.getPublisher());
        return book; // Transactional로 자동 commit
    }

    // [4] 특정 도서 삭제
    public void deleteBook(Integer id) {
        bookRepository.deleteById(id);
    }
}

🔟 Controller 클래스 (BookController.java)

@RestController
@RequiredArgsConstructor
@RequestMapping("/api/books")
public class BookController {

    private final BookService bookService;

    // [1] 도서 등록
    @PostMapping("/create")
    public ResponseEntity<BookEntity> createBook(@RequestBody BookEntity book) {
        return ResponseEntity.ok(bookService.createBook(book));
    }

    // [2] 전체 도서 조회
    @GetMapping("/all")
    public ResponseEntity<List<BookEntity>> getAllBooks() {
        return ResponseEntity.ok(bookService.getAllBooks());
    }

    // [3] 특정 도서 수정
    @PutMapping("/update/{id}")
    public ResponseEntity<BookEntity> updateBook(@PathVariable Integer id, @RequestBody BookEntity newBook) {
        return ResponseEntity.ok(bookService.updateBook(id, newBook));
    }

    // [4] 특정 도서 삭제
    @DeleteMapping("/delete/{id}")
    public ResponseEntity<String> deleteBook(@PathVariable Integer id) {
        bookService.deleteBook(id);
        return ResponseEntity.ok("삭제 완료");
    }
}

✅ 핵심 요약

항목설명
EntityDB 테이블과 매핑된 클래스
RepositoryJPA가 CRUD 메서드 자동 제공
Service트랜잭션 관리 및 비즈니스 로직 담당
ControllerREST API 처리 계층
@Transactional하나의 DB 트랜잭션 단위로 묶어 처리
장점SQL 작성 불필요, 객체 중심 데이터 접근
주의Controller에서는 DTO 사용, Entity 직접 노출 지양

📚 출처: Spring Boot JPA 공식 문서, Hibernate User Guide, 실습 예제(Book CRUD)

profile
2025.05.~K디지털_풀스택 수업 수강중

0개의 댓글