본문 바로가기

끄적끄적/Spring Boot

Spring Boot 프로젝트 필기

JPA_프로그래밍

Maven 사용

 

라이브러리는 어떤 버전을 사용해야할까?

  • 사용할 스프링 부트의 Ref.Doc에서 사용할 라이브러리의 버전을 확인
  • 여기서는 스프링 부트를 사용하지 않기 때문에 버전 상관x

 

JPA 설정

JPA를 사용하려면 몇가지 세팅 파일을 넣어야 한다.

  • persistence.xml 생성 후 프로젝트에 저장

 

Persistence.xml

데이터베이스 접근 정보 입력

1개의 .xml당 하나의 데이터베이스라 생각

 

검색

EntityManagerFactory

: 고객 요청이 올때마다 EntityManager 생성

EntityManager

: 내부적으로 데이터베이스 커넥션을 사용하여 DB사용

EntityTransaction

 

 

영속성 관리

JPA 이해 == 영속성 컨텍스트(문맥, 환경) 이해

JPA

: “Entity를 영구 저장하는 환경"



Ex) EntityManager.persist(entity);

  • 위 예제는 단순히 entity를 DB에 저장하는 것으로 끝나는게 아님
  • 영속성 컨텍스트를 통해 Entity를 영속화

persist()

: DB에 저장하는게 아닌 Entity를 영속성 컨텍스트라는 곳에 저장

영속성 컨텍스트는 논리적 개념

 

EntityManager => PersistenceContext > 1:1 생성으로

: EntityManager 안에 눈에 보이지 않는 영속성 컨텍스트 공간이 생성

 

새 객체를 만듦 > 비영속

만든 객체를 persist()에 넣음 > 영속(관리 시작)

단, 이때 DB에 바로 저장되는거 아님

DB Query는 트랜잭션의 Commit이 되는 시점에 쿼리 실행

준영속

: 영속성 컨텍스트에 객체 지움

삭제

: 실제 DB 삭제를 요청하는 상태

 

[애플리케이션 ] - [영속성 컨텍스트] - [데이터베이스]

위와 같이 영속성 컨텍스트는 애플리케이션과 데이터베이스 사이의 중간계층으로 있는 형태

 

flush()를 하면 1차 캐시가 다 지워질까? No

영속성 컨텍스트 내의 쓰기지연 SQL 저장소에 있는 내용 중 변경이 된 것들이 있다면 SQL update를 준비했다가 데이터 베이스에 반영하는 과정

엔티티 매핑

: 실제 설계적인 측면으로, 객체와 관계형 데이터베이스를 매핑 

 

객체와 테이블 매핑

@Entity

@Table

데이터베이스 스키마 자동 생성

 

필드와 컬럼 매핑

기본 키 매핑

예제, 요구사항 분석과 기본 매핑

연관관계 매칭 기초

연관관계가 필요한 이유

객체를 테이블에 맞추어 데이터 중심으로 모델링하면, 협력 관계를 만들 수 없다.

 

책 추천

  • 객체지향의 사실과 오해(조영호 저)
  • 오브젝트(조영호 저)

객체 지향스럽게 설계하는 것이 어려운 내용을 설명하는 책

단방향 연관관계

@ManyToOne

@JoinColumn(name = “조인할 테이블의 컬럼”)

 

양방향 연관관계와 연관관계의 주인

테이블은 PK를 이용

  • Member에서 Team을 알 수 있고,
  • Team에서는 TeamId를 가진 Member를 Join하여 알 수 있다.

객체

  • Member는 Team 객체를 사용
  • Team은 List Member를 사용

 

@OneToMany(mappedBy = “변수명”)

  • 나의 반대편에는 해당 변수명을 통해 매핑되어있다는 것을 알려줌

규칙

  • 객체의 두 관계중 하나를 연관관계의 주인으로 지정
  • 주인만 외래키를 관리(등록, 수정)
  • 주인이 아닌 쪽은 읽기만 가능
  • 주인은 mappedBy 속성 사용 x
  • mappedBy는 누구를 주인으로 할지를 지정



결론

객체에서 연관관계의 주인은 DB로 치환했을 때 외래키를 가진 객체가 주인이다.

주인에서 값이 생성&변경 되었을 때는 DB에 반영되지만

주인이 아닐 경우(mappedBy 속성 사용) 생성&변경을 해도 DB에 반영되지 않는다.

 

가급적 단방향이 좋긴하다.

양방향은 신경써야 할 내용이 많음

주의

순수한 객체관계를 고려하면 항상 양쪽 다 값을 입력해야한다.

