[SpringBoot] IntelliJ, MySQL, gradle 2. 폴더 구성하기

황유민 Yoomin Hwang·2024년 7월 26일

WEB

목록 보기
9/15

MVC 패턴 적용하기

폴더 구성에서부터 MVC 패턴을 활용하기 위한 세팅을 해주면 좋음

  1. 다루고자 하는 기능, entity, 주제의 핵심이 되는 개념들을 각각 패키지로 만들어준다.
  2. 각 패키지 안에 밑의 폴더들을 또 만들어준다.
    • controller, dto, entity, repository, service 이렇게 5개 폴더가 기본인데 여기서 사용할 개념들만 폴더 만들어서 써도 됨
    • 참고로 config는 로그인이랑 프론트 할 때 추가해주어야 함
  3. 각각 무슨 역할인지 이제부터 설명 예정

Entity

엔티티가 뭔지는 여기서

  • 각 엔티티에 포함되어야 할 개념들이 이 폴더 안에 들어갈 예정
  • 그리고 각 개념들을 의미하는 .java 파일 안에는 해당 개념을 이루는 변수들, 객체들 그리고 buildertoString method 정도가 포함됨
  • 예를 들어, 회의실 예약 시스템을 만들 때 Reservation 엔티티 안에 Reservation.java 파일이 있고 그 안에는 private Long id 가 있는 느낌쓰
import com.camp.reservation.reservation.room.entity.Room;

import jakarta.persistence.*;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import java.time.LocalDate;
import java.time.LocalTime;

@Entity
@Getter
@EntityListeners(AuditingEntityListener.class)
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Reservation {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false)
    private String userName;

    @Column(nullable = false)
    private String userFaculty;

    @ManyToOne
    @JoinColumn(name = "room_id", nullable = false)
    private Room room;

    @Column(nullable = false)
    private LocalDate date;

    @Column(nullable = false)
    private LocalTime startTime;

    @Column(nullable = false)
    private LocalTime endTime;

    @Column(nullable = false)
    private int capacity;

    @Column(nullable = false)
    private String groupname;

    @Column(nullable = false)
    private String purpose;

    @CreatedDate
    @Column(updatable = false)
    private LocalDate createdDate;

    @LastModifiedDate
    private LocalDate lastModifiedDate;

    @Builder
    public Reservation(String userName, String userFaculty, Room room, LocalDate date, LocalTime startTime, LocalTime endTime, int capacity, String groupname, String purpose) {
        this.userName = userName;
        this.userFaculty = userFaculty;
        this.room = room;
        this.date = date;
        this.startTime = startTime;
        this.endTime = endTime;
        this.capacity = capacity;
        this.groupname = groupname;
        this.purpose = purpose;
    }

    @Override
    public String toString() {
        return "Reservation{" +
                "id=" + id +
                ", user=" + userName +
                ", userFaculty=" + userFaculty +
                ", room=" + room +
                ", date=" + date +
                ", startTime=" + startTime +
                ", endTime=" + endTime +
                ", capacity=" + capacity +
                ", groupname='" + groupname + '\'' +
                ", purpose='" + purpose + '\'' +
                '}';
    }
}

설명

Entity Annotation

  • JPA 에서 가져옴

@Id

@CreatedTime

@LastModifiedTime

  • generatedvalue annotation: 개발자가 직접 관리 안해도 지가 알아서 1, 2, 3, 이렇게 변하길 원한다고 annotation을 통해 말하는 것

@Column(name =”author”, nullable=false)

  • 안써도 됨
    → 안 써도 이름이 변수명과 동일하게 설정됨
    → 다만 안 쓰면 null 값 방지가 사라짐
    쓰면 널값을 db차원에서 방지해줌

  • 자바 코드를 SQL로 번역해준다 했는데 보통 자바에서는 camel case로 쓰고 SQL은 언더바로 구분함

@Column(name = “원하는 이름”)

