본문 바로가기
프로그래밍/Project

[Project01] MiniBoard(3) - Custom Annotation 생성, 사용자 Model 생성

by 코딩중독 2024. 1. 25.

목차

    Custom Annotation 생성

    각 클래스의 역할 세분화를 위해 Business, Converter Annotation을 만든다.

    요청 로직의 흐름은

    Client -> Controller -> Business -> Service -> Repository 순으로 흘러가고, 응답은 역순으로 반환한다.

    요청과 응답의 모델이 다르기 때문에 도메인별로 Converter 클래스를 사용할 예정이다.

    @Business

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Service
    public @interface Business {
    
        @AliasFor(annotation = Service.class)
        String value() default "";
    
    }

     

    @Converter

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Service
    public @interface Converter {
    
        @AliasFor(annotation = Service.class)
        String value() default "";
    
    }

     

    사용자 모델 생성

    UserEntity

    MySQL user 테이블과 매칭

    사용자의 상태값을 Java에서 enum 클래스로 관리하는데 MySQL의 varchar 타입과 맞추기 위해 어노테이션을 추가했다.

    실습을 진행할 때 스프링 버전 2.7.9에서는 @Enumerated(EnumType.STRING)으로 사용했는데, 새로운 프로젝트는 3.2.1로 생성을 했더니 DB 연결에서 status를 찾지 못한다고 해서 한참을 헤맸다.

    @Entity
    @Table(name = "user")
    @Data
    @EqualsAndHashCode(callSuper = true)
    @NoArgsConstructor
    @AllArgsConstructor
    @SuperBuilder
    public class UserEntity extends BaseEntity {
    
        @Column(length = 50, nullable = false)
        private String name;
    
        @Column(length = 100, nullable = false)
        private String email;
    
        @Column(length = 100, nullable = false)
        private String salt;
    
        @Column(length = 100, nullable = false)
        private String password;
    
        //    @Enumerated(EnumType.STRING)  // 'org.springframework.boot' version '2.7.9'
        @Convert(converter = UserStatusConverter.class) // 'org.springframework.boot' version '3.2.1'
        @Column(length = 50, nullable = false)
        private UserStatus status;
    
        private LocalDateTime registeredAt;
    
        private LocalDateTime unregisteredAt;
    
    }

     

    UserStatusConverter

    스프링부트 3.x.x대 버전에서는 컨버터 클래스를 생성하고 달아줘야 한다.

    /**
     * 스프링부트 3.x.x 버전에서 java:enum 과 mysql:varchar 맵핑 시키기 위한 컨버터 클래스
     */
    public class UserStatusConverter implements AttributeConverter<UserStatus, String> {
        @Override
        public String convertToDatabaseColumn(UserStatus attribute) {
            if (Objects.isNull(attribute)) {
                throw new NullPointerException("Enum Converting String - UserStatus is null");
            }
    
            return attribute.toString();
        }
    
        @Override
        public UserStatus convertToEntityAttribute(String dbData) {
            return UserStatus.valueOf(dbData);
        }
    }

     

    UserRegisterRequest

    회원가입을 위해 클라이언트가 입력한 값을 담당할 친구이다.

    @Builder ♥ 너무좋다...

    @Data 어노테이션은 Getter, Setter, ToString, RequiredArgsConstructor 등의 어노테이션이 모두 포함된 아이인데, 값의 변경이 불가피한 상황에서만 사용하고 Getter 어노테이션만 사용한다.

    객체의 일관성을 유지하고 값의 변경이 불가피한 경우에만 사용할 예정이다.

    하지만 버릇처럼...

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @Builder
    public class UserRegisterRequest {
    
        @NotBlank
        private String name;
    
        @NotBlank
        @Email
        private String email;
    
        @NotBlank
        private String password;
    
    }

     

    UserResponse

    클라이언트에서 사용자에 대한 요청을 처리한 후 응답값을 담당할 친구이다.

    비밀번호를 제외하고 사용자의 정보를 전달한다.

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @Builder
    public class UserResponse {
    
        private Long id;
    
        private String name;
    
        private String email;
    
        private UserStatus status;
    
        private LocalDateTime registeredAt;
    
        private LocalDateTime unregisteredAt;
    
    }

     

    마치며

    이제 회원가입을 위한 준비가 얼추 마무리된 상태라 다음에는 회원가입 로직을 진행한다.

    개인 프로젝트를 진행하며 기록하는 내용이라 정보를 얻고자 하는 누군가에게는 불친절한 글이 될 수도 있지만 댓글에 질문 주시면 제가 아는 선에서는 답변드리도록 하겠습니다.

    잘못된 내용도 지적해 주시면 감사하겠습니다.