JPA

우야·2021년 7월 16일
0

JPA Annotation

ORM이란?

JAP란?

  • 표준 명세 : JSR 338 - Java Persistence 2.2
    • Object relational mapping

Spring Data JPA란?

  • Repository 추상화를 통해 inference 선언만으로 구현
  • 메서드 이름으로 쿼리 생성
  • Web Supprt(페이징, 정렬, 도메인 클래스 컨버터등)

Spring에서 JPA 사용을 위한 설정

  • spring-data-jpa, hibernate-entitymanager 의존성 라이브러리 추가
  • EntityManagerFactoryBean, JpaTransactioniManager 빈 등록

Entity 클래스 설정 Annotation

@Table(name=xxx) : 맵핑된 Table 이름
@Entity : JPA가 관리할 객체임
@ID : ID Colum으로 사용
@GeneratedValue : ID를 자동 생성할때 사용 
   - TABLE, SEQUENCE(Oracle), IDENTITY(MySQL), AUTO 전략
@Temporal : 날짜 사용시 
   - Date, Time, Timestamp
@EmbeddedId : 복합 PK 사용할때
@Colum : DB Table의 Colum과 맵핑
@Transient : DB Table의 Colum과 맵핑하지 않는 field에 사용
@Enumerated : Enum(열거형) 맵핑
@Lob : CLOB, BLOB 매핑
- CLOB : String, char[], java.sql.CLOB 
- BLOB : byte[], java.sql.BLOB

연관관계

  • 단방향, 양방향
    양방향 연관관계
  • 관계의 주인
    • 연관 관계의 주인은 외래 키가 있는 곳
    • 연관 관계의 주인이 아닌경우, mappedBy속성으로 연관 관계의 주인을 지정해야함
@JoinColum : 외래키와 맵핑
@ManyToOne : 다대일
@OneToMany : 일대다
@OneToOne : 일대일
@ManyToMany : 다대다

ManyToOne의 예제

연관 관계 영속성 전이

  • Table의 레코드가 생성, 저장, 삭제 될때, 연관된 Entity도 같이 생성, 수정, 삭제되게 하기 위한 방법
CasecadeType.ALL : 모두 반영
CasecadeType.PERSIST : 
CasecadeType.MERGE
CasecadeType.REMOVE
CasecadeType.REFRESH
CasecadeType.DETACH

Fetch 전략

FetchType.EAGER : Entity가 로딩될때, 연관된 Entity도 같이 로딩
FetchType.LAZY : Entity가 연관 Entity를 참조 할때 로딩

  • Fetch 추가
    • @ManyToOne(fetch = fetchType.eager)일때,
      • 참조되는 객체를 select해서 같이 가져오는데 이때, 내부적으로 원래 객체 select + 참조 객체 select 가 불리게 된다.
      • 이때 하나의 select와 join으로 가져오게 할수 있는 방법은
        • class에 @NamedEntityGraph("memwithteam", attributeNodes=@NamedAttributeNode("team") 선언한다.
        • findAll api에 @EntityGraph("memwithteam")로 재 정의한다.

interface만 상속하면, JpaRepository의 기본 기능 사용

  • CRUD
  • Paging
  • Sorting

기본 interface사용시 jpa 내부에서 실제 sql문이 생성되어 사용되어 짐으로 사용자는 interface를 사용

메서드 이름으로 쿼리를 생성하는 기능

  • Spring Data JPA에서 제공하는 기능으로 이름 규칙에 맞춰 interface에 선언하면 쿼리 생성
  • findBy, Like, existesBy, And, countBy, deleteBy, Between ...

public interface ItemRepository ... {
// select * from Items where item_name like '%{itemName}%'
ItemEntity findByItemNameLike(String itemName);

// select item_id from Items where item_name = '{itemName}'
// and price = {price} limit 1
boolean existsByItemNameAndPrice(String itemName, Long price);

// select count(*) from Items where item_name like '%{itemName}%'
int countByItemNameLike(String itemName);

// delete from Items where price beteween {price1} and {price2}
void deleteByPriceBetween(long price1, long price2);
}

Pagenation구현은 어떻게 하나?

  • Controller의 Pageable 인자 추가 함
    • xxxx?page=0&size=30 형태로 request를 받을수 있음
  • Repository에 Pageable 인자 추가 및 return Page으로 collection전달

복잡한 쿼리는 어떻게 하나?

  • JPQL : 엔티티 객체를 조회하는 객체 지향 쿼리
  • Criteria API : JPQL을 생성하는 빌더 클래스
  • tirdparty library를 이용하는 방법
    • Querydsl
    • jOOQ
    • ...

단점

  • 상대적으로 높은 학습 곡선
    • 하지만, 기술적인 장벽을 낮춰줄 여러 솔루션 존재
      • Spring Data JPA, QueryDSL 등
  • JPQL에는 한계가 있다.
    • where 절에 임시테이블로 사용하는 inline view같은것을 사용할 수 없음
    • 하지만, Native SQL, 다른 Data Access기술과 혼용/분리 가능

참고 : https://www.youtube.com/watch?v=XQZY0yN9gz0

profile
Fullstack developer

0개의 댓글