Skip to main content

02D. ์—”ํ‹ฐํ‹ฐ

About 2 minJavaSpringAWScrashcoursejavajdkjdk8streamspringspringframeworkspringbootawsaws-ec2

02D. ์—”ํ‹ฐํ‹ฐ ๊ด€๋ จ


2-04. ์—”ํ‹ฐํ‹ฐ

์ ํ”„ ํˆฌ ์Šคํ”„๋ง๋ถ€ํŠธ - WikiDocs

pahkey/sbb3 - 2-04open in new window

์ด์ œ SBB๊ฐ€ ์‚ฌ์šฉํ•  ์—”ํ‹ฐํ‹ฐ(Entity)์„ ๋งŒ๋“ค์–ด ๋ณด์ž. ์—”ํ‹ฐํ‹ฐ๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ํ…Œ์ด๋ธ”๊ณผ ๋งคํ•‘๋˜๋Š” ์ž๋ฐ” ํด๋ž˜์Šค๋ฅผ ๋งํ•œ๋‹ค. SBB๋Š” ์งˆ๋ฌธ๊ณผ ๋‹ต๋ณ€์„ ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒŒ์‹œํŒ ์„œ๋น„์Šค์ด๋‹ค. ๋”ฐ๋ผ์„œ SBB์—๋Š” ์งˆ๋ฌธ๊ณผ ๋‹ต๋ณ€์— ํ•ด๋‹นํ•˜๋Š” ์—”ํ‹ฐํ‹ฐ๊ฐ€ ์žˆ์–ด์•ผ ํ•œ๋‹ค.

์—”ํ‹ฐํ‹ฐ๋Š” ๋ชจ๋ธ ๋˜๋Š” ๋„๋ฉ”์ธ ๋ชจ๋ธ์ด๋ผ๊ณ  ๋ถ€๋ฅด๊ธฐ๋„ ํ•œ๋‹ค. ์ด ์ฑ…์—์„œ๋Š” ์ด๊ฒƒ๋“ค์„ ๊ตฌ๋ถ„ํ•˜์ง€ ์•Š๊ณ  ํ…Œ์ด๋ธ”๊ณผ ๋งคํ•‘๋˜๋Š” ํด๋ž˜์Šค๋ฅผ ์—”ํ‹ฐํ‹ฐ๋ผ ์ง€์นญํ•˜๊ฒ ๋‹ค.


์—”ํ‹ฐํ‹ฐ์˜ ์†์„ฑ ๊ตฌ์ƒํ•˜๊ธฐ

๊ทธ๋ ‡๋‹ค๋ฉด ์งˆ๋ฌธ๊ณผ ๋‹ต๋ณ€ ์—”ํ‹ฐํ‹ฐ์—๋Š” ์–ด๋–ค ์†์„ฑ๋“ค์ด ํ•„์š”ํ•œ์ง€ ๋จผ์ € ์ƒ๊ฐํ•ด ๋ณด์ž.

์งˆ๋ฌธ(Question) ์—”ํ‹ฐํ‹ฐ์—๋Š” ์ตœ์†Œํ•œ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์†์„ฑ์ด ํ•„์š”ํ•˜๋‹ค.

์†์„ฑ๋ช…์„ค๋ช…
id์งˆ๋ฌธ์˜ ๊ณ ์œ  ๋ฒˆํ˜ธ
subject์งˆ๋ฌธ์˜ ์ œ๋ชฉ
content์งˆ๋ฌธ์˜ ๋‚ด์šฉ
create_date์งˆ๋ฌธ์„ ์ž‘์„ฑํ•œ ์ผ์‹œ

๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๋‹ต๋ณ€(Answer) ์—”ํ‹ฐํ‹ฐ์—๋Š” ์ตœ์†Œํ•œ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์†์„ฑ์ด ํ•„์š”ํ•˜๋‹ค.

