๐Ÿ“Œ JPA ์—ฐ๊ด€๊ด€๊ณ„ ๋งคํ•‘ ์‹ค์Šต ์ •๋ฆฌ

My Pale Blue Dotยท2025๋…„ 5์›” 8์ผ
0

SPRING BOOT

๋ชฉ๋ก ๋ณด๊ธฐ
7/40
post-thumbnail

๐Ÿ“… ๋‚ ์งœ

2025๋…„ 5์›” 7์ผ

๐Ÿ“ ํ•™์Šต ๋‚ด์šฉ

1๏ธโƒฃ ์—ฐ๊ด€๊ด€๊ณ„ ๊ธฐ๋ณธ ๊ฐœ๋…

โœ… ๊ฐ์ฒด vs ํ…Œ์ด๋ธ” ๊ฐ„ ์ฐจ์ด

  • ๊ฐ์ฒด ์ง€ํ–ฅ ์„ธ๊ณ„: ๊ฐ์ฒด ์ฐธ์กฐ (์˜ˆ: Member โ†’ Team)
  • ๊ด€๊ณ„ํ˜• DB ์„ธ๊ณ„: ์™ธ๋ž˜ ํ‚ค ์‚ฌ์šฉ (์˜ˆ: member.team_id โ†’ team.id)
  • JPA๋Š” ๊ฐ์ฒด์˜ ์ฐธ์กฐ์™€ ์™ธ๋ž˜ ํ‚ค๋ฅผ ์—ฐ๊ฒฐํ•ด์ฃผ๋Š” ORM ๋„๊ตฌ

2๏ธโƒฃ ์—ฐ๊ด€๊ด€๊ณ„ ์ข…๋ฅ˜

๊ด€๊ณ„ ์ข…๋ฅ˜์„ค๋ช…
ManyToOne๊ฐ€์žฅ ํ”ํ•œ ๊ด€๊ณ„. ๋‹ค์ˆ˜์˜ ์—”ํ‹ฐํ‹ฐ๊ฐ€ ํ•˜๋‚˜๋ฅผ ์ฐธ์กฐ
OneToMany์‹ค๋ฌด์—์„œ ์ž˜ ์‚ฌ์šฉ๋˜์ง€ ์•Š์Œ. ์ถ”๊ฐ€์  ์„ค์ • ํ•„์š”
OneToOne๊ฑฐ์˜ ์‚ฌ์šฉ๋˜์ง€ ์•Š์Œ. ํŠน์ • ์ƒํ™ฉ์—์„œ๋งŒ ํ™œ์šฉ
ManyToMany๋น„์ถ”์ฒœ. ๋ณ„๋„ ์—”ํ‹ฐํ‹ฐ๋กœ ํ’€์–ด๋‚ด๋Š” ๊ฒƒ์ด ์ผ๋ฐ˜์ 

3๏ธโƒฃ ๋‹จ๋ฐฉํ–ฅ vs ์–‘๋ฐฉํ–ฅ

  • ๋‹จ๋ฐฉํ–ฅ: ํ•œ ์ชฝ๋งŒ ์ฐธ์กฐ โ†’ ์„ค์ • ๊ฐ„๋‹จํ•˜์ง€๋งŒ, ์กฐํšŒ ์ œ์•ฝ
  • ์–‘๋ฐฉํ–ฅ: ์–‘์ชฝ ๋ชจ๋‘ ์ฐธ์กฐ ๊ฐ€๋Šฅ
    โ†’ mappedBy๋ฅผ ์ด์šฉํ•ด ์—ฐ๊ด€๊ด€๊ณ„์˜ ์ฃผ์ธ(Owner) ์„ ์„ค์ •
    โ†’ ์‹ค์ œ ์™ธ๋ž˜ ํ‚ค๋Š” ์ฃผ์ธ ์—”ํ‹ฐํ‹ฐ์—์„œ ๊ด€๋ฆฌ๋จ

โ— ์™œ ์—ฐ๊ด€๊ด€๊ณ„์˜ ์ฃผ์ธ์„ ์ •ํ•ด์•ผ ํ• ๊นŒ?

์–‘๋ฐฉํ–ฅ ๊ด€๊ณ„์—์„œ๋Š” ๋‘ ๊ฐ์ฒด๊ฐ€ ์„œ๋กœ๋ฅผ ์ฐธ์กฐํ•˜์ง€๋งŒ,

DB์— ์™ธ๋ž˜ ํ‚ค๋Š” ํ•˜๋‚˜๋งŒ ์กด์žฌํ•˜๋ฏ€๋กœ JPA์—๊ฒŒ ์–ด๋–ค ์ชฝ์ด ๊ด€๋ฆฌ ์ฃผ์ฒด์ธ์ง€ ์•Œ๋ ค์ค˜์•ผ

SQL ์ƒ์„ฑ ๋ฐ ๋™๊ธฐํ™”์— ํ˜ผ๋ž€์ด ์—†์Šต๋‹ˆ๋‹ค.


