DAY67 - YAML, 임베디드 타입

은나현·2023년 5월 1일
0

📌 1. YAML

  • YAML : e-mail 양식에서 개념을 얻어 만들어진 '사람이 쉽게 읽을 수 있는' 데이터 직렬화 양식이다.

📍 1-1. 설정파일 *.yml

  • properties와 비교했을 때 yml 설정파일의 장점
    • 한 눈에 보기에 가독성이 좋다.
    • 불필요한 코드의 반복을 피할 수 있다.
    • 계층 구조로 이해하기 쉽고 쓰기 편하다.
  • 주의사항
    • 띄어쓰기(스페이스) 2칸을 기준으로 계층을 만든다.
    • 띄어쓰기 1칸을 두고 값을 입력한다.
  • application.yml 예시
    #port 수정
    server:
      port: 9090
    #DB Connection
    spring:
      datasource:
        url: jdbc:oracle:thin:@localhost:1521:xe
        driver-class-name: oracle.jdbc.OracleDriver
        username: spring
        password: spring 
    #JPA
    jpa:
      hibernate: 
        ddl-auto: create
      properties:
        hibernate: 
          format_sql: true
          show_sql: true

📌 2. 임베디드 타입

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

📍 2-1. JPA 임베디드 타입 사용법

  • @Embeddable : 값 타입을 정의하는 곳에 표시
  • @Embedded : 값 타입을 사용하는 곳에 표시
    • @Embeddable@Embedded 둘 중에 하나만 넣어도 된다. 하지만 가독성을 위해 둘 다 넣는 것을 권장한다.
  • 기본 생성자가 필수로 요구된다.
  • 회원 주소에 대한 정보를 가진 임베디드 타입 Address 예시
    • Address 클래스(@Embeddable)
      @Embeddable
      @Getter @Setter @AllArgsConstructor @NoArgsConstructor
      public class Address {
      	private String city;
      	private String street;
      	private String zipcode;
      }  
    • Address를 사용하는 Member 클래스
      @Embedded
      private Address address;
    • 파라미터가 있는 생성자를 사용한 값 세팅 예시
      member.setAddress(new Address("서울","역삼","123"));

📍 2-2. 임베디드 타입의 장점

  • 재사용의 편의성, 높은 응집도
  • 객체지향적 설계 가능
    • 해당 값 타입만 사용하는 의미 있는 메소드를 만들 수 있다.
    • 임베디드 타입을 포함한 모든 값 타입은 값 타입을 소유한 엔티티에 생명주기를 의존한다.

📍 2-3. 임베디드 타입과 테이블 매핑

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

📍 2-4. 속성 재정의(@AttributeOverride)

  • 한 엔티티에서 같은 값 타입을 사용하면 컬럼명이 중복된다.
    • @AttributeOverrides, @AttributeOverride를 사용해서 컬럼명 속성을 재정의하여 사용할 수 있다.
    • 동일한 임베디드 타입 Address를 사용한 두 개의 주소 정의
      		// 집주소
      		@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;

📍 2-5. 객체 타입의 한계

  • 임베디드 타입처럼 직접 정의한 값 타입은 자바의 기본 타입이 아니라 객체 타입이다.
    • 자바 기본 타입에 값을 대입하면 값을 복사한다.
    • 객체 타입에서는 참조 값을 직접 대입하는 것을 막을 방법이 없다.
    • 하나의 객체 타입 값을 두 객체에 할당하면 값을 공유하게 되므로 둘 중 하나만 수정하는 것이 불가능하다.
      		Address addr = new Address("서울","역삼","123");
        		// member1에 addr 할당
      		Member member1 = new Member();
      		member.setUsername("user1");
      		member.setAddress(addr);
      		em.persist(member1);
      		// member2에 addr 할당
      		Member member2 = new Member();
      		member2.setUsername("user2");
      		member2.setAddress(addr);
      		em.persist(member2);
      		// 1번째 member의 주소만 newCity로 변경하고자 해도 
        		 member2의 값이 동시에 변경됨
      		member1.getAddress().setCity("newCity");  
  • 객체의 공유 참조는 피할 수 없다.
    • 공유 참조로 인해 발생하는 부작용을 피하기 위해서는 항상 값을 복사해서 사용한다.
    • 새로운 객체를 생성해 할당하는 것을 강제하기 위해 setter를 만들지 않는 방법도 있다.
      		Address addr = new Address("서울","역삼","123");
        		// member1에 addr 할당
      		Member member1 = new Member();
      		member.setUsername("user1");
      		member.setAddress(addr);
      		em.persist(member1);
      		// 기존 addr을 복사 
      		Address copyAddr = new Address(addr.getCity(),addr.getStreet(),addr.getZipcode());
      		// member2에 copyAddr 할당
      		Member member2 = new Member();
      		member2.setUsername("user2");
      		member2.setAddress(copyAddr);
      		em.persist(member2); 

0개의 댓글