[백엔드] 스프링 부트와 JPA 활용 2 - 도메인 분석 설계

유승선 ·2022년 7월 19일
1

JPA 기본 정리

스프링 입문 강의에서 내가 어려워서 생략한 JPA 강의를 다시 들어보았고 이제는 이해가 가는 부분이 많기 때문에 정리해서 적어본다.

JPA 는 객채와 오브젝트를 매핑 하는데, 어노테이션이 필요하고 대표적인 어노테이션으로는 @Entity 가 있다.

그리고 PK (Primary Key) 또한 설정해줘야하는데 여기서는 @Id, @GeneratedValue() 어노테이션을 써준다. 어노테이션을 가지고 데이터베이스와 매핑이 되는것이다. 이 정보를 기준으로 Insert, Select 문이 동작이 되는것이다.

JPA는 EntityManager 이란느것으로 모든것이 동작이 된다. 패키지에 이미 포함되있기 때문에 아무런 코드 없이 EntityManager 이 생성이 될 수 있다. 결론적으로 말하면 JPA를 쓸려면 EntityManager이 필요하다.

Persist 자체의 뜻은 저장하다라고 볼수있는데, EntityManager 클래스를 이용해서 em.persist(value) 를 하게되면 JPA가 INSERT 쿼리를 디비에 넣어주고 ID 또한 만들어준다.

find() 라는 EntityManager 메서드를 쓰게되면 find(type,pk) 값으로 데이터 타입과 식별값만 넣는것만으로도 조회가 된다. EX: em.find(Member.class, id);

ID 같은 PK 값으로 조회하는게 아닌 findByName 같이 이름으로 조회하는 메서드 혹은 findAll() 같이 전체를 조회할 경우에는 JPQL 이라는 쿼리 언어를 직접 입력해야한다. 이것은 객채를 대상으로 쿼리를 쓰는것이다.

EX: em.createQuery("select m from Member m",Member.class).getResultList()

JPA 를 쓸때는 항상 어노테이션인 @Transactional 이 필요하다 (데이터를 저장하거나, 변경할때)

도메인 모델과 테이블 설계

꽤 많은 SQL 지식이 요구 됐었던거 같고 기본편을 안들었던 체로 도메인 모델과 테이블 설계를 이해할려고 하니 힘든 시간을 가졌었다.

이 테이블에서는 회원과, 주문, 등등에 테이블에 많은 관계를 주입 시켜줬는데 정리하자면 아래와 같다.

연관관계 매핑을 분석할때 강의에서는 외래 키에 대한 중요성을 강조했고 연관관계의 주인으로 설정하는것에 대한 설명을 했지만 자세히는 잘 몰랐었다. 앞으로 코드를 계속 쓰다보면 더 배우겠지만 당장은 이런게 있다고만 생각해야겠다. 다만 이 강의에서 중요했던 점 중 하나는 실무에서는 @ManyToMany를 사용하지 말라고 강조했었다.


엔티티 클래스 개발 1,2

Member 클래스

멤버 클래스는 이렇게 써주었고, 새롭게 배운거로는 @Embedded 라는 내용이 있다. Embeded 설명 이곳에 더 자세한 설명이 나와있으며 가독성이 높이기 위한 클래스 활용이라고 생각된다.

그 외에 PK 컬럼 명을 따로 지정한 이유는 위에 설명과 같다.

Order 클래스

이해하기 어려운 컨셉또한 많이 나왔지만, 아까 도메인 분석편에 나와있었듯이 어노테이션이 많이 붙어 헷갈리겠지만 근본적으로 데이터 멤버들을 생성해준 뒤에 @JoinColumn() 어노테이션으로 Foreign Key에 이름을 지정해주었고 그 외에 LocalDateTime 이라는 시간 클래스를 활용 했으며, @Enumerated 를 String 으로 설정하면서 주문 상태를 나타내는데 더 이해가 높아지는 방법을 사용했다.

주문상태

주문상태 엔티티

상품 엔티티

아이템 같은 경우는 바로 밑에 도서, 음반, 영화 엔티티가 상속을 받을것이기때문에 abstract 클래스로 만들었고 카테고리와도 다대다 관계를 유지해야 했기때문에 추가 어노테이션과 함꼐 mappedBy 를 넣어서 읽기 전용으로 만들었다

가장 이해가 안됬던 부분중 하나는 @DiscriminatorColumn 이었는데 이거는 좀 더 기본편을 참고해봐야할거같다

상품 - 도서 엔티티

상품 - 음반 엔티티

상품 - 영화 엔티티

배송 엔티티

배송 상태

카테고리 엔티티

카테고리 엔티티는 유일하게 @ManyToMany 가 설정되어있지만 이것은 추천하지 않는 방법이고 이유는 아래와 같다

주소 값 타입


엔티티 설계시 주의점

Setter 을 가급적 사용하지 말자

Setter가 현재는 모두 열려있는데 lombok 을 이용해서 어노테이션이 굉장히 쉽다. 그러나 Setter 가 많게 되면 변경 포인트가 너무 많아서 유지하기 어렵기 때문에, 나중에 전부 제거해줄것이다.

모든 연관관계는 지연로딩으로 설정!

지연로딩에 대한 자세한 이유와 주의점을 설명 해주었는데 아직 체감상 확 와닿지는 않는다. 지연로딩 중요성 여기 있는 웹사이트를 이용해서 한번씩 확인해보는것도 좋을거같다.

컬렉션은 필드에서 초기화 하자

이거는 어떻게보면 매우 간단해 보이지만 참고하면 중요할것같다. 하이버네이트에 대한 자세한걸 모르기때문에 일단 따라가는게 중요할거같고 컬레션을 필드에서 초기화 한다는것은

이렇게 만들고 그냥 냅두라는 말이랑 같다.

  • 추가로 Cascade에 대한 설명도 했는데

위처럼 persist 를 하게되면 OrderItem 안에 있는 모든 목록을 하나하나 해줘야하지만 CascadeType.All 을 설정하게 되면 그냥 persist(order) 하나로 전부 해결이 된다고 했다.


느낀점

이렇게 강의가 끝났는데 생각보다 굉장히 길었던 강의였다. 물론 주말에 좀 밍기적 거리고 늦게 봤던 감도 있었지만 강의를 2번씩 정주행 해서 보다보니 이해 안갔던 부분도 이해가 갔다. 애초에 JPA와 매핑, 그리고 자바 클래스에 상속성에 대해 정말 야매로 얕은 지식으로 알고있는 정도라 앞으로 기본편을 포함해서 SQL에 대한 전반적인 지식을 더 갈고 닦아야겠다.

몇가지 어노테이션을 빼고는 대체로 이해가 갔던 강의였다.

profile
성장하는 사람

2개의 댓글

comment-user-thumbnail
2022년 7월 20일

잘 보고 갑니다! 다 잊어버린 스프링 복습할 생각인데, 공부하면서 참고하겠습니다 ㅎㅎ

1개의 답글