4๏ธโƒฃ ์‹ค๋ฌด ํŒ: @OneToMany ์‚ฌ์šฉ ์‹œ ์ฃผ์˜

  • ์™ธ๋ž˜ ํ‚ค๋ฅผ ์ƒ๋Œ€ ํ…Œ์ด๋ธ”์—์„œ ๊ด€๋ฆฌํ•˜๋ฏ€๋กœ insert/update ์‹œ ๋ณต์žกํ•ด์งˆ ์ˆ˜ ์žˆ์Œ
  • mappedBy ์„ค์ •๊ณผ cascade, orphanRemoval ๋“ฑ์˜ ์˜ต์…˜ ์กฐํ•ฉ์— ์ฃผ์˜ ํ•„์š”
  • ๋‹จ๋ฐฉํ–ฅ๋ณด๋‹ค ์–‘๋ฐฉํ–ฅ + ๋ช…ํ™•ํ•œ ์ฃผ์ธ ์„ค์ •์ด ์‹ค๋ฌด์—์„œ ๋” ์•ˆ์ •์ 

๐Ÿงฉ ์‹ค์Šต ์ฝ”๋“œ

โœ… Lend ์—”ํ‹ฐํ‹ฐ (์–‘๋ฐฉํ–ฅ ๋‹ค๋Œ€์ผ ์—ฐ๊ด€๊ด€๊ณ„ ์„ค์ •)

package com.example.demo.domain.entity;

import jakarta.persistence.*;
import lombok.*;

@Entity
@Table(name="lend")
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Lend {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToOne
    @JoinColumn(name="bookcode", foreignKey = @ForeignKey(name="FK_LEND_BOOK",
            foreignKeyDefinition = "FOREIGN KEY(bookcode) REFERENCES book(bookcode) ON DELETE CASCADE ON UPDATE CASCADE"))
    private Book book;

    @ManyToOne
    @JoinColumn(name="username", foreignKey = @ForeignKey(name="FK_LEND_USER",
            foreignKeyDefinition = "FOREIGN KEY(username) REFERENCES user(username) ON DELETE CASCADE ON UPDATE CASCADE"))
    private User user;
}

โœ… LendRepository (Spring Data JPA)

package com.example.demo.domain.repository;

import com.example.demo.domain.entity.Lend;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface LendRepository extends JpaRepository<Lend, Long> {

}

โœ… LendRepositoryTest (CRUD ํ…Œ์ŠคํŠธ)

package com.example.demo.domain.repository;

import com.example.demo.domain.entity.Book;
import com.example.demo.domain.entity.Lend;
import com.example.demo.domain.entity.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class LendRepositoryTest {

    @Autowired
    private LendRepository lendRepository;

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private BookRepository bookRepository;

    @Test
    public void t1() throws Exception {
        Book book = bookRepository.findById(3333L).get();
        User user = userRepository.findById("user2").get();

        Lend lend = new Lend();
        lend.setBook(book);
        lend.setUser(user);
        lendRepository.save(lend); // INSERT
    }

    @Test
    public void t2() throws Exception {
        Lend lend = lendRepository.findById(1L).get();
        Book book = bookRepository.findById(4444L).get();
        lend.setBook(book);
        lendRepository.save(lend); // UPDATE
    }

    @Test
    public void t3() throws Exception {
        lendRepository.deleteById(1L); // DELETE
    }
}

๐Ÿ”ฅ ์ •๋ฆฌ

  • @ManyToOne, @JoinColumn์„ ํ†ตํ•ด ์™ธ๋ž˜ ํ‚ค ๋ช…์‹œ ๋ฐ ์ œ์•ฝ ์กฐ๊ฑด ์„ค์ •
  • ์—ฐ๊ด€๊ด€๊ณ„์˜ ์ฃผ์ธ์€ @JoinColumn์ด ์„ ์–ธ๋œ ์ชฝ โ†’ DB์™€์˜ ์‹ฑํฌ ์ฃผ์ฒด
  • Repository๋Š” JpaRepository๋กœ CRUD ์ž๋™ ๊ตฌํ˜„
  • ํ…Œ์ŠคํŠธ ํด๋ž˜์Šค์—์„œ ์‚ฝ์ž…, ์ˆ˜์ •, ์‚ญ์ œ์˜ ์ „์ฒด ํ๋ฆ„์„ ํ™•์ธ
  • ์‹ค๋ฌด์—์„œ๋Š” ManyToOne ์œ„์ฃผ๋กœ ์‚ฌ์šฉ, OneToMany๋Š” ๋ณด์™„์  ์‚ฌ์šฉ์ด ์ผ๋ฐ˜์ 

๐Ÿ”— ์ฐธ๊ณ  ์ž๋ฃŒ


profile
Here, My Pale Blue.๐ŸŒ

0๊ฐœ์˜ ๋Œ“๊ธ€