2주차 스터디는 게시판, 댓글의 ERD를 설계하고 Spring에서 구현 후 JPA를 이용해 데이터 생성 및 ERD를 띄우는 겁니다.
일단 저는 게시판, 댓글의 ERD를 draw.io 에서 설계하다 user라는 테이블이 있으면 더 좋겠다고 생각이 들어 user또한 추가적으로 만들어보았습니다.
- 추후에 문제가 되면 수정하면 되니까..
사실 ERD설계는 학교 데이터베이스 수업때 제외하고 거의 한 적이 없어 가물가물했습니다...
아마도 어딘가 틀린 내용이 있을 것 같은 느낌..?
ERD설계 할 때마다 느끼는건데 머리가 아주 어질어질하다는점ㅋㅋ
ERD
ERD입니다.
첫번째로 user(사용자) 테이블입니다.
기본키 필드는 userId이며 타입은 Long, sql의 auto-increment를 사용할 예정입니다.
추가로 비밀번호 필드는 password 타입은 String입니다.
두번째로 comment(댓글) 테이블입니다.
기본키는 commentId이며 타입은 Long, userId와 똑같이 sql의 auto-increment를 사용할 예정입니다.
댓글의 외래키는 userId, postId입니다.
하나의 사용자는 여러개의 댓글을 등록할 수 있다. (1:N)
하나의 게시물에는 여러개의 댓글이 달릴 수 있다. (1:N)
이렇게 생각하여 이렇게 연관관계를 설정했습니다.
추가로 댓글의 내용 comment, 생성일시 createAt, 수정일시 modfiedAt 칼럼(필드)이 있습니다.
마지막으로 post(게시물) 입니다.
기본키는 postId이며 타입은 Long, userId와 똑같이 sql의 auto-increment를 사용할 예정입니다.
외래키는 userId입니다.
하나의 사용자는 여러개의 게시물을 등록할 수 있다. (1:N)
이렇게 생각하여 연관관계를 설정했슴다.
추가로 게시물 내용인 content, 생성일시 createAt, 수정일시 modfiedAt 칼럼(필드)이 있습니다.
Spring 내부에서 Entity 설계
User 클래스
package com.study.study.entity;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
@Entity
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Getter
@Table(name = "user")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long userId;
@Column(name = "password")
private String password;
}
Post 클래스
package com.study.study.entity;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.LastModifiedDate;
import java.util.List;
@Entity
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Getter
@Table(name = "post")
public class Post {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long postId;
@Column(columnDefinition = "TEXT", nullable = false)
private String content;
@Column(name = "modifiedAt")
@LastModifiedDate
private String modifiedAt;
@ManyToOne
@JoinColumn(name = "userId")
private User user;
@OneToMany(mappedBy = "post")
private List<Comment> comments;
}
Comment 클래스
package com.study.study.entity;
import jakarta.persistence.*;
import lombok.*;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
@Entity
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Table(name = "comment")
public class Comment {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long commentId;
@Column(columnDefinition = "TEXT", nullable = false)
private String comment;
@Column(name = "createAt")
@CreatedDate
private String createAt;
@Column(name = "modifiedAt")
@LastModifiedDate
private String modifiedAt;
@ManyToOne
@JoinColumn(name = "postId")
private Post post;
@ManyToOne
@JoinColumn(name = "userId")
private User user;
}
어노테이션 설명
@Entity
Entity 어노테이션은 DB의 테이블과 1:1로 매핑된다고 합니다.
즉, Entity 객체의 인스턴스 하나가 테이블에서 하나의 레코드 값이라고 할 수 있습니다.
속성으로 name이 있으며 JPA에서 사용할 엔티티의 이름을 지정합니다.
설정하지 않을 경우 클래스의 이름을 사용합니다.
추가로 JPA는 엔티티 객체를 생성할 때 기본 생성자를 사용하기 때문에 기본 생성자는 필수입니다.
@Table
엔티티와 매핑할 테이블을 지정합니다.
속성
name - 매핑할 테이블의 이름을 지정합니다. 설정하지 않으면 클래스의 이름을 사용합니다.
catalog - catalog 기능이 있는 데이터베이스에서 catalog를 매핑합니다.
schema - 스키마 기능이 있는 데이터베이스에서 스키마를 매핑합니다.
@Id
클래스 필드에 선언하며 해당 필드는 해당 Entity의 기본키(Primary Key) 가 될 것임을 지정합니다.
@GeneratedValue - 기본 키 자동생성 전략
대리키를 사용하는 전략입니다.
속성
strategy - 생성 전략을 설정해주기 위해 사용합니다.
- 생성 전략의 종류
IDENTITY - 생성 전략을 DB에게 위임합니다. 즉, DB의 기본키 생성 전략을 따라갑니다.
SEQUENCE - DB의 특별한 오브젝트 시퀸스를 사용하여 기본키를 생성합니다.
TABLE - DB에 키 생성 전용 테이블을 만들고, 이것을 사용해 기본키를 생성합니다.
AUTO - JPA구현체가 자동으로 생성전략을 결정합니다.
@Column
객체의 필드를 테이블의 컬럼에 매핑합니다.
속성
name - 필드와 매핑시킬 컬럼의 이름을 지정합니다
nullable - null값의 사용여부를 결정합니다. false면 NOT NULL 제약조건이 추가됩니다.
@ManyToOne(N:1)
Post클래스는 userId를 외래키를 갖고있는 연관관계의 주인입니다.
post입장에서 user 하나는 다수의 post를 작성할 수 있습니다
즉, post(N) : user (1) 로 판단을 하여 ManyToOne을 사용했습니다 (외래키는 userId로 지정)
Comment클래스는 postId, userId를 외래키를 갖고있는 연관관계의 주인입니다.
commnet입장에서 post(게시물)하나에 다수의 comment를 작성할 수 있습니다.
즉, comment(N) : post(1) 로 판단하여 ManyToOne을 사용했습니다.
+ comment입장에서 user 하나는 다수의 comment를 작성할 수 있습니다.
즉, comment(N) : user(1) 로 판단하여 ManyToOne을 사용했습니다.
@OneToMany
이 어노테이션을 잘 사용했는지는 모르겠습니다.
사용한 클래스는 Post클래스입니다.
왜 사용하자는 판단을 했느냐?
OneToMany 즉, 일대다 관계(1:N)..
게시물 입장에서는 하나의 게시물에 많은 댓글이 달릴 수 있습니다.
즉 post(1) : comment(N) 이 아닌가? 싶지 않아 이런 연관관계를 설정했어요!..
++
추가적으로
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Getter
이 어노테이션들은 LomBok 플러그인이 지원하는 어노테이션입니다.
JPA를 이용해 엔티티를 설계할 때 생성자 및 접근자, 빌더패턴을 사용해야 된다~ 라고 어느 블로그에서 봤습니다.
그렇기 때문에 사용한 어노테이션입니다.
데이터 바인딩 및 ERD를 띄워보자
엔티티 설정을 모두 마친 후 서버를 실행시킵니다.
콘솔 로그에 JPA hibernate가 쿼리문을 짜쭈는걸 확인 가능합니다.
그리고 DataGrip에 들어가 확인해봅시다
테이블이 생성된걸 확인 가능
+ 외래키 기본키도 생성이 됐다.
++ 근데 post의 댓글 객체는 생성이 안됐네 칼럼을 지정 안해줘서 그런가?..
ERD를 띄워보자
이렇게 하단에 Persistence가 있습니다.
main 내부에 entityManagerFactory가 있습니다.
우클릭 후 Entity Relationship Diagram 클릭
이렇게 인텔리제이 내부에서 ERD를 확인할 수 있습니다~
뭐 잘 짠건지는 잘 모르겠지만 에러 안나고 잘 된거에 다행이라고 여기자^^
+ 추가 application.yml 세팅
이렇게 JPA를 통해 엔티티를 설계하고 DB와 바인딩을 하려면 세팅을 먼저 해줘야 합니다.
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:<포트넘버>/<DB명>?useSSL=false&serverTimezone=Asia/Seoul&characterEncoding=UTF-8
username: <사용자이름>
password: <비밀번호>
jpa:
open-in-view: true
hibernate:
ddl-auto: create
naming:
physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
use-new-id-generator-mappings: false
show-sql: true
properties:
hibernate.format_sql: true
dialect: org.hibernate.dialect.MySQL8InnoDBDialect
logging:
level:
org.hibernate.SQL: debug
DB설정 뿐 만이 아닌 jpa에 관련된 설정도 해줘야 합니다!
'Spring' 카테고리의 다른 글
[회고록] Docker 그리고 Docker-Compose를 이용한 배포 (0) | 2025.01.18 |
---|---|
(5주차)(Mac) Spring 댓글 구현 (1) | 2023.12.04 |
(Mac) (4주차) post CRUD 코드 수정 (1) | 2023.11.27 |
(Mac) JPA를 활용한 게시판 CRUD 구현 (1) | 2023.11.19 |
(Mac) Spring 스터디 (1) - spring과 mysql 연동하기 (0) | 2023.11.06 |