1. 복습 

cascade하면 부모 객체만 저장하면 관련된 자식 객체는 자동으로 persist 된다 

2. 애플리케이션 아키텍쳐

-계층형 구조 사용

controller,web: 웹 계층

service: 비즈니스 로직, 트랜잭션 처리

repository: JPA를 직접 사용하는 계층, 엔티티 매니저 사용

domain: 엔티티가 모여 있는 계층, 모든 계층에서 사용

 

3. @SpringBootTest

컴포넌트 스캔을 해서 스프링 빈에 컴포넌트를 등록한다 

4. 테스트 시 Rollback 하는 이유

: db에 테스트 데이터를 남기지 않기 위해서  

5. 스프링 부트가 설정이 없으면 기본으로 메모리 모드로 돌린다

6.  엔티티에 비즈니스 로직 

엔티티 안에 비즈니스 로직을 넣는 것이 좋다(객체지향적인 방법)

데이터를 가지고 있는 곳에서 로직을 실행하는 것이 응집력이 있음

 

1) Order.class

 

- 생성 메서드

Order에서 참조하는 member,delivery,orderItem을 파라미터로 받고 set으로 설정해준다

orderItems는 리스트이므로 반복문으로 하나씩 order에 추가해준다 (여기가 익숙하지 않다)

order가 생성된 것이므로, orderStatus는 ORDER로 설정하고, 현재 시간을 설정해준다 

 

-비즈니스 로직: 주문을 취소한 경우에 대해 구현했다

먼저 해당 상품이 배송중인지 아닌지를 확인한다 

배송중이라면 illegalstateexception("이미 배송 완료된 상품은 취소가 불가능합니다") 설정하고, OrderStatus를 CANCEL로 바꿔준다(setStatus)

배송중인 상품이 아니라면, 각각의 orderItems에 대해서 cancel을 실행한다

 

-조회로직: 주문갯수와 가격을 고려해서 총가격을 가져오는 메소드이다 

 

2) OrderItem.class

 

-OrderItems 생성메서드 

아이템을 구성하는 것들을 set으로 설정한다음 item이 stock에서 count만큼 줄인다

 

 

-OrderItems 취소 비즈니스 로직

: 취소한만큼의 stock을 item에 추가해준다 

 

-주문상품 전체 가격조회 

전체 가격은 주문 가격*갯수이므로 그것으로 구현해준다 

 

7.  현재 문맥에서 가장 적합한 패턴 사용하기(예제에서는 도메인 모델 패턴)

-도메인 모델 패턴: 엔티티가 비즈니스 로직을 가지고 객체 지 향의 특성을 적극 활용하는 것

8. 연관관계 편의 메소드

양방향 연관관계를 가진 엔티티들에서 값 변경이 일어날때 양쪽 모두에 변경된 값을 입력을 할 수 있게 하는 메소드이다 

강의: 인프런 JPA+SpringBoot 활용 1편 

1. jpa 기본 내용 복습

- 같은 트랜잭션 안에서는 영속성 컨텍스트 조회. 같은 영속성 컨텍스트에서 아이디 같으면 같은 엔티티로 인식. 1차 캐시에서 가져옴

- 값 타입은 변경 불가능하게 설정하기 

- 실무에서는 @ManyToMany 사용하지 않기 

2. 개발 시작 단계에서 해야할 것들

-요구사항 분석

-도메인 모델 설계

-엔티티 설계

-테이블 설계: DB에서는 소문자+_ 형태로 주로 사용한다

3. 테이블에서 외래키가 있는 곳을 연관관계의 주인으로 정하기 

4. 쿼리 파라미터 확인하는 방법 : p6spy

쿼리 파라미터 로그 남기는p6spy를 이용해서쿼리 파라미터를 확인   있지만, 잘못하면 성능을 저하시키거나 병목현상을 발생시킬  있다. 되도록이면 개발 단계에서 하는 것을 추천 

p6spy이용했을 때 출력된 쿼리. 파리미터를 확인할 수 있다 

5. 엔티티 설계시 주의점 

 

1) 엔티티에는 가급적 Setter를 사용하지 말자

setter를 사용하면 변경 포인트가 많아져서 유지보수가 어려워진다

 

2) 모든 연관관계는 지연로딩으로 설정하자(fetch=FetchType.LAZY)

즉시 로딩은 예측이 어렵고, 어떤 sql 실행될지 추적하기가 어렵다jpql에서 n+1 문제가 발생할 있기 때문이다 

 

3) 컬렉션은 필드에서 초기화하자(@RequiredArgstructor, private final 이용)

이렇게 하면 null 문제에서 안전하고, 임의의 메서드에서 컬렉션을 잘못 생성하면 하이버네이트 내부 메커니즘에 문제가 발생할 수 있다. 

 

6. em.find() vs JPQL

em.find(): 영속성 컨텍스트를 먼저 조회하고 없으면 SQL을 실행한다

JPQL: SQL을 먼저 실행한다 

 

7. @Controller vs @RestController

@Controller: view를 반환하기 위한 Controller 개발 시 사용한다

강의에서는 thymeleaf를 통해 서버사이드에서 view를 렌더링하기위해 @Controller를 사용했다 

 

@ResponseBody(Controller+ResponseBody): Data(Json Format)을 반환하기 위해 사용한다 

vue.js를 통해 프론트개발을 한다거나 단순히 data를 반환해야하는 api를 개발할 때 사용 

 

8. @Transactional

DB에 접근하는 메소드를 작성할 때 @Transactional 어노테이션을 추가해야 다음과 같은 에러가 발생하지 않는다 

 

이유는 기본적으로 JPA는 transaction을 기반으로 작동하게 되어있다. 

transation 단위에 따라 1차캐시 영역에 있는 객체들이 db로 flush되어 영속화되기 때문이다

 

하지만 그러한 영속작업을 하는 persist()메소드에 객체가 들어갔으나 가능한 transaction이 존재하기 않았기에 위와같은 에러가 발생했다.

변경을 하지 않는 메소드에는 @Transactional(readOnly=true)를 선언하자

 

 

9. 하나의 엔티티에서 두 필드가 서로를 참조하는 경우(부모-자식관계)

+ Recent posts