์†์„ฑ๋ช…์„ค๋ช…
id๋‹ต๋ณ€์˜ ๊ณ ์œ  ๋ฒˆํ˜ธ
question์งˆ๋ฌธ (์–ด๋–ค ์งˆ๋ฌธ์˜ ๋‹ต๋ณ€์ธ์ง€ ์•Œ์•„์•ผํ•˜๋ฏ€๋กœ ์งˆ๋ฌธ ์†์„ฑ์ด ํ•„์š”ํ•˜๋‹ค)
content๋‹ต๋ณ€์˜ ๋‚ด์šฉ
create_date๋‹ต๋ณ€์„ ์ž‘์„ฑํ•œ ์ผ์‹œ

์ด๋ ‡๊ฒŒ ์ƒ๊ฐํ•œ ์†์„ฑ์„ ๋ฐ”ํƒ•์œผ๋กœ ์งˆ๋ฌธ(Question)๊ณผ ๋‹ต๋ณ€(Answer)์— ํ•ด๋‹น๋˜๋Š” ์—”ํ‹ฐํ‹ฐ๋ฅผ ์ž‘์„ฑํ•ด ๋ณด์ž.


์งˆ๋ฌธ ์—”ํ‹ฐํ‹ฐ ์ž‘์„ฑํ•˜๊ธฐ

๋‹ค์Œ๊ณผ ๊ฐ™์ด Question ํด๋ž˜์Šค๋ฅผ ์ž‘์„ฑํ•˜์ž.

ํŒŒ์ผ๋ช…: /sbb/src/main/java/com/mysite/sbb/Question.java

package com.mysite.sbb;

import java.time.LocalDateTime;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.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;
}

์Šคํ”„๋ง๋ถ€ํŠธ 2.x ๋ฒ„์ „์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ

์ด ์ฑ…์€ ์Šคํ”„๋ง๋ถ€ํŠธ 3.x ๋ฒ„์ „์„ ๊ธฐ์ค€์œผ๋กœ ์„ค๋ช…ํ•œ๋‹ค. ๋งŒ์•ฝ ์˜ˆ์ „ ๋ฒ„์ „์ธ ์Šคํ”„๋ง๋ถ€ํŠธ 2.x ๋ฒ„์ „์„ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด import javax.* ์ฒ˜๋Ÿผ jakarta ํŒจํ‚ค์ง€๋กœ ์‹œ์ž‘ํ•˜๋Š” ๋ถ€๋ถ„์„ import javax.* ์ฒ˜๋Ÿผ jakarta๋ฅผ javax๋กœ ๋ฐ”๊พธ์–ด์•ผ ํ•œ๋‹ค.

์—”ํ‹ฐํ‹ฐ๋กœ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด Question ํด๋ž˜์Šค์— @Entity ์• ๋„ˆํ…Œ์ด์…˜์„ ์ ์šฉํ–ˆ๋‹ค. @Entity ์• ๋„ˆํ…Œ์ด์…˜์„ ์ ์šฉํ•ด์•ผ JPA๊ฐ€ ์—”ํ‹ฐํ‹ฐ๋กœ ์ธ์‹ํ•œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  Getter, Setter ๋ฉ”์„œ๋“œ๋ฅผ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•ด ๋กฌ๋ณต์˜ @Getter, @Setter ์• ๋„ˆํ…Œ์ด์…˜์„ ์ ์šฉํ–ˆ๋‹ค.

์ปจํŠธ๋กค๋Ÿฌ์— @Controller ์• ๋„ˆํ…Œ์ด์…˜์„ ์ ์šฉํ•˜๋Š” ๊ฒƒ๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์—”ํ‹ฐํ‹ฐ๋Š” @Entity ์• ๋„ˆํ…Œ์ด์…˜์„ ์ ์šฉํ•ด์•ผ ํ•œ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ์—”ํ‹ฐํ‹ฐ์˜ ์†์„ฑ์œผ๋กœ ๊ณ ์œ ๋ฒˆํ˜ธ(id), ์ œ๋ชฉ(subject), ๋‚ด์šฉ(content), ์ž‘์„ฑ์ผ์‹œ(createDate)๋ฅผ ์ถ”๊ฐ€ํ–ˆ๋‹ค. ๊ฐ ์†์„ฑ์—๋Š” Id, GeneratedValue, Column๊ณผ ๊ฐ™์€ ์• ๋„ˆํ…Œ์ด์…˜์ด ์ ์šฉ๋˜์–ด ์žˆ๋Š”๋ฐ ๊ทธ๊ฒƒ๋“ค์— ๋Œ€ํ•ด์„œ ํ•˜๋‚˜์”ฉ ์•Œ์•„๋ณด์ž.


