(spring) (자바 ORM 표준 JPA 프로그래밍 - 기본편_01)

전성영·2022년 6월 3일
0

spring

목록 보기
12/31

항해를 진행하면서 더 많은 공부를 해야겠다 다짐을 하고 김영한님의 자바 ORM 표준 JPA 프로그래밍과 MVC 기본편? 강의를 구입했다. gradle만 사용해봤는데 ORM 표준 강의는 MAVEN을 사용한다.

열공~!~!~!~!~!~!~!

JPA란?

JPA는 자바 진영에서 DB 테이블과 자바 객체 사이의 매핑을 처리해주는 ORM(Object-relational mapping)이라는 기술의 표준이다.
즉 자바의 클래스와 DB의 테이블을 매핑하는 기술이라고 보면 될 것 같다.
보통 JDBC를 사용하면 테이블 수정을 할 때 관련되어있는 모든 쿼리를 수정해야 하는데 JPA는 매핑설정만 변경하면 되서 유지보수가 쉽다.

JPA는 애플리케이션과 JDBC 사이에서 동작한다.
위 사진은 저장을 했을 때의 예 이다.


또한 JPA는 특정 데이터베이스에 종속되지 않는다.


JPA가 Dialect를 사용하는데 데이터베이스에 맞게 변경해준다.


META_INF 안 persistence.xml
저 파란체크 한 부분을 바꿔주면 된다.


spring 본격적으로 시작 전 정석코드

public class JpaMain {
    public static void main(String[] args){
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello"); //엔티티 매니저 생성, 디비 연결도 된다.
        EntityManager em = emf.createEntityManager(); //닫기 전에 동작하는 코드들을 작성
        EntityTransaction tx = em.getTransaction();

        tx.begin();
        try{
            Member member = new Member();
            member.setId(2L);
            member.setName("HelloB");

            em.persist(member);
            tx.commit();
        }catch(Exception e){
            tx.rollback();
        }finally {
            em.close();
        }
        emf.close();
    }
}

정석 Code
EntityManagerFactory 를 만드는 순간 데이터베이스 연결이 된다.
그 후 EntityManager 를 만든다.

또 알아야 할 것은 데이터를 변경하는 모든 작업은 트랜잭션 안에서 이루어져야 한다는 것이다.
EntityTransaction tx 를 선언 후 begin() 과 commit().
문제가 생긴다면 rollback()을 한다.


영속성 컨텍스트

엔티티를 영구 저장 하는 환경 이라는 뜻이다.

영속성 컨텍스트가 생기는 시점은 엔티티 매니저 생성 시점이다.

@@여기@@ 는 강의를 듣기 전, entity 4가지 상태가 궁금해서 간단히 정리를 해놓은 곳이다.(비영속, 삭제 등등)
추가로 하는 것이라서 전에 글에서 쓴 내용은 거의 안 쓸듯?

영속(managed)

영속성 컨텍스트(엔티티를 영구 저장하는 환경)에 의해서 관리되어지는 상태이다.

준영속

영속 -> 준영속으로 된 것이다.
영속성 컨텍스트가 제공하는 기능을 사용하지 못한다.

Member member = em.find(Member.class, 155L);
member.setName("qweqwe");

em.detach(member);

tx.commit();

em.detach(member) - 영속성 컨텍스트에서 끄집어온다.
즉 위 코드는 update문이 실행되지 않는다.

em.clear() - 영속성 컨텍스트를 완전히 초기화한다.

em.close() - 영속성 컨텍스트를 닫는다.

영속성 특징

  • 1차캐시
  • 동일성 보장
  • 트랜잭션을 지원하는 쓰기 지연
  • 변경 감지

영속성 컨텍스트는 위 사진과 같이 1차 캐시를 가지고 있다.

위에 써둔 링크에도 설명이 되어있지만 .find()를 할 때 바로 DB에서 찾는 것이 아니라 1차 캐시를 본 후 없으면 DB를 간다.

1차캐시에 해당 ID값이 없을 때의 사진이다.
DB에서 꺼내올 때 DB에 담고 반환해준다.

영속 엔티티 동일성 보장

Member a = em.find(Member.class, "member1"); 
Member b = em.find(Member.class, "member1");
System.out.println(a == b); //동일성 비교 true

1차 캐시가 있기 때문에 가능한 일이다.

트랜잭션을 지원하는 쓰기 지연

EntityManager em = emf.createEntityManager();
EntityTransaction transaction = em.getTransaction();
//엔티티 매니저는 데이터 변경시 트랜잭션을 시작해야 한다.
transaction.begin(); // [트랜잭션] 시작
	em.persist(memberA);
	em.persist(memberB);
    
//여기까지 INSERT SQL을 데이터베이스에 보내지 않는다.
transaction.commit();

커밋하는 순간 데이터베이스에 INSERT SQL을 보낸다.
즉, 쓰기지연 SQL 저장소에 있던 memberA와 memberB가 flush되면서 DB에 날라간다.

변경감지

// 영속 엔티티 조회
Member memberA = em.find(Member.class, "memberA");

// 영속 엔티티 데이터 수정
memberA.setUsername("hi");
memberA.setAge(10);

//em.persist(memberA);

transaction.commit();

em.persist(memberA) 이러한 저장코드가 없어도 저장이 된다.

이유
commit을 하면 내부적으로 flush()가 호출된다.
그렇게 되면 1차 캐시 안에 있는 Entity와 스냅샷을 비교한다.
만약 바뀌었으면 UPDATE Query문을 생성해서 쓰기 지연 SQL 저장소에 놓는다.
그 후 DB에 반영하고 commit한다.

스냅샷이란? 최초로 영속 컨텍스트에 들어왔을 때의 값


flush

영속성 컨텍스트의 변경내용을 DB 반영하는 것이다.

언제 플러시가 발생할까?

  • 변경 감지
  • 수정된 엔티티 쓰기 지연 SQL 저장소에 등록
  • 쓰기 지연 SQL 저장소의 쿼리를 데이터베이스에 전송

영속성 컨텍스트를 플러시 하는 방법

  • em.flush() - 직접 호출
  • 트랜잭션 커밋 - 플러시 자동 호출
  • JPQL 쿼리 실행 - 플러시 자동 호출

Member member = new Member(200L, "member200");
em.persist(member);

em.flush();
System.out.println("==============================");

tx.commit();

flush가 없는 상황에선 commit을 한 후 =====가 출력되었겠지만, DB에 바로 때려박는 flush형님이 있어서 쿼리문이 나온 후 ===== 가 나온다.

- flush를 해도 1차캐시는 남아있는다.
- 영속성 컨텍스트를 비우지 않는다.

profile
Slow and Steady

0개의 댓글