공부기록/JPA

자바 ORM 표준 JPA 프로그래밍 #1~5

DGL 2021. 5. 3. 01:33

1장

SQL을 직접 다루면 문제의 소지들이 있음!

(jdbc 사용시 table에 변경이 있다면 바꿔야 할 코드가 많음)

→ JPA를 사용하자!

뿐만 아니라 패러다임의 불일치가 발생

⇒ 객체와 테이블은 다르다!

  1. 객체- 상속가능, 테이블 -불가능
  2. 객체는 탐색이 가능하지만, 테이블은 탐색시 join을 해야하며, 많이하면 비용이 엄청남
  3. 또한 객체는 연결이 단방향, 테이블은 양방향

⇒ 이런 패더라임의 차이로 개발자가 많은 시간을 투자해야했음

⇒ 위의 문제들을 JPA가 해결해줌 ( 개발자의 개발시간을 많이 단축해줌)

⇒ 복잡한 통계정보같은 것들은 여전히 sql을 사용해야함


2장

  • 기본적인 JPA 프로젝트( 여기에 사용된 기본적인 어노테이션들 소개)
  • JPA의 구조 ( DB마다 방언이 있는데, 그래서 db마다 구현체를 사용해줘야함 JPA는 인터페이스)
  • 엔티티 매니저에 대한 소개 ( 엔티티 매니저 팩토리(하나만 써야함)로 부터 생성) ⇒ 스프링 부트에서는 알아서 관리됨
  • tx.begin tx.commit 사이에 비즈니스 로직을 넣어서 관리 ( 한번에 배치로 sql들이 처리됨)

3장

매번 객체를 db에 저장하는 것이아니라, 메모리상에 저장(영속)해두었다가 tx.commit시에 전송함

메모리상에서 더이상 관리 안하는 상태(준영속)로 바꿀수도 있음

이렇게 관리함으로 얻을 수 있는 이점들

  1. 1차 캐시 - 저장후, select할때 메모리에서 가져와도됨 ( 만약 여기서 저장한 row라면!)
  2. 동일성 보장 - 메모리에서 객체를 가져오기 때문에 == 가 참으로 나옴
  3. 트랜잭션을 지원하는 쓰기 지연 - 배치 처리로 최적화(여러번 왔다갔다 하지 않기)
  4. 변경 감지 - 스냅샷을 사용하여 변경된 점이 있다면 수정된 부분에 대하여 update
  5. 지연 로딩 - 실제 객체 대신 프로식 객체를 로딩해두고 해당 객체를 실제 사용할 때 영속성 컨텍스트를 통해 데이터를 불러오는 방법이다. → FetchType.LAZY 나중에 더 자세히 나올듯 하다

플러시는 값을 지우는게 아니라, 동기화하는 것

tx.commit, jpql, creteria 실행시 ⇒ 플러시


4장

기본적인 매핑

@Entity ( JPA의 테이블이다라는..)

@Table ( table의 이름,속성을 지정할 수 있음 )

@Id JPA에서는 무조건 PK를 설정해야함 ( 영속성관리에서 중복 처리될 수 있기 때문)

hibernate.hbm2ddl.auto 테스트/개발중에는 create, create-drop, update 등을 사용하고

실제 배포시에는 validate, none을 사용해야함

@Column name= 이름, nullable = not null contraint 설정 , length = 길이 제한

@UniqueConstraint 유니크 제약조건

기본 키 매핑 3가지 전략

  • 직접할당
  • 대리 키
    • 자동증가 : 최대한 사용말아야.. ( 두번 db에 갔다와야해서 영속성 컨텍스트의 이점이 사라지는듯하다)
    • sequence: 한번에 id 여러개 할당받음, 그러나 모든 db에서 sequence 기능을 제공하는 것은 아니다... @SequenceGenerator를 사용함
    • table: sequence의 역할을 하는 테이블을 사용하는 방법 @TableGenerator를 사용함

자연키: 주민번호, 이메일, 전화번호

대리키: 비즈니스와 관련없는 임의로 만들어진키

→ 대리키를 pk로 사용추천

@Enumerated : Enum 타입 사용 용도 String 사용추천 , ORINAL은 enum의 변경에 취약할 수 있음

@Temporal : 자바의 날짜와 호환되는 타입, DATE, TIME, TIMESTAMP

@Lob : blob과 clob

@Transient : 매핑하지 않는 필드

@Access : 변수에 직접접근인지 getter를 사용하여 접근인지


5장

가장 단순한 외래키 매핑 N:1 매핑

@ManyToOne

@JoinTable

다대일 관계에서 ( 다수가 연관관계의 주인)

setter에서 양방향으로 모두 저장되는 것처럼 설정하자 ( 실제로는 안되겠지만..)

this.team = team

team.getMembers().add(this)

주인이 아닐경우

@OneToMany

@JoinTable(mappedBy ="team")

mappedBy를 사용해야함