JPA의 기본 값 타입에 대한 이해
Java Persistence API(JPA)는 객체 관계 매핑을 통해 데이터베이스와 객체 지향 프로그래밍을 연결한다.
JPA에서는 데이터 타입을 크게 엔티티 타입, 값 타입으로 분류한다.
엔티티 타입(Entity Type)
엔티티 타입은 데이터베이스의 테이블에 해당하는 클래스이다.
각 엔티티 인스턴스는 고유한 식별자(ID)를 가지며, 이 식별자를 통해 데이터가 변경되어도 지속적으로 추적이 가능하다.
값 타입(Value Type)
값 타입은 단순한 값을 나타내는 타입으로, Java의 기본 타입(int, double 등)이나 래퍼 클래스(Integer, Long 등), String과 같은 객체이다.
값 타입은 고유의 식별자를 가지지 않으며, 그 값 자체로 사용된다.
값 타입의 분류
기본 값 타입(Primitive Value Type): Java의 기본 타입과 래퍼 클래스, String 등이 이에 해당한다.
임베디드 타입(Embedded Type): 복합 값 타입으로, 여러 필드를 하나의 객체로 구성한다.
컬렉션 값 타입(Collection Value Type): 값 타입의 집합을 나타낸다.
값 타입의 특징 및 주의사항
기본 값타입은 서로 공유되면 안되며, 생명 주기를 엔티티에 의존한다.
엔티티가 삭제되면 함께 삭제된다. ex) 회원을 삭제하면 이름, 나이 필드도 함께 삭제된다.
회원이름 변경시 다른 회원의 이름도 함께 변경되면 절대 안된다.
Reference Type vs premitive Type
객체는 = 값 연산시 참조값(Reference)이 넘어가고, Premitive 타입은 값 자체가 넘어가므로, 객체 = 값 연산을 사용하면 안된다.
특정 값을 만들때는 항상 생성자를 통해 사용해야하고, 수정 시 Setter가 아닌 의도가 드러나는 메서드를 따로 정의해서 사용하는 게 좋다. 세터는 절대 금지.
처음에 필드 3개 이상을 갖지 말라고 했었는데, 이를 임베디드 타입으로 해결할 수 있다.
예를 들어, 이름, 전화번호 앞자리, 전화번호 중간자리, 전화번호 뒷자리 .. 를 가진다
어색하다고 생각된다. 우리는 평소에 이름, 전화번호를 가진다. 라고 표현을 하기 떄문이다.
이를 코드에 그대로 적용하면 된다.
임베디드 타입 예시 코드
Member
@Entity
public class Member {
@Id @GeneratedValue
@Column(name = "MEMBER_ID")
private Long id;
@Column(name = "USERNAME")
private String username;
@Embedded
private PhoneNumber phoneNumber;
...
}
Phonenumber
@Embeddable
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class PhoneNumber {
private Integer front; // 앞자리
private Integer midle; // 중간자리
private Integer tail; // 뒷자리
}
이와 같이 PhoneNumber 클래스는 @Embeddable 어노테이션을 사용하여 임베디드 타입으로 선언되며, Member 클래스 내에서 객체로 사용된다.
'JPA > ORM 표준 JPA' 카테고리의 다른 글
[ORM 표준 JPA] 12. JPQL 기본 함수 정리 (0) | 2023.10.14 |
---|---|
[ORM 표준 JPA] 10. 프록시와 N + 1 문제 FetchType.LAZY (0) | 2023.10.04 |
[ORM 표준 JPA] 9.고급매핑 - 상속관계 매핑, @MappedSuperclass (0) | 2023.09.30 |
[ORM 표준 JPA] 8.다양한 연관관계 매핑 (0) | 2023.09.30 |
[ORM 표준 JPA] 7. 연관관계 매핑2 양방향 연관관계와 연관관계의 주인 (0) | 2023.09.23 |