JPA를 이용하여 게시판 CRUD 만들기

juuuu·2025년 4월 13일
0

9oormthon

목록 보기
2/3

ERD(Entity Relationship Diagram)

데이터베이스 설계 과정에서 사용되는 모델링 기법 중 하나로, 데이터베이스에 저장될 데이터 엔티티(entity)들과 엔티티 간의 관계(relationship)를 시각적으로 표현

ERD의 용도

  • 데이터 베이스 모델링
    엔티티와 속성들을 테이블과 컬럼들로 변환
  • 소프트웨어 엔지니어링
    서로 다른 시스템 요소와 서로 간의 관계를 식별하는데 도움이 됨

ERD 구성요소

Entity

어떤 시스템인지에 따라 Entity는 사람, 장소, 사건(이벤트), 오브젝트가 될 수 있음
데이터베이스의 테이블이 엔티티로 표현됨

Attribute

특성, 엔티티의 성격, 관계, 또 다른 속성
데이터베이스의 테이블의 각 필드(컬럼)들이 엔티티 속성

Relationship

엔티티 사이의 논리적인 연결 즉 엔티티와 엔티티가 존재의 형태나 행위로서 서로에게 영향을 주는 형태

Domain

속성의 값, 타입, 제약사항 등에 대한 범위를 표현
사용자의 기호에 따라 속성 타입만 그릴수도 있고 가독성을 위해서 생략할 수도 있음

ERD 키와 제약 조건 표기법

주 식별자(PK)

데이터베이스 테이블의 Primary Key표현
중복이 없고 NULL 값이 없는 유일한 값에 지정하는 식별자
◆ 다이아몬드로 표현하기도 하고 아니면 열쇠로도 표현하기도 함
주 식별자는 유일한 속성이므로 다른 속성과의 명확한 구분을 위해 구분선을 두기도 함

NOT NULL

해당 속성에 들어갈 값에 NULL을 비허용한다면 N 혹은 NN을 적음
만약 NULL을 허용한다면 N을 적지 않음

외래 식별자(FK)

데이터베이스 테이블의 Foreign Key를 표현
외래 식별자 역시 Key의 일종이기 때문에 ERD 엔티티에도 열쇠 아이콘으로 표시
외래 식별자를 표시할 때에는 선을 이어주는데 개체와 관계를 따져 표시

ERD 엔티티 관계 표기법

엔티티끼리 관계가 있는 경우 선을 이어 관계를 맺어야 함
부모의 키를 자식에서 PK로 쓰는지 일반 속성으로 사용하는지에 따라 실선인지 점선인지 나뉘게 됨
실선으로 그으면 강한 관계를 나타내는 것이며 식별자 관계
점선으로 그으면 약한 관계를 나타내는 것이며 비식별자 관계

ERD 네이밍 규칙

  • 테이블 이름은 직관적이어야하고 약어는 지양해야함
  • 테이블 이름은 복수로 정해야 함

Cardinality

  • 테이블 간의 관계를 명시하는 표현
  • 1:1 관계: 유저당 유저 이메일
  • 1:n 관계: 한 유저당 여러 개의 상품을 장바구니에 넣는 경우
  • n:m 관계: 학생과 강의의 관계

함수적 종속성

  • DB 속성들간의 종속 관계

  • 학번을 통해 학생의 학년을 알 수 있다 (학번은 중복될 수 없다)
  • 학번, 과목번호 ▶️ 성적
    완전 함수 종속: 학번과 과목번호를 모두 알아야 성적을 알 수 있다
    즉 Y가 X의 전체에 종속됨
  • 과목번호, 학번 ▶️ 학년
    부분 함수 종속: 학년을 알기 위해서는 과목번호까지는 몰라도 된다
    즉 Y가 X의 부분만 종속됨

CRUD

"Create, Read, Update, Delete"의 약어로 데이터 베이스와 같은 시스템에서 기본적인 데이터 관리 기능을 의미

DB에서의 CRUD

  • Create(생성): 새로운 데이터 생성
  • Read(읽기): 데이터 조회
  • Update(갱신): 기존 데이터 수정
  • Delete(삭제): 데이터 삭제

