[Spring Boot] 임베디드 타입, embedded type , @Attributeoverrides, @AttributeOverride / 불변객체

seulki·2022년 12월 12일
0

[springboot]

목록 보기
21/27

🎈 임베디드 타입 (복합 값 타입)

  • 내장 타입
  • 새로운 값 타입을 직접 정의할 수 있음
  • JPA는 임베디드 타입(embedded type)이라고 함
  • 주로 기본값 타입을 모아 만들어서 복합값 타입이라고도 함
  • int, String 과 같은 값 타입

  • Member 클래스에서 startDate, endDate 가 동일한 성격이고,
    city, street, zipcode가 동일한 성격이다.



✨ JPA에서 임베디드 타입 사용법

  • @Embeddable : 값 타입을 정의하는 곳에 표시
  • @Embedded : 값 타입을 사용하는 곳에 표시
  • 기본 생성자 필수


👌 임베디드 타입의 장점

  • 재사용 가능
  • 높은 응집도
  • 객체지향적인 설계가 가능하다.

  • 엔티티 클래스에서는 Period, Address와 같이 임베디드 타입으로 묶었지만,
    DB 테이블에서는 아무런 변화없이, 기본 테이블과 같은 형태로 만들어진다.

  • Member.java

@Entity
@TableGenerator(name = "MEMBER_SEQ_GENERATOR", table="MY_SEQUENCES", 			
				pkColumnValue = "MEMBER_SEQ",
				allocationSize = 1)
@Getter @Setter
public class Member {

	@Id
	@GeneratedValue(strategy = GenerationType.TABLE, 
    				generator = "MEMBER_SEQ_GENERATOR")
	private Long id;
	
	@Column(name = "name", nullable = false)
	private String username;

	private int age;
	
	private LocalDateTime startDate;
	private LocalDateTime endDate;

	private String city;
	private String street;
	private String zipcode;
  • 묶어주기 위해서 클래스 생성하기 - Period / Address

  • 묶을 변수들을 클래스로 옮긴다.

  • @Embeddable 어노테이션 사용 -> 값 타입을 정의

  • Member에서는 @Embedded 어노테이션으로 임베디드 타입을 사용한다.
    Period 객체를 만들어준다.

  • @Embedded와 @Embeddable 둘 중 하나만 넣어도 되나, 둘 다 넣어줄 것을 권장

  • Member에서 Period에 접근할 수 있도록 getter, setter 생성해줘야 한다.

  • Address 임베디드 타입 생성

-

  • 기본생성자가 필수이기 때문에 생성해주고, 테스트를 위한 파라미터가 있는 생성자도 생성해준다.

  • JpaMain.java 에서 new로 객체 생성하여 값 할당 -> 객체지향적이다.

-



✨ 임베디드 타입과 테이블 매핑

  • 임베디드 타입은 엔티티의 값일 뿐이다.
  • 임베디드 타입을 사용하기 전과 후에 매핑하는 테이블은 같다.
  • 잘 설계된 애플리케이션은 매핑한 테이블의 수보다 클래스의 수가 더 많다.


👌 임베디드 타입 부작용, Side Effect

  • user1과 user2가 같은 addr을 가지고 있다.

  • 만약 user1의 주소만 newCity로 변경하고 싶어서, member의 Address를 수정했다면, member2의 주소까지 함께 변경된다. 그렇기 때문에 임베디드 타입을 사용할 때는 주의해서 값을 변경해야한다.

  • 같은 객체를 바라보고 있기 때문에, Address 객체를 한 곳에서 수정해도 다른 곳에도 영향을 미치게 된다.

  1. 임베디드 타입 객체를 따로 만들고 값만 가져와서 사용하는 방법.
  • Address 객체를 새로 만들면서, 기존 Address객체의 값만 가져와서 할당한다.

  • 그 후에 member1의 주소만 변경을 하면, 각각 값이 다르게 할당되어 있다.


  1. 임베디드 객체를 하나만 생성하는 대신, 값의 변경이 필요할 경우 그때그때마다 아에 새로운 객체를 생성하여 할당해준다.
  • 이 방법을 사용할 경우, 변경이 필요할 때는 객체가 생성자를 통해서 새로 생성되기 떄문에, setter로 인한 값 변경을 막아주어야 한다. -> 불변객체로 사용

🗝️ 불변객체

  • 객체 타입을 수정할 수 없게 만들면 부작용을 원천 차단
  • 값 타입은 불변 객체로 설계해야함
  • 생성 시점 이후 절대 값을 변경할 수 없는 객체
  • 생성자로만 값을 설정하고 수정자 (Setter)를 만들지 않으면 됨.


🎈 @AttributeOverride : 속성 재정의

  • 한 엔티티에서 같은 값 타입을 사용하면 컬럼명이 중복된다.

  • @Attributeoverrides, @AttributeOverride를 사용해서 컬럼 명 속성을 재정의

  • 만약 기존의 Address 객체로 회사 주소라는 변수들을 생성한다면, 기존의 Address와 컬럼명이 곂치기 때문에, @attributeOverrides, @AttributeOveride 어노테이션으로 오버라이드 하고, 컬럼명을 변경 해 준다.

	//주소
	@Embedded
	private Address 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;

profile
웹 개발자 공부 중

0개의 댓글