3.5.1 JPA

yeonseong Jo·2023년 6월 28일
0

SEB_BE_45

목록 보기
36/47
post-thumbnail

Django의 orm을 배울 때
뭔가 새로웠지만 신기하고 재밌음에도
편리하다는 느낌까지 받았다.

JPA는 과연...
너도 django만큼 날 만족 시킬 수 있니?


JPA

jpa는
Java Persistence API의 약자로
Java에서 사용하는 대표적인 orm이다.

JDBC를 공부 할 때
JPA도 JDBC를 활용하여 만든거라 했는데,
사실 사이에 Hibernate ORM 하나가 더 껴있다.

Hibernate은 JPA 인터페이스의 구현체이고,
Hibernate 외에도
EclipseLink, DataNucleus등이 있다.

Persistence

Persistence는
영속성 혹은 지속성을 뜻한다.
무언가의 상태를 지속하는 것 같다.

여기서 이 무언가는 entity를 뜻하며,
DB에 저장되는 객체인
Spring에서 말하는 entity와 같은 것이다.

그래서 Entity Manager는
1차 캐시에 들어오는 entity의 수명주기를 관리하고,
쓰기 지연 저장소를 통해 commit할 때 까지
쿼리를 실행 시키지 않으며,
commit이나 flush이후 DB에 쿼리를 실행시킨다.

flush?

flush는 1차 캐시안의 entity의 변경 내용을
DB에 반영하는 것으로
transaction을 통해 commit하는 것과 달리
Entity Manager를 통해 진행 되기 때문에,
flush 이후에도 1차 캐시를 비우지 않는다.

그러니까 entity의 변경사항만 db에 전송하는 것

EntityManager

Spring Data JPA가 아닌
일반 JPA는
EntityManager를 통해 entity를 관리하고,
em.getTransaction()을 통해
생성한 객체로transaction을 관리한다.

em.persist()를 통해 1차 캐시에 entity객체가 저장되고
쓰기 지연 SQL 저장소에 쿼리가 등록된다.
tx.commit()을 통해 쓰기 지연 SQL 저장소에 등록된 쿼리가 실행되고 실행된 쿼리는 저장소에서 삭제한다.

em.에는 findflush등 여러 메서드가 존재

Entity

@Entity
@Table(name="USER")
public class Member {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long memberId;
}

Entity에 해당하는 클래스에
@Entity 을 통해 해당 클래스가 Entity라는 것을 알린다.

@Table 에서 name을 통해 DB에 있는 Table의 이름을 설정할 수 있다.

Id

@Id 를 단 필드는 primary key가 되며
@GeneratedValue를 통해
primary key 생성 전략을 선택할 수 있다.

  • IDENTITY
    entity를 영속화 시키는 시점에
    바로 insert 쿼리가 실행된다.
  • SEQUENCE
    DB Sequence를 활용하는 방식으로
    DB에서 Sequnece를 생성하고,
    Entity 클래스에 @SequenceGenerator
    @GeneratedValue에 generator를 넣어 사용한다.

    @Entity
    @SequenceGenerator(
    	name = "USER_SEQ_GENERATOR",
       sequenceName = "USER_SEQ",
       initialValue = 1,
       allocationSize = 1
    )
    public class Member {
    
       @Id
       @GeneratedValue(
       	strategy = GenerationType.SEQUENCE,
       	generator = "USER_SEQ_GENERATOR"
       )
       private Long id;
    }
  • TABLE
    성능이슈로 별로 사용안함

  • AUTO
    DB의 종류에 따라 알맞는 전략을 자동으로 선택해줌

Column

@Column(nullable = false)
private String name;

Entity 클래스에서 일반적으로 쓰이는 필드를
DB의 column에 매핑하는 annotation으로
nullable, updatable, unique등의 매개변수가 있다.

사실 @Coulumn annotation 없어도 알아서 등록하는거 같다.
하지만, 명시적으로 지정하기 위해 사용하는것 같다.

만약 사용 시 nullable
default값은 true이기 때문에 유의 해야한다.

NtoM

@Entity
public class Post {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long memberId;
    
    @ManyToOne
    @JoinColumn(name="MEMBER_ID")
    private Member member;
    ...
}

@ManyToOne, @OneToOne등을
@JoinColumn과 같이 활용해
Entity간의 연관관계 매핑이 가능하다.

@JoinColumn 에서 name에 들어가는 값은
참조 Entity의 primary key값의 이름이다.

@Entity
@Table(name="USER")
public class Member {
   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   private Long memberId;
   
   @OneToMany(mappedBy = "member")
   private List<POST> posts = new ArrayList<>();
   ...
}

@OneToMany를 활용해 1:N의 관계에서
1에 해당하는 Entity에서
N에 해당하는 Entity List를 불러올 수 있다.

물론 DB에 저장되는 값은 아니고,
1에 해당하는 Entity를 find 할 때
join query를 통해 알아서 가져오는거 같다.

mappedBy에 들어가는 값은
N에 해당하는 Entity 클래스에서
관계를 매핑할 때 사용한 필드의 이름이다.


역시 python인가..
jpa도 재미는 있지만,
복잡하고 django orm보다 어려운거 같다.

profile
뒤(back)끝(end)있는 개발자

0개의 댓글