Intellij) JDBC 프로젝트 (7) Entity 클래스와 롬복(Lombok)

Intellij) JDBC 프로젝트 (7) Entity 클래스와 롬복(Lombok)

(다른 글 목차 삽입 예정)

Entity 클래스

도메인, 모델, 엔티티, VO 등 다양한 표현이 존재합니다. DTO도 있습니다만, DTO는 다른 쓰임새에서 명명하기에 더 자연스럽게 사용되고 있기 때문에 이번에는 제외해서 표현하려고 합니다.

이 표현들은 모두 데이터를 담은 객체를 뜻하는데, 이번에 우리가 쓰려는 목적에 맞게 쉽게 풀어 쓰자면 테이블에 매핑되는 클래스 정도로 생각할 수 있습니다.

롬복 추가하기

우리는 엔티티 클래스를 만들고 사용하기 위해서 lombok이라는 것의 도움을 받으려고 합니다.

lombok은 여러 자바 프로젝트에서 전통적으로 사용되어 온 라이브러리로, 자바가 다른 젊은 언어들과 경쟁할 수 있도록 여러 편의 기능을 제공해 줍니다. build.gradle에서 라이브러리를 추가할 수 있죠.

dependencies {
    // lombok
    compileOnly 'org.projectlombok:lombok:1.18.32'
    annotationProcessor 'org.projectlombok:lombok:1.18.32'

    // ...
}

User Entity 클래스

우리는 "user" 테이블을 만들었으니까, User 클래스를 만들어 봅시다. Getter/Setter를 사용하려면 사용하셔도 됩니다만, 이번 예시에서는 편의상 생략했습니다. Getter, setter, builder 등의 사용에는 여러 관점 충돌이 존재합니다만, 사실 그 자체로 아주 치명적인 것은 아닙니다.

우리가 "user" 테이블에 작성한 컬럼을 자바에 호환되는 타입으로만 바꾸어서 User 클래스의 필드로 작성해 봅시다.

  • package: com.example.app.auth.domain
package com.example.app.auth.domain;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.ToString;

import java.time.Instant;

@Builder
@AllArgsConstructor
@ToString
public class User {
    public String username;
    public String password;

    public String nickname;

    public String status;
    public Instant createdAt;
    public Instant updatedAt;
}

날짜와 시간 데이터는 데이터베이스에서 timestamp, 자바에서는 Instant를 권합니다. 특히 타임존을 생략하고, UTC(이때는 GMT와 같은 표현)를 기준으로 시간을 다룰 수 있다는 메리트가 큽니다.

Instant는 자바 내의 여러 시간 표현 방식 중에 호환성이 아주 높은 편이기도 합니다.

Status로 표현되는 것은 enum이 낫습니다.

특히 이번처럼 필드 이름이 status라면 enum으로 만들어 봅시다. enum은 선택지가 있는 구조에서 잘 어울리는 클래스 유형입니다. 다음 enum 클래스는 PENDING, ACTIVE, PROTECTED, SUSPENDED, SLEPT, REMOVED 등 사용자 계정이 가질 수 있는 '상태'를 나열하고 있습니다. 사용자 계정은 이중에서 하나를 골라서 상태로 가질 수 있게 할 것입니다.

package com.example.app.auth.domain;

public enum UserStatus {
    PENDING,
    ACTIVE,
    PROTECTED,
    SUSPENDED,
    SLEPT,
    REMOVED
}

이것을 타입으로 사용할 때는 일반 클래스처럼 타입 선언부 등에 사용할 수 있습니다.

다음처럼 User 클래스에서 status 필드를 String에서 UserStatus 타입으로 바꿔 봅시다.

@Builder
@AllArgsConstructor
@ToString
public class User {
    // ... (중략)
    public UserStatus status; // String status -> UserStatus status
    // ...
}

원한다면 기본값을 줄 수 있습니다. 특히 필드 위에 @Builder.Default 애노테이션을 통해 이 기본값을 빌더도 사용하도록 허용해 주는 것이 좋습니다. 이번 구현에서는 생략하였습니다. 기본값은 ACTIVE를 사용하는 것보다 PENDING을 사용하는 것을 권합니다.

// 기본값을 둔다면 이렇게 작성하며, 이번에는 구현하지 않아도 됩니다.
@Builder.Default
public UserStatus status = UserStatus.PENDING;

기본값에 PENDING을 권한 이유는, 기본값 등 자동으로 채우는 데이터는 작업자 실수가 발생할 수 있기 때문입니다. 명시적으로 ACTIVE가 필요할 때는 우리가 코드에 직접 작성할 수 있기 때문이기도 합니다.