[JPA] 엔티티의 개념

devlsn96·2024년 10월 24일
0

1. 엔티티 매핑

엔티티를 매핑할 때는 애너테이션을 이용하여 각 요소들을 매핑한다.

  • 객체와 테이블 매핑 : @Entity, @Table
  • 필드와 컬럼매핑 : @Column
  • 기본키 매핑 : @Id
  • 연관관계매핑 : @ManyToOne, @JoinColumn

1. @Entity

  • @Entity가 붙은 클래스는 JPA가 관리하는 엔티티라고 한다.
  • JPA를 사용해 테이블과 매핑할 클래스는 @Entity가 필수이다.
  • ✨ 주의할 사항은
    • 기본 생성자는 필수적으로 생성한다.
    • final class, enum, interface, inner클래스에서는 사용하지 않는다.
    • 저장할 필드에는 final 사용하지 않는다.
    • 클래스 이름을 그대로 사용하고, 같은 클래스 이름이 없으면, 기본값을 사용한다.

2. @Table

  • @Table은 엔티티와 매핑할 테이블을 지정하고
  • 속성은 다음과 같다.
    속성기능기본값
    name매핑할 테이블이름엔티티 이름을 사용한다.
    catalogDB의 catalog 매핑
    schemaDB의 schema 매핑
    uniqueConstraints(DDL)DDL생성 시에 유니크 제약 조건 생성

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

  • DDL을 애플리케이션 실행 시점에 (다음 표와 같은 옵션으로)테이블 자동 생성한다.
  • 테이블에서 객체 중심으로 작업을 처리를 하기 위해 데이터베이스 방언을 활용해서 데이터베이스에 맞는 적정 DDL를 생성한다.
    • 이렇게 생성된 DDL은 개발 장비에서만 사용 (운영에서 사용해서는 안된다)
    • 생성된 DDL은 운영서버에서는 사용하지 않거나, 적절히 다듬은 후 사용한다.
  • 운영 장비에는 절대 create, create-drop, update 사용하면 안된다.
    • 개발 초기 단계 : create 또는 update,
    • 테스트 서버 단계 : update 또는 validate,
    • 스테이징과 운영서버 단계 : validate 또는 none를 사용한다.

DDL생성 기능

제약조건 추가

  • 회원이름은 필수, 10자 추가 제한 조건일 때, @Column(nullable=false, length=10)

unique제약 조건 추가 조건 일 때,

  • @Table(uniqueConstraints = {@UniqueConstraint(name="NAME_AGE_UNIQUE", columnNames{"NAME","AGE"})})
  • DDL 생성기능은 DDL을 자동 생성할 때만 사용되고, JPA의 실행로직에는 영향을 주지 않는다.

3. @Lob

  • 데이터베이스 BLOB, CLOB타입과 매핑
  • 지정할 수 있는 속성이 없다.

4. @Transient

  • 필드 매핑X
  • 데이터베이스에 저장X, 조회X
  • 주로 메모리 상에만 임시로 어떤값을 보관하고 싶을때 사용한다.

5. 기본키 매핑

@Id : @Id만 사용하여 직접 할당한다.

@GeneratedValue

  • 자동 생성에는 4가지 전략(Strategy)이다.
    • INDENTITY : 데이터베이스에 위임 (MySQL에 사용)
    • SEQUENCE** : 데이터베이스 시퀀스 오브젝트 사용 (Oracle에서 사용)
    • TABLE : 키 생성용 테이블 사용, 모든 DB에서 사용 가능한 방법, @TableGenerator이 필요
    • AUTO : 방언에 따라 자동 지정한다. (기본값)
      • 즉, AUTO는 DB방언에 맞춰 INDENTITY, SEQUENCE, TABLE 3개 중 하나가 선택이 된다.

6. 연관관계 매핑

객체를 테이블에 맞춰 데이터 중심으로 모델링하면 협력관계를 만들 수 때문에,
(테이블은 외래키로 조인을 사용해서 연관된 테이블을 찾고, 객체는 참조를 사용해서 연관된 객체를 찾는 테이블과 객체 사이에 차이)
따라서, 객체지향 모델링 방식으로 연관관계를 표현한다.

1) 단방향 연관관계

  • 객체지향 모델링으로 진행한다.

2) 양방향 연관관계

가급적 단방향 연관관계로 처리하되, 필요에 따라서는 양방향 연관관계 매핑을 추가한다.

연관관계 주인

  • 외래키가 있는 객체가 연관관계의 "주인"이다.
  • 테이블에서는 FK만 잘 걸려 있으면, 양방향으로 이동할 수 있다.
  • 객체의 양방향 관계는 양방향이 아니라, 서로 다른 단방향 관계가 2개이다.

🧨 문제점!!

연관관계에 있는 엔티티 둘 중 하나로 외래키를 관리해야 하는데,
그러나, 수정을 할 때에 어느 쪽의 테이블을 수정해야 하는 지에 대한 이슈가 발생

