Notice
Recent Posts
Recent Comments
Link
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 |
Tags
- 접근제어지시자
- While
- 메서드 오버로딩
- 포함관계
- JAVA객체지향
- 생성자
- OPP개념
- Java
- 연관관계
- for문
- 컴파일
- 메서드
- JAVA기초
- 자바 멀티스레딩
- Thread
- java변수
- 반복문
- 인텔리제이 한글 깨짐 해결법
- IntelliJ IDEA
- continue문
- function
- break문
- 집합관계
- multi-threading
- 형 변환
- 시스템 환경 변수 편집
- this예약어
- 상수
- 인텔리제이 기초 설정
- Java데이터 타입
Archives
- Today
- Total
최원종의 개발 블로그
V2(PersistentContext) 게시글 작성 - PersistenceContext 활용 본문
Persistence Context(영속성 컨텍스트)
영속성 컨텍스트
엔티티(객체)를 영구 저장하고 관리하는 논리적인 메모리 영역.
애플리케이션과 데이터베이스(DB) 사이에서 중계자 역할
영속상태
영속성 컨텍스트에 의해 관리되는 상태, 데이터베이스와의 동기화가 이루어짐

1차 캐시 (Memory Cache): DB에 가기 전에 메모리에서 먼저 찾습니다.
똑같은 데이터를 두 번 조회하면 두 번째는 DB에 물어보지 않고 메모리에서 꺼내옵니다.
동일성 보장 (Identity): 같은 ID로 조회한 두 객체는 자바의 == 비교에서 항상 true입니다.
쓰기 지연 (Write-Behind): save를 한다고 바로 DB에 쿼리를 쏘지 않습니다.
쿼리를 모아뒀다가 트랜잭션이 끝나는(Commit) 순간 한꺼번에 보냅니다.
(택배를 하나씩 안 보내고 트럭에 모아서 한 번에 보내는 것과 같음.)
변경 감지 (Dirty Checking): 객체의 값만 바꿔두면, 트랜잭션이 끝날 때
JPA가 처음과 값이 다른 걸 확인 하고 알아서 UPDATE 쿼리를 만들어 날려줍니다.
JPA를 선택하는 이유
1. **영속성 컨텍스트**: 자동 상태 관리, 변경 감지, 1차 캐시
2. **객체지향적 개발**: 엔티티 중심의 비즈니스 로직
3. **생산성**: 반복적인 CRUD 코드 자동화
4. **표준화**: JPA 표준으로 벤더 독립적
5. **연관관계 관리**: 객체 간 관계를 자연스럽게 표현
Board.java 코드
package com.tenco.blog.board;
import com.tenco.blog.util.MyDateUtil;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.CreationTimestamp;
import java.sql.Timestamp;
@Data // get,set, toString ..
// @Entity - JPA가 이 클래스를 데이터베이스 테이블과 매핑하는 객체로 인식하게 설정
// 즉, 이 어노테이션이 있어야 JPA가 관리 함
@Entity
@Table(name = "board_tb")
@NoArgsConstructor
@AllArgsConstructor // 전체 멤벼 번수를 넣을 수 있는 생성자.
@Builder
public class Board {
// @id : 이 필드가 기본키임을 설정 함
@Id
// IDENTITY 전략: 데이터베이스게 기본 AUTO_INCREMENT 기능 사용
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String username;
private String title;
private String content;
// @CreationTimestamp : 하이버네이트가 제공하는 어노테이션
// 특정 하나의 엔티티가 저장이 될 때 현재 시간을 자동으로 저장해 설정
// now() 명시할 필요 없음
// pc --> db (자동 날짜 주입)
@CreationTimestamp
private Timestamp createdAt;
// createdAt -> 포멧 하는 메서드 만들어 보기
public String getTime() {
return MyDateUtil.timestampFormat(createdAt);
}
}
BoardPersistRepository.java코드
package com.tenco.blog.board;
import jakarta.persistence.EntityManager;
import jakarta.transaction.Transactional;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;
@Repository // IoC
@RequiredArgsConstructor // DI 처리 됨
public class BoardPersistRepository {
// JPA 핵심 인터페이스
// 영속성 컨텍스트를 관리하고 엔티티의 생명주기를 제어
// @Autowired // DI
private final EntityManager em; // final 사용하면 성능 개선이 조금 됨
// 의존 주입 (외부에서 생성되어 있는 객체의 주소값을 주입 받다)
// public BoardPersistRepository(EntityManager em) {
// this.em = em;
// }
// 게시글 저장
@Transactional
public Board save(Board board) {
// 1. 매개 변수로 받은 board는 비영속상태
// -- 아직 영속성 컨텍스트에 관리 되고 있지 않는 상태
// -- 데이터베이스과 연관 없는 수순 JAVA 객체 일 뿐 아직은..
//em.createNativeQuery("insert into board_tb .... ) x
em.persist(board); // insert 처리 완료
// 2. 이 board 객체를 영속성 컨텍스트에 넣어 둠 (SQL 저장소에 등록)
// -- 영속성 컨텍스트에 들어가더라도 아직 DB 실제 insert한 상태는 아님
// 3. 트랜잭션 커밋시점에 실제 DB에 접근해서 insert 구문이 수행이 된다.
// 4. board 객체의 id 변수값을 1차 캐쉬에 map 구조로 보관 되어 짐.
// 1차 캐쉬에 들어간 이제 영속상태로 변경된 Object 리턴 한다.
return board;
}
}
board/BoardRequest.java코드
package com.tenco.blog.board;
import lombok.Builder;
import lombok.Data;
// 요청 데이터를 담는 DTO 클래스
// 컨트롤러.. 비즈니스 .. 데이터 계층 사이에서 데이터 전송 역할 객체
public class BoardRequest {
@Data
@Builder
public static class SaveDTO {
private String username;
private String title;
private String content;
// 편의 기능 설계 가능
// DTO 에서 Entity로 변환해주는 편의 메서드
public Board toEntity() {
return Board.builder()
.username(username)
.title(title)
.content(content)
.build();
}
}
}
BoardController코드
/**
* 게시글 작성 기능 요청
* @return 페이지 반환
* 주소설계 : http://localhost:8080/board/save-form
*/
@PostMapping("/board/save")
// 사용자 요청 -> HTTP 요청 메시지(Post)
public String saveProc(BoardRequest.SaveDTO saveDTO) {
Board board = saveDTO.toEntity();
boardPersistRepository.save(board);
return "redirect:/";
}'Spring boot 입문' 카테고리의 다른 글
| V2(PersistentContext) 게시글 상세보기 만들기 - Persistence Context와 1차 캐시 활용 (0) | 2026.05.07 |
|---|---|
| V2(PersistentContext) 게시글 목록 보기 - Persistence Context와 JPQL 활용 (0) | 2026.05.07 |
| V2(PersistentContext)-패키지 구조 변경 (0) | 2026.05.07 |
| V2(PersistentContext)- 영속성 컨텍스트 개념 정리 (0) | 2026.04.30 |
| V1(익명블로그)-게시글 수정하기 (0) | 2026.04.30 |