@Id

๊ณ ์œ  ๋ฒˆํ˜ธ id ์†์„ฑ์— ์ ์šฉํ•œ @Id ์• ๋„ˆํ…Œ์ด์…˜์€ id ์†์„ฑ์„ ๊ธฐ๋ณธ ํ‚ค๋กœ ์ง€์ •ํ•œ๋‹ค. ๊ธฐ๋ณธ ํ‚ค๋กœ ์ง€์ •ํ•˜๋ฉด ์ด์ œ id ์†์„ฑ์˜ ๊ฐ’์€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ €์žฅํ•  ๋•Œ ๋™์ผํ•œ ๊ฐ’์œผ๋กœ ์ €์žฅํ•  ์ˆ˜ ์—†๋‹ค. ๊ณ ์œ  ๋ฒˆํ˜ธ๋ฅผ ๊ธฐ๋ณธ ํ‚ค๋กœ ํ•œ ์ด์œ ๋Š” ๊ณ ์œ  ๋ฒˆํ˜ธ๋Š” ์—”ํ‹ฐํ‹ฐ์—์„œ ๊ฐ ๋ฐ์ดํ„ฐ๋ฅผ ๊ตฌ๋ถ„ํ•˜๋Š” ์œ ํšจํ•œ ๊ฐ’์œผ๋กœ ์ค‘๋ณต๋˜๋ฉด ์•ˆ ๋˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ๋Š” id์™€ ๊ฐ™์€ ํŠน์ง•์„ ๊ฐ€์ง„ ์†์„ฑ์„ ๊ธฐ๋ณธ ํ‚ค(primary key)๋ผ๊ณ  ํ•œ๋‹ค.


@GeneratedValue

@GeneratedValue ์• ๋„ˆํ…Œ์ด์…˜์„ ์ ์šฉํ•˜๋ฉด ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•  ๋•Œ ํ•ด๋‹น ์†์„ฑ์— ๊ฐ’์„ ๋”ฐ๋กœ ์„ธํŒ…ํ•˜์ง€ ์•Š์•„๋„ 1์”ฉ ์ž๋™์œผ๋กœ ์ฆ๊ฐ€ํ•˜์—ฌ ์ €์žฅ๋œ๋‹ค. strategy๋Š” ๊ณ ์œ ๋ฒˆํ˜ธ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ์˜ต์…˜์œผ๋กœ GenerationType.IDENTITY๋Š” ํ•ด๋‹น ์ปฌ๋Ÿผ๋งŒ์˜ ๋…๋ฆฝ์ ์ธ ์‹œํ€€์Šค๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ๋ฒˆํ˜ธ๋ฅผ ์ฆ๊ฐ€์‹œํ‚ฌ ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.

strategy ์˜ต์…˜์„ ์ƒ๋žตํ•  ๊ฒฝ์šฐ์— @GeneratedValue ์• ๋„ˆํ…Œ์ด์…˜์ด ์ง€์ •๋œ ์ปฌ๋Ÿผ๋“ค์ด ๋ชจ๋‘ ๋™์ผํ•œ ์‹œํ€€์Šค๋กœ ๋ฒˆํ˜ธ๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ผ์ •ํ•œ ์ˆœ์„œ์˜ ๊ณ ์œ ๋ฒˆํ˜ธ๋ฅผ ๊ฐ€์งˆ์ˆ˜ ์—†๊ฒŒ ๋œ๋‹ค. ์ด๋Ÿฌํ•œ ์ด์œ ๋กœ ๋ณดํ†ต GenerationType.IDENTITY๋ฅผ ๋งŽ์ด ์‚ฌ์šฉํ•œ๋‹ค.


