목차
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;
}
마치며
이제 회원가입을 위한 준비가 얼추 마무리된 상태라 다음에는 회원가입 로직을 진행한다.
개인 프로젝트를 진행하며 기록하는 내용이라 정보를 얻고자 하는 누군가에게는 불친절한 글이 될 수도 있지만 댓글에 질문 주시면 제가 아는 선에서는 답변드리도록 하겠습니다.
잘못된 내용도 지적해 주시면 감사하겠습니다.
'프로그래밍 > Project' 카테고리의 다른 글
[Spring] ToyProject 2단계(2) - 역할 분배, 기본 구조 (0) | 2024.01.29 |
---|---|
[Spring] ToyProject 2단계(1) - 시작하기 (0) | 2024.01.28 |
[Project01] MiniBoard(2) - ObjectMapper, SwaggerUI, Filter 설정 (0) | 2024.01.25 |
[Project01] MiniBoard(1) - 프로젝트 생성, 데이터베이스 연결 (0) | 2024.01.23 |
[Java] ToyProject 1단계 (0) | 2023.12.29 |