Gathering Backend 구현 1 (프로젝트 생성 및 엔티티 설계)
백엔드는 Java-Spring boot로 진행하려고 한다.
이에 따라 https://start.spring.io/ 를 이용하여 패키지를 생성한다.
해당 부분에 대한 설명은
https://dev-studyingblog.tistory.com/92
Spring boot 시작하기
스프링 부트는 스프링부트 스타터(https://start.spring.io/)라는 사이트를 이용하여 편리하게 프로젝트를 생성할 수 있다.스프틸 부트 스타터에서 다음과 같은 세팅을 설정한다.Project 선택 (Project Type)
dev-studyingblog.tistory.com
해당 부분을 참고 하면 된다.
다음과 같이 설정하고 generate를 진행하였다.
프로젝트 생성후 다음과 같이 build.gradle에 종속성을 추가해준다.
// Spring Boot Dependencies
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
// Database
runtimeOnly 'com.h2database:h2' // H2 Database
implementation 'mysql:mysql-connector-java' // MySQL
// Lombok
implementation 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
// Validation
implementation 'org.springframework.boot:spring-boot-starter-validation'
// Testing
testImplementation 'org.springframework.boot:spring-boot-starter-test'
프로젝트 디렉토리는 다음과 같이 설정해준다.
com.gathering.gathering_backend
├── config # 프로젝트 설정 관련
├── controller # REST API 컨트롤러
├── dto # 요청 및 응답 DTO
├── entity # JPA 엔티티 클래스
├── repository # JPA 레포지토리 인터페이스
├── service # 서비스 로직
└── util # 유틸리티 클래스
다음과 같은 역할을 하도록 진행해줄 예정이다.
그 후, ERD를 바탕으로 엔티티를 설계 해준다. (https://www.erdcloud.com/d/zcA9DF5Y9759FhTvK)
예시는 다음과 같다.
Post Entity
package com.gathering.gathering_backend.entity;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import java.time.LocalDateTime;
@Entity
@Getter
@Setter
@NoArgsConstructor
public class Post {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long postNo;
@Column(nullable = false, length = 30)
private String postName;
@Column(nullable = false)
private int postMember;
@Column(nullable = false)
private int postMaxMem;
@Column(columnDefinition = "TEXT")
private String postDetail;
@Column(columnDefinition = "TEXT")
private String postGather;
private String postImg;
@Column(nullable = false)
private LocalDateTime postDate;
@Column(nullable = false)
private boolean postComplete;
private LocalDateTime postEndDate;
private LocalDateTime postDeleteDate;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "userNo", nullable = false)
private User user;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "cxNo", nullable = true)
private ExternalAct externalAct;
}
사용한 어노테이션과 파라미터에 대해 간단히 설명하겠다.
- @Entity는 이 클래스가 데이터베이스 테이블과 매핑된다는 것을 JPA에 알려주기 위해 사용한다.
- @Getter, @Setter는 Lombok을 활용해 Getter와 Setter 메서드를 자동 생성하여 코드 작성을 줄이기 위해 사용한다.
- @NoArgsConstructor는 기본 생성자를 자동 생성해 객체 생성 시 유연성을 높이기 위해 사용한다.
- @Id와 @GeneratedValue(strategy = GenerationType.IDENTITY)는 해당 필드를 기본 키로 지정하고, 데이터베이스가 자동으로 값을 생성하도록 설정하기 위해 사용한다.
- @Column(columnDefinition = "TEXT")는 해당 컬럼이 TEXT 타입으로 데이터베이스에 저장되도록 지정하기 위해 사용한다.
- @ManyToOne(fetch = FetchType.LAZY)와 @JoinColumn(name = "userNo", nullable = true)는 다른 엔티티와의 다대일 관계를 매핑하고, 외래 키로 userNo를 지정하기 위해 사용한다. -> 이때 XToOne의 경우 기본은 즉시로딩이여서 지연로딩으로 변경하였다. 지연로딩을 사용하면 엔티티 간의 관계 데이터를 "필요한 시점"에 로드할 수 있다.
User Entity
package com.gathering.gathering_backend.entity;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import java.util.List;
@Entity
@Getter
@Setter
@NoArgsConstructor
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long userNo;
@Column(nullable = false, unique = true, length = 20)
private String userId;
@Column(nullable = false, length = 100)
private String userPw;
@Column(nullable = false, length = 20)
private String userName;
@Column(columnDefinition = "TEXT")
private String userDescription;
@Column(nullable = false)
private int userType;
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Post> posts;
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Comment> comments;
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
private List<SearchHistory> searchHistories;
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Notification> notifications;
}
공통된 부분을 제외하고
- @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)는 이 엔티티와의 일대다 관계를 매핑하며, 연관된 엔티티의 영속성 전이와 고아 객체 제거를 자동화하기 위해 사용한다. -> 영속성 전이란 부모 엔티티의 상태 변경(저장, 삭제 등)이 연관된 자식 엔티티에도 자동으로 전파되도록 설정하는 기능이며, 고아 객체 제거란 부모 엔티티와의 관계가 끊어진 자식 엔티티를 자동으로 삭제하는 기능을 말한다.
이후 부분은 중복되기 때문에 따로 설명을 제외하였다. (Comment, ExternalAct, Gather, SearchHistory, Notification, Interest)
해당 코드들은
https://github.com/software-gathering/gather-be1
GitHub - software-gathering/gather-be1
Contribute to software-gathering/gather-be1 development by creating an account on GitHub.
github.com
여기서 확인 가능하다.