이걸 일일이 안해줘도 SQL 입장에서는 자바 문법이 사투리니까 그걸 default로 번역해줌

@Auditing

  • 붙이려면 main에다가 같이 해줘야함

@Builder

  • 빌더 패턴: 자바 문법 (스프링 문법 아님)
  • 작가, title, 컨텐츠 들어오면 저장해줌
  • id는 왜 안넣어주나?
    자동으로 만들어지는 값이니까!
    프론트에서 받는 걸 자동으로 만들어주면 안되니까
  • 자동으로 만들어주는 건 파라미터로 넣으면 안 됨

import jakarta.persistence.*;
→ JPA 에서 import 하는 것

코드 수 를 줄여준다? 보통 Lombok 에서 온다고 생각

DB 와 관련되어 있다? 보통 JPA 에서 온다고 생각

  • Entity는 불변 객체 가 아님
    틀 자체는, 즉 테이블은 변경될 수 없으나 그 값들은 변경 가능하다

DTO

Data Transfer Object

  • 택배 박스라고 생각하면 됨
    즉, 뭔가를 보낼 때 그걸 담을 객체
  • DTO 객체는 대충 프론트로부터 받을 내용과 같은 형식으로 만들어 주면 됨

왜?

  • 기능하는 건 없고 그저 전달의 역할만 수행
  • 뭔가 바뀌면 안됨

불변 객체의 역할

  • 따라서 final로 선언해줌

record

  • 원래는 class 만들 때 생성자 접근자 만들어주고 해야 하는데 요즘 JAVA 에서 편하게 쓸 수 있는 기능 record

자바에서 신식 문법이라 할 수 있는 부분

가독성 측면에서도 아 이 부분은 전달 역할만 하는구나 라고 바로 인식할 수 있음

⇒ 근데 class로 먼저 플로우와 그 불편함을 경험하고 나서 쓰는 것을 더 추천함
왜 편한지를 알아야 편하게 쓸 수 있을 것이기 때문

public record BoardCreateDTO {

}

Controller

Dispatcher Servlet: Tomcat에서 browser 에 띄워주고 Dispatcher가 전달하는 servlet 작은 알맹이

  • Controller 는 디스패처 서블릿이 전달해준 거 받음
  • 해당 url로 post 요청이 옴
  • 프론트에서 post api로 보낸 걸 받음

@PostMapping(”/api/board/save”)

@RequestBody 로 받음 → 프론트에서 보낸 내용 전달 받음 → 안쓰면 인식을 못하고 null값 들어감

  • Controller는 서버에서 주문 받는 사람이라고 보면되고 Service가 실제 요리하는 사람

Service

  • 주요 기능은 서비스 센터에서 맡기듯이 다 service에서 하는 것

클라이언트에서 요구하는 것 = 비즈니스 로직 이라 한다

  • 두 가지 파일로 나우기: request 파일 + response 파일

  • 스프링부트 입장에서 요청 받으면 request

  • 반대로 답변 주면 response

요청 받는 것 ⇒ requestbody ⇒ dto

  • Controller 가 서비스 부를 때

controller → service → db

  • service가 생성자를 만드는 코드가 controller 안에 있어야 함
  • lombok에서 제공해주는 @RequiredArgsContructor

@service

  • Service랑 Controller는 spring web에서 제공함

  • DTO: client에서 back으로 전달되는 방식

  • Entity: back에서 db로 전달되는 방식

→ 알맞는 형식으로 바꿔야 함

따라서 toEntity라는 함수를 DTO 안에 만들어준 이유: 받은 DTO 를 Entity로 만들어준다는 것

Repository

  • Repository 에서는 JPA 사용

  • JPA 에서 기본으로 제공해주는 것 중 하나가 insert 함수를 save라는 함수로 사용 가능

boardRepository.save(board)
  • id에는 기본적으로 Not null 설정 되어 있음

postman

이렇게 열심히 만든 API를 프론트 없이 테스트 해보고 싶을 때 사용할 수 있는 툴

0개의 댓글