REST API에서의 CRUD

  • Create(생성)
    -HTTP 메서드: POST
    -ex) 새로운 사용자 생성
  • Read(읽기)
    -HTTP 메서드: GET
    -ex) 모든 사용자 목록 가져오는 경우
  • Update(갱신)
    -HTTP 메서드: PUT 또는 PATCH
    -ex) 특정 사용자의 정보 업데이트
  • Delete(삭제)
    -HTTP 메서드: DELETE
    -ex) 특정 사용자 삭제

CRUD 구현

기능HTTPURL
게시글 목록 조회GET/posts
게시글 단건 조회GET/posts/{id}
게시글 작성POST/posts
게시글 수정PUT/posts/{id}
게시글 삭제DELETE/posts{id}

계층 분리 구조

  • Controller는 요청을 받고
  • Repository는 DB와 통신을 하고
  • Service는 그 사이에서 진짜 로직을 처리

게시판 엔티티

package com.goormthonUniv.goormthon.entity;

import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Column;

@Entity
public class Post {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false, length = 100)
    private String title;

    @Column(nullable = false, columnDefinition = "TEXT")
    private String content;

    public Long getId() {
        return id;
    }

    public String getTitle() {
        return title;
    }

    public String getContent() {
        return content;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public void setContent(String content) {
        this.content = content;
    }
}

Controller

package com.goormthonUniv.goormthon.controller;

import com.goormthonUniv.goormthon.dto.PostRequestDto;
import com.goormthonUniv.goormthon.dto.PostResponseDto;
import com.goormthonUniv.goormthon.repository.PostRepository;
import com.goormthonUniv.goormthon.service.PostService;
import jakarta.validation.Valid;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/posts")
public class PostController {

    private final PostService postService;

    public PostController(PostService postService) {
        this.postService = postService;
    }

    @PostMapping
    public ResponseEntity<PostResponseDto> createPost(@RequestBody PostRequestDto request) {
       PostResponseDto response = postService.createPost(request);
       return new ResponseEntity<>(response, HttpStatus.CREATED);
    }

    @GetMapping
    public List<PostResponseDto> list() {
        return postService.getAllposts();
    }


    @GetMapping("/{id}")
    public PostResponseDto get(@PathVariable Long id) {
        return postService.getPost(id);
    }

    @DeleteMapping("/{id}")
    public ResponseEntity<String> delete(@PathVariable Long id) {
        postService.deletePost(id);
        return ResponseEntity.ok("게시글이 성공적으로 삭제되었습니다.");
    }

    @PutMapping("/{id}")
    public PostResponseDto update(@PathVariable Long id, @RequestBody @Valid PostRequestDto request) {
        return postService.updatePost(id, request);
    }
}

POST

GET


DELETE

  • DELETE 후 GET 실행하여 삭제되었는지 확인

PUT

-PUT 후 GET 실행하여 제대로 수정이 되었는지 확인


어노테이션 개념 정리

어노테이션위치설명
@RestControllerController이 클래스가 REST API 요청을 처리하는 컨트롤러임을 나타냄
리턴값이 자동으로 JSON으로 변환
@RequestMapping("/posts")Controller이 컨트롤러의 기본 경로를 설정
@PostMappingControllerHTTP POST 요청을 처리
@GetMappingControllerHTTP GET 요청을 처리
@DeleteMappingControllerHTTP DELETE 요청을 처리
@PutMappingControllerHTTP DELETE 요청을 처리
@PathVariableControllerURL 경로에 있는 값을 변수로 받기
/posts/3 → id = 3
@RequestBodyController요청 바디의 JSON → Java 객체로 변환
@ValidController@RequestBody로 받은 DTO의 유효성 검사를 수행
@ServiceService이 클래스가 비즈니스 로직을 수행하는 Service 컴포넌트임을 Spring에게 알려줌
@EntityEntity이 클래스가 JPA가 관리하는 엔티티임을 나타냄
@IdEntity이 필드가 테이블의 기본 키(PK) 임을 나타냄
@GeneratedValue(strategy = GenerationType.IDENTITY)Entityid 값을 DB가 자동 생성하도록 지정
@Column(nullable = false, length = 100)Entity이 필드를 DB 컬럼으로 매핑 + 컬럼 제약 조건 설정
@Column(nullable = false, columnDefinition = "TEXT")Entity이 필드를 DB에서 TEXT 타입 컬럼으로 저장

0개의 댓글