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

> (다른 글 목차 삽입 예정)

# Entity 클래스

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

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

## 롬복 추가하기

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

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

```java
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`
    

```java
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` 등 사용자 계정이 가질 수 있는 '상태'를 나열하고 있습니다. 사용자 계정은 이중에서 하나를 골라서 상태로 가질 수 있게 할 것입니다.

```java
package com.example.app.auth.domain;

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

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

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

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

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

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

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