(3) 엔티티(Entity)
엔티티 구상 및 작성하기
시작하기 전에
개요 : 질문과 답변을 할 수 있는 게시판 서비스를 스프링부트를 통해 만들어 본다.
학습사이트 : https://wikidocs.net/book/7601
예제 코드 : https://github.com/pahkey/sbb
사용할 툴과 미리 익혀놓을 개념에 대해서 알아보자
H2 데이터베이스
주로 개발용이나 소규모 프로젝트에서 사용되는 파일 기반의 경량 데이터베이스. (참고 사이트 : https://kukim.tistory.com/105)
- 세팅 순서
-
gradle파일 dependoncies에 아래 코드 추가
runtimeOnly 'com.h2database:h2'
-
application.properties 파일에 아래 코드 추가
# DATABASE # 콘솔 접속 허용여부 spring.h2.console.enabled=true # 콘솔 접속을 위한 URL spring.h2.console.path=/h2-console # 데이터베이스 접속을 위한 경로 -> 홈 디렉토리 spring.datasource.url=jdbc:h2:~/local # 데이터베이스 접속시 사용하는 드라이버 spring.datasource.driverClassName=org.h2.Driver # 사용자명 / 패스워드 spring.datasource.username=sa spring.datasource.password=
-
홈 디렉토리에 local.mv.db 파일 생성
-
- 접속
- URL : http://localhost:8080/h2-console
- 연결 버튼을 클릭하면 local.mv.db파일과 연결됨
ORM (Object-Relational Mapping)
- Class와 RDB의 테이블을 매핑한다는 뜻
- 객체를 통해 간접적으로 데이터베이스 데이터를 다룬다
JPA (Java Persistence API)
- Java에서 ORM 기술 표준으로 사용하는 인터페이스 모음
- JPA를 구현한 대표적 실제 클래스에는 하이버네이트등이 있다
- 자바 프로그램에서 DB에 데이터를 저장하거나 조회하려면 JPA사용
- 세팅 순서
-
gradle파일 dependoncies에 아래 코드 추가
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
-
application.properties 파일에 아래 코드 추가
# JPA # DB엔진 종류 설정 spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect # 엔티티를 기준으로 테이블을 생성하는 규칙을 정의. 아래의 코드는 update spring.jpa.hibernate.ddl-auto=update # 개발 환경에서는 보통 update 모드를 사용하고 운영환경에서는 # none(엔티티가 변경되더라도 데이터베이스를 변경하지 않음) 또는 # validate(변경사항이 있는지 검사만 함) 모드를 사용한다.
-
엔티티(Entity)란
- 데이터베이스 테이블과 매핑되는 자바 클래스
- 우리가 만들려는 웹사이트는 질문과 답변을 할 수 있는 게시판 서비스이므로, 질문과 답변에 해당하는 엔티티가 있어야 한다.
엔티티 속성 구상
- 질문 엔티티
속성명 | 설명 |
---|---|
id | 질문의 고유 번호 |
subject | 질문의 제목 |
content | 질문의 내용 |
create_data | 질문을 작성한 일시 |
- 답변 엔티티
속성명 | 설명 |
---|---|
id | 답변의 고유 번호 |
question | 질문(어떤 질문의 답변인지 알아야 함) |
content | 답변의 내용 |
create_data | 답변을 작성한 일시 |
엔티티 작성하기
질문 엔티티
- Question.java
package com.mysite.sbb;
import java.time.LocalDateTime;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@Entity
public class Question {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(length = 200)
private String subject;
@Column(columnDefinition = "TEXT")
private String content;
private LocalDateTime createDate;
}
- @Entity
- 에너테이션을 적용해야 JPA가 엔티티로 인식.
- @Id
- id에너테이션을 적용하면 고유번호적용 → primary key
- @GeneratedValue
- strategy : 고유번호를 생성하는 옵션
- IDENTITY : 해당 컬럼만의 독립적인 시퀀스 생성
- 해당 속성에 값을 따로 세팅하지 않아도 1씩 자동증가
- Colums
- 테이블의 컬럼 세부 설정
- (length = 200) : subject의 길이 200
- (columnDefinition = “TEXT”) : 글자 수를 제한할 수 없는 경우 사용
참고사항
- 테이블의 컬럼명
- 위의 Question 엔티티에서 작성일시에 해당하는 createDate 속성의 실제 테이블의 컬럼명은 create_date가 된다.
- 대소문자 형태의 카멜케이스(단어 중간에 대문자가 들어가는 표기) 는 언더바(_)로 치환되어 실제 테이블 컬럼명이 된다.
- 엔티티와 Setter
- 일반적으로 엔티티에는 Setter 메서드를 구현하지 않고 사용하기를 권한다. 왜냐하면 엔티티는 데이터베이스와 바로 연결되어 있으므로 데이터를 자유롭게 변경할 수 있는 Setter 메서드를 허용하는 것이 안전하지 않다고 판단하기 때문이다.
- Setter 메서드 없이 값을 저장하는 방법 : 엔티티를 생성할 경우에는 롬복의 @Builder 어노테이션을 통한 빌드패턴을 사용하고, 데이터를 변경해야 할 경우에는 그에 해당되는 메서드를 엔티티에 추가하여 데이터를 변경하면 된다.
- 단 “점프 투 스프링부트”에서는 원활한 설명을 위해 엔티티에 Setter 메서드를 사용.
답변 엔티티
- Answer.java
package com.mysite.sbb;
import java.time.LocalDateTime;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@Entity
public class Answer {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(columnDefinition = "TEXT")
private String content;
private LocalDateTime createDate;
@ManyToOne
private Question question;
}
- @ManyToOne
- 이름 그대로 N : 1 관계 (하나의 질문엔 여러개의 답변이 달릴 수 있다)
- Answer 엔티티가 Question엔티티를 참조해야한다
- 참조키(외래키) 관계
- 답변 엔티티의 question 속성은 어떤 질문의 답변인지 알아야 하기 때문에 추가된 속성이다. 따라서 ManyToOne 에너테이션을 추가해줘야 한다
- @OneToMany
- 반대방향 : Question 엔티티가 Answer 를 참조하는 방법
- 하나의 질문에 답변은 여러개이므로 Question 엔티티 의 속성은 List 형태로 구현해야 함
- Question.java파일에 아래의 코드 추가
// import 추가 import java.util.List; import javax.persistence.OneToMany; public class Question { // Question 클래스에 아래의 코드 추가 @OneToMany(mappedBy = "question", cascade = CascadeType.REMOVE) private List<Answer> answerList; }
- mappedBy
- 참조 엔티티의 속성명을 의미한다.
- cascade
- 연쇄삭제
- 질문이 삭제되면 달려있는 답변도 모두 삭제되어야 한다.
테이블 확인
- 코드 저장 후 h2 데이터베이스 접속
- ANSWER과 QUESTION 테이블 생성됨.
- 생성되지 않을 시 로컬 서버 재시작
- Question.java파일에 createDate를 creteDate라 오타를 내어 한 칼럼이 더 생성됨….
- h2콘솔에서 아래의 sql문 실행
- ALTER TABLE QUESTION DROP COLUMN CRETE_DATE
- 컬럼을 삭제하는 sql문
Leave a comment