Spring Boot JPA (1)


ORM 

객체-관계 매핑 객체와 관계형 데이터베이스의 데이터를 자동으로 매핑해주는것 

  ORM DB
데이터 객체 테이블
관계 속성 FK, Join Key

 

ORM 사용 이유 

SQL 의존 개발, 코드의 반복 즉 데이터베이스 의존적 개발을 지양 하기 위해  

장점 

  • 비지니스 로직에 집중할 수 있다. 
  • 선언문 할당 등이 없어짐 
  • 코드의 재상용 유지보수성 
  • DBMS 종속성이 적다. => 데이터베이스를 교체해도 시간이 덜 걸릴 수 있다. 

단점 

  • N+1 문제 등 해결해야할 과제가 있다. 
  • 속도 저하(캐싱 기능 때문에 Case By Case로 속도 향상의 효과를 얻을 수 있다.), 일관성 저하 
  • 프로시져가 많은 시스템에서는 ORM 에서의 객체지향 장점을 사용할 수 없다. 

 

JPA(인터페이스)

Java 진형의 ORM 기술 인터페이스 임으로 구현체가 필요 하다. 

구현체 

  • Hibernate
  • OpenJPA

* MyBatis 와의 차이 

MyBatis는 Mapper Class 를 SQL 쿼리와 매핑시켜 DB의 데이터를 얻어오는 방식이라면 JPA 는 JPA Repository 의 Entity Manager를 통해 데이터를 가져온다. 

 

Hibernate, JPA, Spring Data Jpa 관계

  • JPA – Interface 
  • Hibernate – JPA 구현체 
  • Spring Data JPA(Repository) – JPA를 쉽게 사용하게 해주는 모듈 

Spring Data JPA 사용과 미사용

  • 사용:         DB —- JDBC —–Hibernate —– JPA —–Spring Data JPA —— APP(Service..)
  • 사용안함: DB —- JDBC —–Hibernate —– JPA —– APP(Service..) – EntityManager를 알아서 관리 해야함

 <참조>

 

JpaRepository

Repository<<Interface>>  <—-  CrudRepository<<interface>>  <—-  PaginAndSortingRepository<<interface>> <—-  JpaRepository<<interface>>

 

JPA 관련 Spring Boot Annotaion

@Entity

  • Name 속성으로 이름지정 가능, Name 속성 없으면 Class 이름
  • JPA에게 해당 객체가 테이블에 매핑되기 때문에 관리 대상이라는 것을 알려주는 Annotation

@Table 

  • 엔티티와 매핑할 테이블을 지정한다. 생략할 경우는 매핑한 앤치치 이름을 테이블 이름으로 사용한다. 
  • 속성: name(Entity 이름), catalog, schema

@Column(name =”id”)

식별자 PK의 name 속성을 매핑할 DB 테이블 칼럼을 지정 

@GeneratedValue

PK 를 생성하는 전략, 자동 증가 등등 .. 

  • AUTO(Default) – JPA 구현체가 생성방식 결정
  • IDENTITY – 사용하는 데이터베이스가 키를 결정 
  • SEQUENCE – 데이터베이스의 sequence를 이용해서 키를 생성 (@SequenceGenerator)
  • TABLE – 키 생성 테이블을 생성해서 키 생성 (@TableGenerator)

@id

@Enumerated

자바의 enum 타입을 매핑 EnumType.String 이름 지정 

@Temporal

날짜 타입 매핑 

@Lob

Blob 타입 매핑 

@Transient 

특정 필드를 데이터 베이스에 매핑하지 않는다. 예를 들면 PasswordConfirm 필드 PasswordConfirm필드는 Entity에만 필요하고 굳이 DB Table에 있을 필요는 없다 이때 해당 Annotation 사용 

@ManyToOne/OneToMany..

속성

  • optional => false 연관된 엔티티가 항상 있어야함
  • fetch => EAGER => 앤티티 가지고 올때 항상 연관 엔티티가져옴/ LAZY 사용될때 가져옴 프록시

@JoinColumn

@Query