@Column

์—”ํ‹ฐํ‹ฐ์˜ ์†์„ฑ์€ ํ…Œ์ด๋ธ”์˜ ์ปฌ๋Ÿผ๋ช…๊ณผ ์ผ์น˜ํ•˜๋Š”๋ฐ ์ปฌ๋Ÿผ์˜ ์„ธ๋ถ€ ์„ค์ •์„ ์œ„ํ•ด @Column ์• ๋„ˆํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•œ๋‹ค. length๋Š” ์ปฌ๋Ÿผ์˜ ๊ธธ์ด๋ฅผ ์„ค์ •ํ• ๋•Œ ์‚ฌ์šฉํ•˜๊ณ  columnDefinition์€ ์ปฌ๋Ÿผ์˜ ์†์„ฑ์„ ์ •์˜ํ•  ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค. columnDefinition = "TEXT"์€ "๋‚ด์šฉ"์ฒ˜๋Ÿผ ๊ธ€์ž ์ˆ˜๋ฅผ ์ œํ•œํ•  ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ์— ์‚ฌ์šฉํ•œ๋‹ค.

์—”ํ‹ฐํ‹ฐ์˜ ์†์„ฑ์€ @Column ์• ๋„ˆํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋”๋ผ๋„ ํ…Œ์ด๋ธ” ์ปฌ๋Ÿผ์œผ๋กœ ์ธ์‹ํ•œ๋‹ค. ํ…Œ์ด๋ธ” ์ปฌ๋Ÿผ์œผ๋กœ ์ธ์‹ํ•˜๊ณ  ์‹ถ์ง€ ์•Š์€ ๊ฒฝ์šฐ์—๋งŒ @Transient ์• ๋„ˆํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•œ๋‹ค.

ํ…Œ์ด๋ธ”์˜ ์ปฌ๋Ÿผ๋ช…

์œ„์˜ Question ์—”ํ‹ฐํ‹ฐ์—์„œ ์ž‘์„ฑ์ผ์‹œ์— ํ•ด๋‹นํ•˜๋Š” createDate ์†์„ฑ์˜ ์‹ค์ œ ํ…Œ์ด๋ธ”์˜ ์ปฌ๋Ÿผ๋ช…์€ create_date๊ฐ€ ๋œ๋‹ค. ์ฆ‰ createDate์ฒ˜๋Ÿผ ๋Œ€์†Œ๋ฌธ์ž ํ˜•ํƒœ์˜ ์นด๋ฉœ์ผ€์ด์Šค(Camel Case) ์ด๋ฆ„์€ create_date ์ฒ˜๋Ÿผ ๋ชจ๋‘ ์†Œ๋ฌธ์ž๋กœ ๋ณ€๊ฒฝ๋˜๊ณ  ์–ธ๋”๋ฐ”(_)๋กœ ๋‹จ์–ด๊ฐ€ ๊ตฌ๋ถ„๋˜์–ด ์‹ค์ œ ํ…Œ์ด๋ธ” ์ปฌ๋Ÿผ๋ช…์ด ๋œ๋‹ค.

์—”ํ‹ฐํ‹ฐ์™€ Setter

์ผ๋ฐ˜์ ์œผ๋กœ ์—”ํ‹ฐํ‹ฐ์—๋Š” Setter ๋ฉ”์„œ๋“œ๋ฅผ ๊ตฌํ˜„ํ•˜์ง€ ์•Š๊ณ  ์‚ฌ์šฉํ•˜๊ธฐ๋ฅผ ๊ถŒํ•œ๋‹ค. ์™œ๋ƒํ•˜๋ฉด ์—”ํ‹ฐํ‹ฐ๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์™€ ๋ฐ”๋กœ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ž์œ ๋กญ๊ฒŒ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋Š” Setter ๋ฉ”์„œ๋“œ๋ฅผ ํ—ˆ์šฉํ•˜๋Š” ๊ฒƒ์ด ์•ˆ์ „ํ•˜์ง€ ์•Š๋‹ค๊ณ  ํŒ๋‹จํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

