Skip to main content

Command Palette

Search for a command to run...

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

Updated
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가 필요할 때는 우리가 코드에 직접 작성할 수 있기 때문이기도 합니다.

More from this blog

클래스에 Serializable 인터페이스를 구현 받는 이유가 무엇인가요? #42

이 아티클은 깃허브 nettee-space 조직의 디스커션 #42 항목을 옮겨 온 것입니다.관련 논의: nettee-space/backend-sample-hexagonal-simple-crud/discussions/42 Question: 클래스에 Serializable 인터페이스를 구현 받는 이유가 무엇인가요? 여러 소스들을 접하면서 VO 객체 등에 Serializable를 구현받는 것을 많이 접했습니다. 저희 헥사고날(스터디 팀내 2단계 ...

Feb 7, 2025
클래스에 Serializable 인터페이스를 구현 받는 이유가 무엇인가요? #42

개념 2. JWT 액세스 토큰의 생성과 전달, Stateful한 리프레시 토큰의 생성, 전달, 보존

이전 글에서 정리에 꽤 힘을 뺐기 때문에, 이번 글에서는 서두와 부연설명을 줄이고 필요한 정보를 담아 전달해 보겠습니다. JWT 액세스 토큰 JWT 액세스 토큰은 인가에 직접 사용되는 토큰이고, stateless 하다는 장점이 있었습니다. 액세스 토큰의 생성 JWT(JSON Web Token)로 생성합니다. 비밀번호 인증 등 자격 검토 후 JWT를 발급합니다. JWT는 헤더, 페이로드, 시그니처 세 영역을 점(.) 기호로 구분한다고 했습니다....

Oct 23, 2024
개념 2. JWT 액세스 토큰의 생성과 전달, Stateful한 리프레시 토큰의 생성, 전달, 보존

Merge Simpson의 매너 있고 다정한 한국어 개발자 블로그

37 posts