QueryMethod로 처리가 힘든 복잡한 Query를 만들시 JPQL 과 함께 사용된다. JPQL 은 Table 대신 Entity, 칼럼대신 필드를 사용한다. 

@Modifying

@Repository

JpaRepository 사용 

@Commit

Transaction 결과를 DB에 반영 만약 없으면 Rollback 됨

그외

  • @Configuration
  • @PersistenceContext
  • @Getter
  • @Transactional – update 같은 경우 붙혀줘야 함 
  • @NoArgsConstructor – 인자값 없이도 생성자 호출 가능하도록 
  • @Builder
  • @EnableJpaRepositories

앤티티 매니져 

앤티티 매니져 팩토리 통해 생성, 쓰레드 간에 공유 금지 

 

엔티티 매니져 팩토리 

persistance.xml 설정 정보 JPA 기반객체 만들고 Connection pool 생성, 생성 비용이 큼으로 딱 한번만 생성 후 공유, 사용이 끝나면 종료 해줘야 함 Sping Boot가 알아서 관리 해줌 

 

Persistence context

영구 저장 환경, 

영속성 컨택스트 쓰는이유 

1차 캐시, 동일성 보장, 트랜잭션 지워하는 쓰기 지원(불필요한 IO 감소)

Flush 는 영속성 컨텍츠의 변경 내용을 데이터베이스에 반영 

 

연관관계 매핑 

ORM 참조 사용 , 방향성이 있음, 연관관계주인

N:1 관계에서 1 이 N을 못볼 수도 있다.

객체의 연관 관계는 항상 단방향이다. 양방향성이 가능한건 단방향이 두 개여서 가능 

 

연관관계의 주인 

외래키를 관리하는 객체, 관계 Annotation 에 mappedBy 속성이 없는 객체가 연관관계 주인이다. 

 

연관관계 매핑시 주의 사항 

다중성(N:1, 1:N, ….)/ 단방향, 양방향 고려 / 양방향일시 연관관계 주인

N; 1 관계

Team(1)

id (PK)

User(N)

team_id(FK)

외래키가 있는N쪽이 연관관계 연관관계의 주인 이여야 한다. 

1: N

JoinColumn을 항상 명시 해야 한다. 

문제 매핑한 객체가 관리하는 외래키가 다른 테이블에 있기때문에 연관관계 처리를 위해 update sql 을 추가로 실행 해야 한다. 

이런 문제 땜에 N;N 관계가 낮다. 

1:1

N:N

@JoinTable

 

고급매핑

상속관계매핑, 실별관계매핑,

MappedSuperclass, 복합 키와 식별 관계 매핑

식별관계 – 비식별관계 비식별관계를 쓰는게 낮다. 조인테이블

 

@MappedSuperclass

부모클래스는 테이블과 매핑하지 않고 부모 클래스를  상속받는 자식 클래스에게 매핑 정보만 제공하고 싶을때 

추상 클래스랑 비슷 @Entity는 실제 테이블과 매핑되지만 @MappedSuperclass는 그렇지 않다. 

단순히 매핑 정보를 상속할 목적일때 

@Entity Class 는 @Entity , @MappedSuperclass 만 상속가능 

연관관계 재정의시는 @AssociationOverride

 

프록시 

fetch Lazy 사용시… 데이터가 실제 필요할 때 데이터를 불러오는 지연로딩 사용시 실제 엔티티 객체 대신 사용되는 가짜 객체

특징 

처음 사용시 한번만

프록시 객체 초기화시 실제 엔티티에 접근 

영속성 컨택스트에 실제 엔티티가 존재하는 상황에선 프록시가 아닌 실제 엔티티 반환

준영속 상태의 프록시 초기화시 문제 발생 

Team 엔티티 조회시 연관관계인 팀원 조회는 필요할 때만 (Lazy)

 

JPA 기본 패치 전략

ManyToOne, OneToOne = EAGER

OneToMany, ManyToMany = LAZY

 

from 패스트캠퍼스 – 스프링아카데미아



블로그 구독하기 !!

You may also like...

댓글 남기기

이메일은 공개되지 않습니다.