๊ทธ๋ ‡๋‹ค๋ฉด Setter ๋ฉ”์„œ๋“œ ์—†์ด ์–ด๋–ป๊ฒŒ ์—”ํ‹ฐํ‹ฐ์— ๊ฐ’์„ ์ €์žฅํ•  ์ˆ˜ ์žˆ์„๊นŒ?

์—”ํ‹ฐํ‹ฐ๋ฅผ ์ƒ์„ฑํ•  ๊ฒฝ์šฐ์—๋Š” ๋กฌ๋ณต์˜ @Builder ์–ด๋…ธํ…Œ์ด์…˜์„ ํ†ตํ•œ ๋นŒ๋“œํŒจํ„ด์„ ์‚ฌ์šฉํ•˜๊ณ , ๋ฐ์ดํ„ฐ๋ฅผ ๋ณ€๊ฒฝํ•ด์•ผ ํ•  ๊ฒฝ์šฐ์—๋Š” ๊ทธ์— ํ•ด๋‹น๋˜๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ์—”ํ‹ฐํ‹ฐ์— ์ถ”๊ฐ€ํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณ€๊ฒฝํ•˜๋ฉด ๋œ๋‹ค.

๋‹ค๋งŒ, ์ด ์ฑ…์€ ๋ณต์žก๋„๋ฅผ ๋‚ฎ์ถ”๊ณ  ์›ํ™œํ•œ ์„ค๋ช…์„ ์œ„ํ•ด ์—”ํ‹ฐํ‹ฐ์— Setter ๋ฉ”์„œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ์ง„ํ–‰ํ•˜๋ ค ํ•œ๋‹ค.


๋‹ต๋ณ€ ์—”ํ‹ฐํ‹ฐ ์ƒ์„ฑํ•˜๊ธฐ

์ด์–ด์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋‹ต๋ณ€ ์—”ํ‹ฐํ‹ฐ๋„ ์ž‘์„ฑํ•˜์ž.

ํŒŒ์ผ๋ช…: /sbb/src/main/java/com/mysite/sbb/Answer.java

package com.mysite.sbb;

import java.time.LocalDateTime;

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

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;

    private Question question;
}

Id, content, createDate ์†์„ฑ์€ ์งˆ๋ฌธ ์—”ํ‹ฐํ‹ฐ์™€ ๋™์ผํ•˜๋ฏ€๋กœ ์„ค๋ช…์€ ์ƒ๋žตํ•œ๋‹ค.

question ์†์„ฑ์€ ๋‹ต๋ณ€ ์—”ํ‹ฐํ‹ฐ์—์„œ ์งˆ๋ฌธ ์—”ํ‹ฐํ‹ฐ๋ฅผ ์ฐธ์กฐํ•˜๊ธฐ ์œ„ํ•ด ์ถ”๊ฐ€ํ–ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๋‹ต๋ณ€ ๊ฐ์ฒด(์˜ˆ:answer)๋ฅผ ํ†ตํ•ด ์งˆ๋ฌธ ๊ฐ์ฒด์˜ ์ œ๋ชฉ์„ ์•Œ๊ณ  ์‹ถ๋‹ค๋ฉด answer.getQuestion().getSubject()์ฒ˜๋Ÿผ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด๋ ‡๊ฒŒ ์†์„ฑ๋งŒ ์ถ”๊ฐ€ํ•˜๋ฉด ์•ˆ๋˜๊ณ  ์งˆ๋ฌธ ์—”ํ‹ฐํ‹ฐ์™€ ์—ฐ๊ฒฐ๋œ ์†์„ฑ์ด๋ผ๋Š” ๊ฒƒ์„ ๋ช…์‹œ์ ์œผ๋กœ ํ‘œ์‹œํ•ด์•ผ ํ•œ๋‹ค.