연관관계의 주인(Owner)

  • 양방향 매핑의 규칙에서 필요하다.
  • 객체의 두 관계 중 하나를 연관관계의 주인(외래키가 있는 객체)으로 지정한다.
    - 연관관계의 주인만이 외래키를 관리(등록과 수정 등)할 수 있다.
    - 주인이 아닌 객체는 읽기만 가능하다.
    - 주인은 mappedBy 속성을 사용하지 않는다. (값을 넣어봐야 아무일도 벌어지지 않는다)
    - 주인이 아니면, mappedBy속성으로 주인을 지정한다. (List형태로 객체를 담는다)

🧨 양방향 연관관계시, 주의사항 🧨

  • 순수 객체 상태를 고려해서 항상 양쪽에 값을 설정하자!
  • 연관관계 편의 메서드를 생성하자!
  • 양방향 매핑시에 무한 루프를 조심하자!
    (toString() 메서드, lombok에서의 toString, ..)
    따라서, 연관관계 편의 메서드를 생성한다.
    • 연관관계 객체 둘 중에 하나만 넣자,
      만약 둘 다 넣으면, 무한루프가 걸리는 경우가 있다.

양방향 매핑 결론

  • 단방향 매핑만으로도 이미 연관관계 매핑은 완료되었고,
    양방향 매핑은 반대방향으로 조회 기능이 추가 된 것 뿐이다.
  • **양방향을 사용하는 이유는
    • JPQL, QueryDSL에서 역방향으로 탐색할 일이 많음 **
  • 단방향 매핑을 먼저 진행하고, 양방향은 필요할 때 추가해도 된다. (테이블에 영향을 주지 않는다.)

2. 임베디드 타입(Embedded type)

임베디드 타입이란, 사전적 정의로 내장 타입이란 뜻으로 새로운 값 타입을 직접 정의할 수 있다.

  • JPA가 대표적인 임베디드 타입이다.
  • 주로 기본값 타입을 모아 만들어서 복합값 타입이라고도 한다.
  • int, String과 같은 값 타입

JPA에서의 Embedded type 사용법

  • @Embeddable : 값 타입을 정의하는 곳에 표시
  • @Embedded : 값 타입을 사용하는 곳에 표시
  • 사용하기 위해서는, 기본 생성자가 필수로 있어야 한다.
  • @Embedded나, @Embeddable 둘 중에 하나만 써도 기능은 된지만, 둘 다 넣는 것을 권장한다.

임베디드 타입의 장점

  • 재사용이 목적이고, 높은 응집도를 가진다.
  • 객체 지향적 설계가 가능하다.
  • 임베디드 타입을 포함한 모든 값의 타입은 값 타입을 소유한 "엔티티에 생명주기"에 의존한다.

Embedded type에 의한 테이블 매핑은

  • 객체 입장에서 mapping만 변경될 뿐, DB 테이블 입장에서는 변화가 없다.
  • 테이블은 그대로 생성되었고, 좀 더 객체지향적으로 사용할 수 있다.
    - 임베디드 타입은 엔티티의 값일 뿐이다
  • 객체와 테이블을 아주 세밀하게 매핑하는 것이 가능하다.
  • 따라서, 잘 설계된 ORM 애플리케이션은 매핑한 테이블의 수보다 클래스의 수가 더 많다.

@AttributeOverride (속성 재정의)의 사용

한 엔티티에서 같은 값 타입을 사용하면 컬럼명이 중복되기 때문에, @AttributeOverrides, @AttributeOverride를 사용해서 컬럼명 속성을 재정의한다.

  • Address라는 임베디드 타입을 개인주소, 그리고 회사주소로 컬럼이름만 변경하여 재정의하고자 할 때, 이용할 수 있다.
@Embedded
@AttributeOverrides({
		@AttributeOverride(name = "city", column = @Column(name="WORK_CITY")), 
		@AttributeOverride(name = "street", column = @Column(name="WORK_STREET")),
		@AttributeOverride(name = "zipcode", column = @Column(name="WORK_ZIPCODE")), 
	})
private Address workAddress;

영속성 전이 (CASCADE)란?

특정 엔티티에 대한 특정한 작업을 수행하면, 관련된 엔티티에도 동일한 작업을 수행한다는 의미이다.

  • cascade = CascadeType.ALL : "모든 cascade 를 적용한다."

1. cascade = CascadeType.ALL의 역할

JPA에서 CascadeType.ALL은 엔티티 관계를 정의하는데 사용되는 옵션 중 하나로, 이 옵션은 부모 엔티티의 변경사항이 자식 엔티티에 모두 전파되도록 지정한다.

  • 부모 엔티티가 저장 될 때 자식 엔티티도 함께 저장한다.
  • 부모 엔티티가 업데이트될 때, 자식 엔티티도 함께 업데이트한다.
  • 부모 엔티티가 삭제될 때, 자식 엔티티도 함께 삭제한다.
profile
Quantum Jump to class for java….

0개의 댓글