기본값 타입
JPA의 데이터 타입 분류
엔티티 타입
@Entity 객체
데이터가 변해도 식별자로 추적 가능
회원 엔티티의 키나 나이를 변경해도, 식별자로 인식 가능해요
값 타입
int, Integer, String 처럼 단순 값으로 사용하는 자바 기본타입이나 객체
식별자가 없고 값만 있음, 변경하면 추적 불가
숫자 100을 200으로 변경하면 완전히 다른 값이에요
값 타입의 종류
*기본값
자바 기본 타입(int, double)
래퍼 클래스(Integer, Long)
String
*임베디드 타입 embedded type
복합 값 타입
직접 커스텀해서 값 타입 사용하고 싶을 때
*컬렉션 값 타입 collection value type
임베디드, 기본 값 타입을 넣을 수 있음
기본값 타입
- 생명주기를 엔티티에 맡김
- 회원을 삭제하면 이름, 나이 필드도 함께 삭제됨
- 값 타입은 공유 절대 안 됨X
ㄴ 회원 이름 변경하는데 다른 회원 이름도 변경되면 큰일남
자바 기본 타입은 절대 공유 안 됨
- 기본 타입은 항상 값을 복사함
- 같이 변경이 되는 것이 아닌, 값을 복사만 하니까 공유하는 것이 아님
- Integer 같은 래퍼 클래스나 String 같은 특수 클래스?
ㄴ 공유 가능한 객체이지만 변경은 안 됨니다~
임베디드 타입
- 새로운 값 타입 직접 정의
- JPA는 임베디드 타입
- 주로 기본 값 타입을 모아서 복합 값 타입이라고도 해요
- int, String과 같은 값 타입(엔티티아님)
임베디드 타입은 어떻게 사용해요?
@Embeddable : 값 타입 정의할 때(클래스)
@Embedded : 값 타입 사용하는 곳(사용하는 필드)
*기본 생성자는 필수 !
장점)
- 재사용 가능
- 높은 응집도
- 해당 값 타입만 사용하는 의미 있는 메서드 만들 수 있다
- 임베디드타입을 포함한 모든 값 타입은,
값 타입을 소유한 엔티티에 생명주기를 의존합니당
DB에서는 똑같으나, 객체는 클래스로 연관있는 밸류를 합침
임베디드타입은 엔티티의 값일 뿐
임베디드타입을 사용하기 전과 후에도 매핑하는 테이블은 같음
-> 하지만, 객체와 테이블을 세밀하게 매핑 가능, 모델링 깔끔하게 떨어짐
잘 설계한 ORM 애플리케이션은 매핑한 테이블의 수보다 클래스 수가 더 많습니당
임베디드 타입이 엔티티를 가질 수도 있음니다(외부 키로)
@AttributeOverride 속성 재정의
한 엔티티에서 같은 값 타입을 사용하면?
ㄴ 컬럼명 중복 ㅠㅠ
@AttributeOverrides, @AttributeOverride로
컬럼 명 속성을 재정의해용!
임베디드 타입이 null이면 매핑한 테이블 값도 다 null
(임베디드 타입 필드 있는 테이블의 값 다 null)
값 타입과 불변 객체
값 타입?
복잡한 객체 세상을 조금이라도 단순화하려고 만듬
그래서, 단순하고 안전하게 다룰 수 있어야 해용
임베디드 타입 같은 값 타입을
여러 엔티티에서 공유하면 위험해연
임베디드타입은 사용할 엔티티에서 유일하게 쓰고
다른 엔티티에서는 새로운 임베디드타입을 복사해서 쓰세연
그런데!
항상 값을 복사해서 사용하면 공유 참조 부작용을 피할 수 있지만
임베디드 타입처럼 직접 정의한 값 타입? 객체타입임
객체 타입은 참조 값을 직접 대입하는 것을 막을 방법이 없음...(주소 복사)
객체의 공유 참조는 피할 수 없음....
이것이 객체 타입의 한계 ㅠ_ㅠ
그래서!
불변 객체!!!! 로 만들자 !!
ㄴ 생성 시점 이후에 절대 값을 변경할 수 없음
ㄴ 생성자로만 값을 설정하고, setter 안 만들기
객체 타입을 수정할 수 없음(부작용 차단)
값 타입은 불변 객체로 설계해야함
그래도 값을 바꾸고 싶다면?ㅠㅠ
걍 통으로 새로 만드세연....
new로 새로 객체 만들고 get으로 기존 필드 불러오고, 수정할 값만 바꿔줌니다
@@@@꼭 불변 객체로 만드세연@@@@
값 타입을 비교해보자!
값 타입은 인스턴스가 달라도, 안에 값이 같으면 같은 것으로 봐야합니당
하지만 ~ 객체는 인스턴스가 다르면 == 비교는 false ㅠ_ㅠ
동일성 비교 : 인스턴스 참조 값 비교. ==
동등성 비교 : 인스턴스 값을 비교. equals()
값 타입은 동등성 비교를 해야함 (equals)
그래서 값 타입의 equals() 메소드를 적절하게 Override 하자!
(모든 필드에서 ㄱㄱ)
대부분의 경우 equals 오버라이딩은 그냥 자동으로 생성해주는 걸로 쓰세연~
+ hashCode도 같이 추가해주세연~ HashMap 이런거 사용 가능하겡
값 타입 컬렉션?
- 값 타입을 컬렉션에 담아서 쓰는 것입니다
- DB는 컬렉션을 같은 테이블에 저장할 수 없어용
- 그래서 따로 테이블을 만들어냅니당
- 지연로딩
컬렉션 생성하고,(List, Set)
@ElementCollection <- 얘는 값 타입 컬렉션임
@CollectionTable(name = "테이블명", joinColumns = @JoinColumn(name = "조인할컬럼(외래키값)"))
속성이 String, Integer 같은 하나라면,
@Column ( name = "내가 사용할 컬럼명" ) 추가
다른 테이블이어도, 컬렉션을 넣은 엔티티가 관리하기때문에
해당 엔티티가 전부 관리함
하지만 지연로딩이기때문에 해당 엔티티를 조회해도
직접 값을 사용하지 않으면 쿼리가 안 나가고 프록시로 생김
수정할땐, 임베디드는 불변객체로 만듬 ㅡㅡ 직접 set XXXX
직접 get으로 불러온 후, 수정할 값만 새로 넣음(통으로 갈아껴야함)
기본 타입을 값 타입 컬렉션으로 만들었을 경우엔
변경할 값을 remove한 후 새 값을 add해야함
기본 타입이 아닐 경우에도 마찬가지인데,
remove하기 위해서는 add 했을 때와 똑같은 객체를 넣고 remove해야함
1) 기본적으로 equals 사용하기 때문에, 해당 객체에 equals+hashCode 만들어준 후
2) remove에 기존 객체와 똑같은 값을 가진 객체를 넣어서 삭제 후
3) 새로운 값을 add해야 함
값 타입은 식별자 기능 X
값 변경하면 추적이 어려움
값 타입 컬렉션에 변경 사항이 발생한다?
- 주인 엔티티와 연관된 모든 데이터 삭제
(하나만 수정해도, 관련된 모든 값 삭제 후 다시 INSERT...)
- 값 타입 컬렉션에 있는 현재 값을 모두 다시 저장
---결론
->걍 쓰지마세연~~값타입 컬렉션 쓰지마여~~~~
ㄴ 정말 개단순하고 변경할 거리가 없는 거에만 사용...
->다른 방법을 사용하도록 하세욘~~^.^
->일대다 관계를 쓰는 것을 고려해보세용!
ㄴ 일대다 관계를 위한 엔티티를 만들고, 여기에서 값 타입 사용
ㄴ 영속성 전이 + 고아 객체 제거를 사용해서 값 타입 컬렉션처럼 사용
@OneToMany( 영속성전이 , 고아객체제거 )
@JoinColumn ( name = "외래키" )
엔티티 타입
- 식별자 O
- 생명 주기 관리
- 공유
값 타입 특징
- 식별자 X
- 생명 주기를 엔티티에 의존
- 값 공유 XX 하지마세연
- 불변 객체로 만드세요
'개발공부 개발새발 > DB' 카테고리의 다른 글
MyBatis ) 마이바티스 스프링 부트 연동하기 (1) | 2023.01.15 |
---|---|
JPA ) JPA 요약 (내가 검색하는 용도) (2) | 2022.11.29 |
JPA ) 영속성 전이, 고아 객체 (0) | 2022.11.25 |
JPA) 즉시로딩과 지연로딩??? (0) | 2022.11.25 |
JPA) 프록시란 무엇인가 (0) | 2022.11.25 |