์ฆ‰, ๋‹ค์Œ๊ณผ ๊ฐ™์ด question ์†์„ฑ์— @ManyToOne ์• ๋„ˆํ…Œ์ด์…˜์„ ์ถ”๊ฐ€ํ•ด์•ผ ํ•œ๋‹ค.

// (... ์ƒ๋žต ...)
import jakarta.persistence.ManyToOne;
// (... ์ƒ๋žต ...)

@Getter
@Setter
@Entity
public class Answer {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

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

    @CreatedDate
    private LocalDateTime createDate;

    @ManyToOne
    private Question question;
}

ย 
















ย 


๋‹ต๋ณ€์€ ํ•˜๋‚˜์˜ ์งˆ๋ฌธ์— ์—ฌ๋Ÿฌ๊ฐœ๊ฐ€ ๋‹ฌ๋ฆด ์ˆ˜ ์žˆ๋Š” ๊ตฌ์กฐ์ด๋‹ค. ๋”ฐ๋ผ์„œ ๋‹ต๋ณ€์€ Many(๋งŽ์€ ๊ฒƒ)๊ฐ€ ๋˜๊ณ  ์งˆ๋ฌธ์€ One(ํ•˜๋‚˜)์ด ๋œ๋‹ค. ๋”ฐ๋ผ์„œ @ManyToOne์€ N:1 ๊ด€๊ณ„๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋ ‡๊ฒŒ @ManyToOne ์• ๋„ˆํ…Œ์ด์…˜์„ ์„ค์ •ํ•˜๋ฉด Answer ์—”ํ‹ฐํ‹ฐ์˜ question ์†์„ฑ๊ณผ Question ์—”ํ‹ฐํ‹ฐ๊ฐ€ ์„œ๋กœ ์—ฐ๊ฒฐ๋œ๋‹ค. (์‹ค์ œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ๋Š” ForeignKey ๊ด€๊ณ„๊ฐ€ ์ƒ์„ฑ๋œ๋‹ค.)

@ManyToOne์€ ๋ถ€๋ชจ ์ž์‹ ๊ด€๊ณ„๋ฅผ ๊ฐ–๋Š” ๊ตฌ์กฐ์—์„œ ์‚ฌ์šฉํ•œ๋‹ค. ์—ฌ๊ธฐ์„œ ๋ถ€๋ชจ๋Š” Question, ์ž์‹์€ Answer๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ๋‹ค.

๊ทธ๋ ‡๋‹ค๋ฉด ๋ฐ˜๋Œ€๋ฐฉํ–ฅ, ์ฆ‰ Question ์—”ํ‹ฐํ‹ฐ์—์„œ Answer ์—”ํ‹ฐํ‹ฐ๋ฅผ ์ฐธ์กฐํ• ์ˆ˜๋Š” ์—†์„๊นŒ?

๊ฐ€๋Šฅํ•˜๋‹ค. ๋‹ต๋ณ€๊ณผ ์งˆ๋ฌธ์ด N:1์˜ ๊ด€๊ณ„๋ผ๋ฉด ์งˆ๋ฌธ๊ณผ ๋‹ต๋ณ€์€ 1:N์˜ ๊ด€๊ณ„๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋Ÿฐ๊ฒฝ์šฐ์—๋Š” @ManyToOne์ด ์•„๋‹Œ @OneToMany์• ๋„ˆํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•œ๋‹ค. Question ํ•˜๋‚˜์— Answer๋Š” ์—ฌ๋Ÿฌ๊ฐœ์ด๋ฏ€๋กœ Question ์—”ํ‹ฐํ‹ฐ์— ์ถ”๊ฐ€ํ•  ๋‹ต๋ณ€์˜ ์†์„ฑ์€ List ํ˜•ํƒœ๋กœ ๊ตฌ์„ฑํ•ด์•ผ ํ•œ๋‹ค.