만일 team.getMembers().add(member)를 안 할 경우

List<Member> members = findTeam.getMembers()를 호출 할 때, DB의 데이터가 아닌 1차 캐시(영속성 컨텍스트) 안에 있는 데이터를 불러오기 때문.

중간에 flush(), clear()가 있으면 DB에 쿼리를 날리기 때문에 데이터를 불러올 수 있다.

 

휴먼에러를 방지하기 위해 갑 또는 을측을 선정 후 메서드를 생성

setter 또는 값을 변경하는 메서드에서 값을 세팅 후, 을 측의 List 컬렉션에 add(this) 실행



양방향 매핑시 무한루프 조심

  • 컨트롤러에서 Entity 자체 반환 금지
  • 단순하게 값만 있는 DTO로 변환하여 반환하는 것을 추천

실전 예제 2 연관관계 매칭 시작

다양한 연관관계 매핑

연관관계 매핑시 고려사항 3가지

다대일 [N:1]

일대다 [1:N]

일대일 [1:1]

다대다 [N:M]

실전 예제 - 3. 다양한 연관관계 매핑

고급 매핑

상속 관계 매핑

상속받은 테이블을 구분하기위해 DType은 있는게 베스트

 

주의

구현 클래스마다 테이블 전략은 사용하지 않기

> 반드시 후회됨

@MappedSuperclass

상속과 매핑에 상관 없음

반복되는 내용을 부모 엔티티로 두어 사용

 

 

프록시와 연관관계 관리

Member와 Team의 객체가 있을 경우 member 데이터를 가져 올 때 team 데이터도 가져오는 경우가 많을 경우에는 괜찮지만, 다른 프로젝트에서 member데이터만 가져와도 될 경우 낭비가 심함.

=> 이럴때 프록시와 지연 로딩을 활용

프록시

즉시 로딩과 지연 로딩

fetch 타입을 지연로딩(LAZY)로 설정하면 proxy로 설정이 됨

실무에서 즉시 로딩 사용은 가급적 지양

테이블이 복잡하게 얽혀있는 상태에서 즉시 로딩을 할 경우 DB의 성능이 급격히 떨어짐

영속성 전이: CASCADE

Child를 Parent만 소유할 경우는 상관이 없지만, Parent2도 Child를 소유할 경우 CASCADE.ALL은 위험

고아 객체

 

값 타입

기본값 타입

임베디드 타입(복합 값 타입)

값 타입과 불변 객체

값 타입의 비교

값 타입 컬렉션

 

객체지향 쿼리 언어_기본문법

분기에 따라 쿼리문의 변화가 생길 경우 동적으로 변해야 하는데 이는 문자열로 만드는데 한계가 있다. 그렇기 때문에 문자열 쿼리가 아닌 동적 쿼리에 유용한  Criteria를 사용

단, SQL 스럽지 않아 사용 안함

 

QueryDSL 사용   

기본 문법과 쿼리 API

프로젝션(SELECT)

조인은 웬만하면 다 직접 명시적으로 하는게 좋다 => 경로 표현식

  • 명시적 조인
  • 묵시적 조인

페이징

조인

서브 쿼리

FROM절 안될 경우 Native Query 사용

하이버네이트6에서는 FROM 서브쿼리 지원

JPQL 타입 표현과 기타식

조건식(CASE 등등)

JPQL 함수

경로표현식

  • 단일 값 연관 경로 "SELECT m.team FROM Member m";

묵시적 내부 조인이 발생할 경우 웬만하면 사용 x => 쿼리 튜닝에 어려움이 있다

JPQL 작성 시 SQL과 유사하게 짜 놓아야 편함

  • 컬렉션 값 연관 경로 "SELECT t.members FROM Team t";
  • members의 username을 알고 싶은 경우 묵시적 조인이 아닌 명시적 조인으로
  • "SELECT m FROM Team t JOIN t.members m"

패치 조인

  • Fetch 사용 안할 경우 "SELECT m FROM Member m"
  • 지연 로딩이 필수적으로 세팅 후 Fetch JOIN 사용

 

데이터베이스의 1대 다 데이터를 가져 올 때 데이터 뻥튀기 조심(다대 1은 x)

다영성 쿼리

엔티티 직접 사용

Named 쿼리

벌크 연산

 

'끄적끄적 > Spring Boot' 카테고리의 다른 글

개인프로젝트_서버 구상  (0) 2024.08.11
Spring Boot Querydsl  (0) 2024.07.26
Spring Boot Data JPA  (0) 2024.07.13
Spring Boot 강의 필기  (0) 2024.06.14