자바 ORM 표준 JPA 프로그래밍 #1~5
1장
SQL을 직접 다루면 문제의 소지들이 있음!
(jdbc 사용시 table에 변경이 있다면 바꿔야 할 코드가 많음)
→ JPA를 사용하자!
뿐만 아니라 패러다임의 불일치가 발생
⇒ 객체와 테이블은 다르다!
- 객체- 상속가능, 테이블 -불가능
- 객체는 탐색이 가능하지만, 테이블은 탐색시 join을 해야하며, 많이하면 비용이 엄청남
- 또한 객체는 연결이 단방향, 테이블은 양방향
⇒ 이런 패더라임의 차이로 개발자가 많은 시간을 투자해야했음
⇒ 위의 문제들을 JPA가 해결해줌 ( 개발자의 개발시간을 많이 단축해줌)
⇒ 복잡한 통계정보같은 것들은 여전히 sql을 사용해야함
2장
- 기본적인 JPA 프로젝트( 여기에 사용된 기본적인 어노테이션들 소개)
- JPA의 구조 ( DB마다 방언이 있는데, 그래서 db마다 구현체를 사용해줘야함 JPA는 인터페이스)
- 엔티티 매니저에 대한 소개 ( 엔티티 매니저 팩토리(하나만 써야함)로 부터 생성) ⇒ 스프링 부트에서는 알아서 관리됨
- tx.begin tx.commit 사이에 비즈니스 로직을 넣어서 관리 ( 한번에 배치로 sql들이 처리됨)
3장
매번 객체를 db에 저장하는 것이아니라, 메모리상에 저장(영속)해두었다가 tx.commit시에 전송함
메모리상에서 더이상 관리 안하는 상태(준영속)로 바꿀수도 있음
이렇게 관리함으로 얻을 수 있는 이점들
- 1차 캐시 - 저장후, select할때 메모리에서 가져와도됨 ( 만약 여기서 저장한 row라면!)
- 동일성 보장 - 메모리에서 객체를 가져오기 때문에 == 가 참으로 나옴
- 트랜잭션을 지원하는 쓰기 지연 - 배치 처리로 최적화(여러번 왔다갔다 하지 않기)
- 변경 감지 - 스냅샷을 사용하여 변경된 점이 있다면 수정된 부분에 대하여 update
- 지연 로딩 - 실제 객체 대신 프로식 객체를 로딩해두고 해당 객체를 실제 사용할 때 영속성 컨텍스트를 통해 데이터를 불러오는 방법이다. → 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를 사용해야함