์ด๋ฅผ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด Question ์—”ํ‹ฐํ‹ฐ๋ฅผ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ˆ˜์ •ํ•˜์ž.

ํŒŒ์ผ๋ช…: /sbb/src/main/java/com/mysite/sbb/Question.java

package com.mysite.sbb;

import java.time.LocalDateTime;
import java.util.List;

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

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;

    @OneToMany(mappedBy = "question", cascade = CascadeType.REMOVE)
    private List<Answer> answerList;
}



ย 

ย 





ย 




















ย 
ย 

Answer ์—”ํ‹ฐํ‹ฐ ๊ฐ์ฒด๋กœ ๊ตฌ์„ฑ๋œ answerList๋ฅผ ์†์„ฑ์œผ๋กœ ์ถ”๊ฐ€ํ•˜๊ณ  @OneToMany ์• ๋„ˆํ…Œ์ด์…˜์„ ์„ค์ •ํ–ˆ๋‹ค. ์ด์ œ ์งˆ๋ฌธ ๊ฐ์ฒด(์˜ˆ:question)์—์„œ ๋‹ต๋ณ€์„ ์ฐธ์กฐํ•˜๋ ค๋ฉด question.getAnswerList()๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ๋œ๋‹ค. @OneToMany ์• ๋„ˆํ…Œ์ด์…˜์— ์‚ฌ์šฉ๋œ mappedBy๋Š” ์ฐธ์กฐ ์—”ํ‹ฐํ‹ฐ์˜ ์†์„ฑ๋ช…์„ ์˜๋ฏธํ•œ๋‹ค. ์ฆ‰, Answer ์—”ํ‹ฐํ‹ฐ์—์„œ Question ์—”ํ‹ฐํ‹ฐ๋ฅผ ์ฐธ์กฐํ•œ ์†์„ฑ๋ช… question์„ mappedBy์— ์ „๋‹ฌํ•ด์•ผ ํ•œ๋‹ค.

CascadeType.REMOVE

์งˆ๋ฌธ ํ•˜๋‚˜์—๋Š” ์—ฌ๋Ÿฌ๊ฐœ์˜ ๋‹ต๋ณ€์ด ์ž‘์„ฑ๋  ์ˆ˜ ์žˆ๋‹ค. ์ด๋•Œ ์งˆ๋ฌธ์„ ์‚ญ์ œํ•˜๋ฉด ๊ทธ์— ๋‹ฌ๋ฆฐ ๋‹ต๋ณ€๋“ค๋„ ๋ชจ๋‘ ํ•จ๊ป˜ ์‚ญ์ œํ•˜๊ธฐ ์œ„ํ•ด์„œ @OneToMany์˜ ์†์„ฑ์œผ๋กœ cascade = CascadeType.REMOVE๋ฅผ ์‚ฌ์šฉํ–ˆ๋‹ค.


ํ…Œ์ด๋ธ” ํ™•์ธํ•˜๊ธฐ

Question๊ณผ Answer ์—”ํ‹ฐํ‹ฐ๋ฅผ ์ž‘์„ฑํ•œํ›„ H2 ์ฝ˜์†”์— ์ ‘์†ํ•ด ๋ณด์ž.

๊ณผ  ํ…Œ์ด๋ธ”์ด ์ž๋™์œผ๋กœ ์ƒ์„ฑ๋œ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.
Question๊ณผ Answer ํ…Œ์ด๋ธ”์ด ์ž๋™์œผ๋กœ ์ƒ์„ฑ๋œ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

๋งŒ์•ฝ ํ…Œ์ด๋ธ”์ด ์ƒ์„ฑ๋˜์ง€ ์•Š์•˜๋‹ค๋ฉด ๋กœ์ปฌ ์„œ๋ฒ„๋ฅผ ์žฌ์‹œ์ž‘ํ•ด ๋ณด์ž.


์ด์ฐฌํฌ (MarkiiimarK)
Never Stop Learning.