아래는 김영한 강사님의 스프링 jpa 활용 1편을 듣고 정리한 내용이다.
프로젝트 환경설정
참고할만한 것들
thymeleaf:모던 서버 사이트 자바 템플렛 엔진 JSP 와 비교된다
JSP 나 그런 것들은 서버를 통해야만 여는 것이 가능했다. 그러나 thymeleaf 는 안그래도 된다.
Model에 데이터를 실어서 view에 넣기 가능
implementation 'org.springframework.boot:spring-boot-devtools'로
서버를 껐다 켰다 할 필요없이 변경사항을 반영하는 것이 컴파일로만 가능해짐
처음 db 생성: 파일 생성 모드
이후에는 TCP네트워크 모드
Repository에서 저장을 하고 나면 return 값 안만드는게 좋은데
ID 정도 있으면 조회하기 편하다.
엔티티 매니저를 통한 데이터 변경은 항상 transaction 안에서 이루어져야
@Transactional 이 @Test에 있으면 defualt가 rollback이다.
같은 transaction 안에서 저장하고 조회하면 영속성 컨텍스트가 똑같다. 같은 영속성 컨텍스트 안에서는
아이디 값이 같으면 같은 Entity로 식별(1차 캐쉬)
도메인 분석 설계
1대N 관계
->연관관계 주인을 정해야 함. -> 외래 키가 있는 주문을 연관관계의 주인으로 정함.
Member->mapped by:거울 이라 생각, 단순 읽기만 가능 ,조회용
Order-> 연관관계 주인 ,연관관계 주인 쪽에 값을 세팅해야 값이 변경된다
주문 상품과 단방향 관계
ORDER_ITEM 과 ITEM 은 단방향 관계, item 입장에서 나를 주문한 order item을 다 찾아
이럴 필요가 없기 때문에 단 방향관계로 설정하였다.
객체는 many to many 가 쉽지만 table 관계는 어렵다.
외래 키가 있는 곳을 연관관계의 주인으로 정해라
1대 N 다시 강조
order 의 회원을 바꿀때 값을 바꿀수도 있고 member 에서 값을 바꿀수도 있따
JPA 는 둘 중에 뭘 믿어야 하는가?
둘 중에 하나만 하자
다가 연관관계 주인
CascadeType.ALL
->persist를 전파한다
예를 들어서 orderItems 에다가 데이터를 넣어두고 order 를 저장하면 orderItems도 같이 저장된다.
em.persist(A); em.persist(B);, em.persist(C);em.persist(order);를 em.persist(order)로 한꺼번에 저장이 가능하다.
ex)Order 가 delivery 관리를 하기 때문에 이럴 경우엔 Cascade 쓰는게 좋다.
연관관계 편의 메서드
연관관계 편의 메서드는 Control 하는 쪽에 둔다.
양방향일때 쓰면 좋다고 한다.
상속 처리
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
:한 테이블에다가 자식의 모든 column들을 떄려 박는다
JOINED: 정교화된 스타일
TABLEPERCLASS: 도 존재
@DiscriminatorColumn(name="dtype")으로 자식 구분이 가능하다
1대1 관계
order 와 delivery 같은 1대1 관계에서는 주로 access를 많이 하는 곳에 둔다.
delivery를 가지고 order 를 찾는 일은 없을 테니 order 에다가 forein key를 둔다.
EnumType
@Enumerater(EnumType.STRING)
EnumType.ORDINAL 은 중간에 다른 상태가 생기면 망한다.
Embeddable 에서는...
JPA 가 생성할때 reflection,proxy 가 필요하므로 기본 생성자를 사용한다.
-->protected Address(){} -->GOOD
설계 주의점
모든 연관 관계는 지연 로딩으로 설정한다.
@ManyToOne, 등 @-toOne은 기본이 즉시 로딩이므로 지연로딩으로 꼭 설정한다(N+1)문제.
em.persist 에 대해서
영속성 컨텍스트에 멤버 객체 넣고 트랜잭션이 commit 되는 시점에 DB 반영
같은 Transaction 안에서 ID 값이 똑같으면 같은 영속성 컨텍스트에서 똑같은 애가 관리
JPQL 이란?
SQL 은 테이블 대상으로 쿼리를 날리고, JPQL 은 엔티티 객체를 대상으로 쿼리를 날린다.
Transaction
JPA 의 모든 데이터 변경은 transaction 안에서 처리 되어야 한다!
create
create:Drop 한 후에 다시 create, create-drop은 create 랑 똑같은데 마지막에 drop --> 자원정리
비즈니스 로직에 관해서...
엔티티 자체에서 해결 가능한 그런 것들은 entity 안에 비즈니스 로직을 넣는게 좋다.
그것이
객체지향 이기 때문.
엔티티가 비즈니스 로직을 가지고 객체지향의 특성을 적극 활용하는 것을 -->도메인 모델 패턴
엔티티에는 비즈니스 로직이 거의 없고 ,서비스 계층에서 대부분의 비즈니스 로직을 처리하는 것을 트랜잭션 스크립트 패턴이라고 한다.