이제 SBB가 사용할 엔티티(Entity)을 만들어 보자. 엔티티는 데이터베이스 테이블과 매핑되는 자바 클래스를 말한다. SBB는 질문과 답변을 할 수 있는 게시판 서비스이다. 따라서 SBB에는 질문과 답변에 해당하는 엔티티가 있어야 한다.

엔티티는 모델 또는 도메인 모델이라고 부르기도 한다. 이 책에서는 이것들을 구분하지 않고 테이블과 매핑되는 클래스를 엔티티라 지칭하겠다.

질문 엔티티를 다음과 같은 코드로 작성하자.

엔티티로 만들기 위해서는, 엔티티로 만드려는 클래스에 @Entity 어노테이션을 적용시킨다. 위 코드에서는 Question이라는 클래스가 엔티티가 되었다.@Entity 애너테이션을 적용해야 JPA가 엔티티로 인식한다. 그리고 Getter, Setter 메서드를 자동으로 생성하려면 롬복의 @Getter, @Setter 애너테이션을 적용했다.

롬복(Lombok)은 여러가지 @어노테이션을 제공하고 이를 기반으로 반복 소스코드를 컴파일 과정에서 생성해주는 방식으로 동작하는 라이브러리이다.

 

그리고 엔티티의 속성으로 고유번호(id), 제목(subject), 내용(content), 작성일시(createDate)를 추가했다. 각 속성에는 Id, GeneratedValue, Column과 같은 애너테이션이 적용되어 있는데 그것들에 대해서 하나씩 알아보자.

 

@Id

고유 번호 id 속성에 적용한 @Id 애너테이션은 id 속성을 기본 키로 지정한다. 기본 키로 지정하면 이제 id 속성의 값은 데이터베이스에 저장할 때 동일한 값으로 저장할 수 없다. 고유 번호를 기본 키로 한 이유는 고유 번호는 엔티티에서 각 데이터를 구분하는 유효한 값으로 중복되면 안 되기 때문이다.

데이터베이스에서는 id와 같은 특징을 가진 속성을 기본 키(primary key)라고 한다.

@GeneratedValue

@GeneratedValue 애너테이션을 적용하면 데이터를 저장할 때 해당 속성에 값을 따로 세팅하지 않아도 1씩 자동으로 증가하여 저장된다. strategy는 고유번호를 생성하는 옵션으로 GenerationType.IDENTITY는 해당 컬럼만의 독립적인 시퀀스를 생성하여 번호를 증가시킬 때 사용한다.

strategy 옵션을 생략할 경우에 @GeneratedValue 애너테이션이 지정된 컬럼들이 모두 동일한 시퀀스로 번호를 생성하기 때문에 일정한 순서의 고유번호를 가질수 없게 된다. 이러한 이유로 보통 GenerationType.IDENTITY를 많이 사용한다.

@Column

엔티티의 속성은 테이블의 컬럼명과 일치하는데 컬럼의 세부 설정을 위해 @Column 애너테이션을 사용한다. length는 컬럼의 길이를 설정할때 사용하고 columnDefinition은 컬럼의 속성을 정의할 때 사용한다. columnDefinition = "TEXT"은 "내용"처럼 글자 수를 제한할 수 없는 경우에 사용한다.

엔티티의 속성은 @Column 애너테이션을 사용하지 않더라도 테이블 컬럼으로 인식한다. 테이블 컬럼으로 인식하고 싶지 않은 경우에만 @Transient 애너테이션을 사용한다.

점프 투 스프링부트테이블의 컬럼명

위의 Question 엔티티에서 작성일시에 해당하는 createDate 속성의 실제 테이블의 컬럼명은 create_date가 된다. 즉 createDate처럼 대소문자 형태의 카멜케이스(Camel Case) 이름은 create_date 처럼 모두 소문자로 변경되고 언더바(_)로 단어가 구분되어 실제 테이블 컬럼명이 된다.

점프 투 스프링부트엔티티와 Setter

일반적으로 엔티티에는 Setter 메서드를 구현하지 않고 사용하기를 권한다. 왜냐하면 엔티티는 데이터베이스와 바로 연결되어 있으므로 데이터를 자유롭게 변경할 수 있는 Setter 메서드를 허용하는 것이 안전하지 않다고 판단하기 때문이다.

그렇다면 Setter 메서드 없이 어떻게 엔티티에 값을 저장할 수 있을까?

엔티티를 생성할 경우에는 롬복의 @Builder 어노테이션을 통한 빌드패턴을 사용하고, 데이터를 변경해야 할 경우에는 그에 해당되는 메서드를 엔티티에 추가하여 데이터를 변경하면 된다.

다만, 이 책은 복잡도를 낮추고 원활한 설명을 위해 엔티티에 Setter 메서드를 추가하여 진행하려 한다.

 

질문 엔티티를 생성했으니, 이제 질문을 했으니 당연히 답변이 와야 한다. 따라서 답변 엔티티를 다음과 같이 작성한다.

질문 엔티티 코드와는 다르게 private Question question; 속성이 새롭게 추가되었다. 왜 질문 속성이 추가되었냐면, 답변 엔티티에서 질문 엔티티를 참조하기 위해 추가했다. 예를 들어 답변 객체(예:answer)를 통해 질문 객체의 제목을 알고 싶다면 answer.getQuestion().getSubject()처럼 접근할 수 있다. 하지만 이렇게 속성만 추가하면 안되고 질문 엔티티와 연결된 속성이라는 것을 명시적으로 표시해야 한다.

 

다음 포스팅에서 질문 엔티티와 연결된 속성이라는 것을 명시적으로 표시하는 법을 설명하겠다.

'백엔드 > Springboot' 카테고리의 다른 글

리포지터리(Repository) -1-  (0) 2023.09.18
엔티티(Entity) -2-  (0) 2023.09.17
JPA 환경설정  (0) 2023.09.17
JPA  (1) 2023.09.17
ORM(Object Relational Mapping)  (0) 2023.09.17

+ Recent posts