1. 기본개념
2. 사용법
3. 장점
@Embeddable
public class Address {
//컬럼길이 지정 같은 공통룰 적용도 편리
@Column(length = 10)
private String city;
@Column(length = 20)
private String street;
@Column(length = 5)
private String zipcode;
//값타입은 의미있는 메소드 생성 가능
public String fullAddress() {
return getCity() + getStreet() + "-" + getZipcode();
}
//값타입이므로 불변객체로 만들기 위해 setter는 private으로 생성
public String getCity() {
return city;
}
private void setCity(String city) {
this.city = city;
}
public String getStreet() {
return street;
}
private void setStreet(String street) {
this.street = street;
}
public String getZipcode() {
return zipcode;
}
private void setZipcode(String zipcode) {
this.zipcode = zipcode;
}
//equals, hashcode 오버라이드
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Address address = (Address) o;
return Objects.equals(getCity(), address.getCity()) && Objects.equals(getStreet(), address.getStreet()) && Objects.equals(getZipcode(), address.getZipcode());
}
@Override
public int hashCode() {
return Objects.hash(getCity(), getStreet(), getZipcode());
}
}
4. 임베디드 타입과 테이블 맵핑
@Entity
public class MemberMapping extends BaseEntity {
@Id
@GeneratedValue
@Column(name = "MEMBER_ID")
private Long id;
@Column(name = "USERNAME")
private String username;
//임베디드타입 Period
@Embedded
private Period workPeriod;
//임베디드타입 Address
@Embedded
private Address homeAddress;
@ManyToOne(fetch = FetchType.LAZY) //지연로딩 사용해서 프록시로 조회
@JoinColumn(name = "TEAM_ID")
private TeamMapping team;
@OneToOne
@JoinColumn(name = "LOCKER_ID")
private Locker locker;
@OneToMany(mappedBy = "member")
private List<MemberProduct> memberProductList = new ArrayList<>();
//...getter,setter
}
@Embeddable
public class Address {
private String city;
private String street;
private String zipcode;
public Address() {
} //기본생성자 필수
public Address(String city, String street, String zipcode) {
this.city = city;
this.street = street;
this.zipcode = zipcode;
}
//...getter,setter
}
@Embeddable
public class Period {
private LocalDateTime startDate;
private LocalDateTime endDate;
public Period() {
} //기본생성자 필수
public Period(LocalDateTime startDate, LocalDateTime endDate) {
this.startDate = startDate;
this.endDate = endDate;
}
//...getter,setter
}
MemberMapping member = new MemberMapping();
member.setUsername("hello!!!");
member.setHomeAddress(new Address("Seoul", "star-ro","1000"));
member.setWorkPeriod(new Period());
em.persist(member);
tx.commit();
- 임베디드 타입은 사실 엔티티의 값일 뿐
- 임베디드 타입 사용 전/후 맵핑하는 타이블은 같음!!!
- 객체와 테이블을 아주 세밀하게 맵핑할 수 있음
- 잘 설계한 ORM 애플리케이션은 맵핑한 테이블의 수 < 클래스의 수
5. 임베디드 타입과 연관관계
@Entity
public class MemberMapping extends BaseEntity {
....
//임베디드타입 Period
@Embedded
private Period workPeriod;
//임베디드타입 Address
@Embedded
private Address homeAddress;
//한 엔티티에 안에서 같은 값 타입을 사용하면 컬럼명이 중복되므로 @AttributeOverrides, @AttributeOverride로 컬럼명 속성 재정의
@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;
//...getter,setter
}
6. 임베디드 타입과 null