JPA 정의
JPA(Java Persistence API)
- 자바 진영의 ORM 기술 표준 (자바에서 RDB를 사용하는 방식을 정의한 인터페이스)
- ORM(Object Relational Mapping) = 객체와 RDB의 데이터를 자동으로 매핑(연결)해주는 것
=> 어플리케이션의 객체를 RDB 테이블에 자동으로 영속화 해주는 것
- 자바 환경에서 반복적인 SQL CRUD 처리에 용이함
- Repository 인터페이스 개발 후 구현체 선언 시 인터페이스명+[Impl]로 구현체명을 정의해야 Spring Data JPA가 인식
- JPA는 persistence.xml을 사용해서 필요한 설정 정보를 관리
※ Persistence(영속성) = 데이터를 생성한 프로그램의 실행이 종료되더라도 사라지지 않는 데이터의 특성
테이블 매핑 어노테이션
- @Entity = 테이블 설정
- @Id = 기본키(PK) 설정
- @Column = 컬럼 속성 설정 (name=컬럼명, length=문자일경우 varchar 길이, updatable = 데이터 수정 가능 여부, ...)
※ 매핑 어노테이션을 생략하면 DB 컬럼명 = 필드명으로 자동 매핑됨
- @Enumerated = 해당 필드의 타입이 enum일 경우 필수 입력!
(Enum의 데이터 타입을 지정해줘야 함 기본 = int, String으로 출력시 eunmType.String입력)
- @Temporal = 해당 필드가 자바 Date 타입일 경우 DB에서의 날짜 데이터 형태 입력
- @GeneratedValue = 기본키(PK) 값 생성 전략 설정
※ strategy = GenerationType.IDENTITY => DB가 알아서 auto_increment
※ strategy = GenerationType.TABLE => 기본키 관련 테이블(hibernate_sequences) 생성 후 데이터 추가때마다 참조되어 auto_increment를 구현할 수 있도록 해줌
JPQL (Java Persistence Query Language)
- SQL과 비슷한 문법을 가진 자바의 객체 지향 쿼리
- 쿼리문 입력시 * 사용 불가
EntityManager(em) 메소드
- em.find(클래스, 기본키) = 입력한 기본키에 해당하는 데이터를 지정한 클래스 타입으로 반환
- em.persist() = DB에서 해당 객체 추가
- em.remove() = DB에서 해당 객체 삭제
- em.createQuery(String타입 쿼리문) = 쿼리 생성 ()
(추가적으로 해당 쿼리문 실행시 반환받을 객체의 클래스 타입 입력 가능)
※ 쿼리문에서 엔티티명을 입력할 때 무조건 첫글자는 대문자로 입력해야함
ex) em.createQuery("SELECT m FROM member m", Member.class) - 오류
em.createQuery("SELECT m FROM Member m", Member.class) - 정상 실행
※ 쿼리문에서 컬럼명을 입력해줄때 DB 기준(table)이 아닌 JPA 기준(Entity)으로 컬럼명을 입력해 줘야함
ex) product_type(X) => productType(O)
Query, TypedQuery
- TypedQuery = 반환되는 엔티티가 정해져 있을 때 사용하는 타입 (createQuery에서 .class 입력 O)
- 보통 TypedQuery<타입> 으로 입력됨
- TypedQuery 객체의 getResultList() 메서드 = 결과값 리스트(List)로 반환
- Query = 반환되는 엔티티가 정해져 있지 않을 때 사용하는 타입 (createQuery에서 .class 입력 X)
두 엔티티 간 연관 관계(JOIN) 설정
어노테이션
- [@엔티티To필드] 형식으로 어노테이션이 구성되어 있음
- @JoinColumn(name=) = 자식 엔티티에서 보여질 부모 컬림명 설정
- @OneToOne = 1(엔티티):1(필드) 관계 설정
- @OneToMany = 1(엔티티):다(필드) 관계 설정
- @ManyToOne = 다(엔티티):1(필드) 관계 설정
- 한쪽에서 @OneToMany를 설정했으면 다른 한쪽에서는 @ManyToOne를 필수적으로 설정해줘야함
(@OneToOne은 한쪽에서 적용하면 다른 한쪽에 적용할 필요 X)
다대일, 일대다 관계 (@OneToMany, @ManyToOne)
- fetch = 데이터 조회 방식 설정
- FetchType.EAGER = 즉시 로딩 설정 (@ManyToOne의 기본값)
- FetchType.LAZY = 지연 로딩 설정 (@OneToMany의 기본값)
- 즉시 로딩(EAGER)은 데이터를 조회할 때마다 연관된 데이터까지 한 번에 불러오는 것이고, 지연 로딩(LAZY)은 필요한 시점에만 연관된 데이터를 불러오는 것
=> LAZY는 엔티티에서 해당 필드를 참조할 경우에만 해당 필드의 데이터를 불러오도록 하는것 (데이터를 유동적으로 불러오기 때문에 메모리 절약에 효과적) => @ManyToOne(fetch=FetchType.LAZY)를 많이 사용함
- mappedBy = 두 엔티티의 컬럼 사이에서 부모 지정 (자식 컬럼에서 설정 - 1:다의 경우에는 @OneToMany에서 설정) => 양방향 관계 설정