Converter, Embedded

duckbill413·2023년 1월 21일
0

Spring boot

목록 보기
4/8
post-thumbnail

Converter

스프링은 기본적으로 Object Mapper을 통해 스프링으로 들어온 객체를 변환해주지만, 사용자가 직접 이를 구현해주는 것 또한 가능하다.

다음은, Book status가 integer로 들어왔을때 이에 대하여 설명을 추가해주는 converter을 구현하는 예제이다.

  • Book Entity
    @EqualsAndHashCode(callSuper = true)
    @ToString(callSuper = true)
    @Entity
    @NoArgsConstructor
    @AllArgsConstructor
    @Data
    @Builder
    public class Book extends BaseEntity{
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;
        private String name;
    
        @Convert(converter = BookStatusConverter.class)
        private BookStatus status; // 판매 상태
    }
    • 판매 상태를 보여주는 BookStatus 필드 입력한다.
    • @Converter 어노테이션을 사용해 converter 클래스를 지정해준다.
    • 어노테이션을 지정하지 않았을때 나타나는 에러는 RuntimeError 이다.
  • BookStatus class
    @Data
    public class BookStatus {
        private int code;
        private String description;
    
        public BookStatus(int code){
            this.code = code;
            this.description = parseDescription(code);
        }
        private String parseDescription(int code){
            switch (code){
                case 100:
                    return "판매 종료";
                case 200:
                    return "판매중";
                case 300:
                    return "판매 보류";
                default:
                    return "미지원";
            }
        }
    }
    • 생성자로 status code가 들어와 생성할 때 description도 같이 초기화 해준다.
  • BookStatusConverter
    @Converter // autoApply: ide 에서 RuntimeError 로 체크
    public class BookStatusConverter implements AttributeConverter<BookStatus, Integer> {
        @Override
        public Integer convertToDatabaseColumn(BookStatus attribute) {
            return attribute.getCode();
        }
    
        @Override
        public BookStatus convertToEntityAttribute(Integer dbData) {
            return dbData != null ? new BookStatus(dbData) : null;
        }
    }
    • AttributeConverter 을 implement 하여 converter class를 생성해준다.
    • @Converter 어노테이션을 붙여 Converter 클래스를 등록해준다.
    • @Converter의 autoApply 옵션을 사용하면 대상 클래스에서 @Convert Annotation을 붙이지 않아도 사용가능하나 명시적으로 선택하는 것이 안전하다.
    • BookStatus는 변환할 대상, Integer은 변환완료 후의 데이터 타입이다.
    • convertToDatabaseColumn
      • BookStatus 가 들어왔을때 DB에 저장할 데이터를 리턴해준다.
      • 보기의 경우 Integer 이 리턴된다.
    • convertToEntityAttribute
      • DB의 데이터가 들어왔을때 어떻게 변환할 것인지 정의 해준다.
      • 보기의 경우 DB에 저장되었던 Integer 타입의 데이터가 들어왔을때 null 검사를 진행한다. new BookStatus(code) 로 convert 해주어 리턴해주게 된다.

Embedded

  • 임베디드 타입은 새로운 값 타입을 직접 정의해서 사용한는 JPA의 방법이다.

  • 임베디드 타입을 사용하여 더욱 객체지향적인 코드를 만들 수 있다.

  • 코드의 재사용성을 향상 시킬 수 있다.

  • 주소 Embedded class

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    @Embeddable
    public class Address {
        private String city; // 시
        private String district; // 구
        @Column(name = "address_detail")
        private String detail; // 상세주소
        private String zipcode; // 우편번호
    }
    • 임베디드 타입으로 사용할 클래스 이다.
    • @Embeddable 어노테이션을 붙인다.
    • @Column을 사용하여 DB에 저장될 컬럼명을 수정할 수 있다.
  • 주소 타입을 사용하는 Entity

    @Embedded
    private Address address;
    • @Embedded 어노테이션을 사용해서 임베디드 타입임을 명시한다.
  • DDL 명령

    create table member (
       id bigint not null auto_increment,
        created_at datetime(6) default now(6) comment '생성시간' not null,
        updated_at datetime(6) default now(6) comment '수정시간' not null,
        city varchar(255),
        address_detail varchar(255),
        district varchar(255),
        zipcode varchar(255),
        email varchar(255),
        gender varchar(255),
        name varchar(255),
        primary key (id)
    ) engine=InnoDB
    • Address 필드들이 각각 생성된 것을 확인해 볼 수 있다.

AttributeOverrides

Embedded type의 필드들을 여러개 사용할때 사용된다.

AttributeOverride, AttributeOverrides 를 사용하여 컬럼의 이름을 명시적으로 바꾸어줄 수 있다.

@Embedded
@AttributeOverrides({
        @AttributeOverride(name = "city", column = @Column(name = "home_city")),
        @AttributeOverride(name = "district", column = @Column(name = "home_district")),
        @AttributeOverride(name = "detail", column = @Column(name = "home_address_detail")),
        @AttributeOverride(name = "zipCode", column = @Column(name = "home_zip_code"))
})
private Address homeAddress;
@Embedded
@AttributeOverrides({
        @AttributeOverride(name = "city", column = @Column(name = "company_city")),
        @AttributeOverride(name = "district", column = @Column(name = "company_district")),
        @AttributeOverride(name = "detail", column = @Column(name = "company_address_detail")),
        @AttributeOverride(name = "zipCode", column = @Column(name = "company_zip_code"))
})
private Address companyAddress;
  • AttributeOverride, AttributeOverrides 를 활용하여 두 개의 Embedded type를 정의하였다.

DDL

create table member (
   id bigint not null auto_increment,
    created_at datetime(6) default now(6) comment '생성시간' not null,
    updated_at datetime(6) default now(6) comment '수정시간' not null,
    company_city varchar(255),
    company_address_detail varchar(255),
    company_district varchar(255),
    company_zip_code varchar(255),
    email varchar(255),
    gender varchar(255),
    home_city varchar(255),
    home_address_detail varchar(255),
    home_district varchar(255),
    home_zip_code varchar(255),
    name varchar(255),
    primary key (id)
) engine=InnoDB
  • homeAddresscompanyAddress 가 각각 AttributeOverride 된 컬럼명으로 생성된다.
profile
같이 공부합시다~

0개의 댓글