🌈 [Section3] 7. [ Spring MVC ] Spring Data JPA 1

ν˜„μ£ΌΒ·2022λ…„ 11μ›” 2일
0

bootcamp

λͺ©λ‘ 보기
47/71

πŸ“• 였늘 배운 λ‚΄μš©!

  • JPA (Java Persistence API)
  • μ—”ν‹°ν‹° 맀핑

✏️ JPA (Java Persistence API)

  • Java μ§„μ˜μ—μ„œ μ‚¬μš©ν•˜λŠ” ORM(Object-Relational Mapping) 기술의 ν‘œμ€€ 사양(Specification)

  • Jakarta Persistence 라고도 뢈림

  • ν…Œμ΄λΈ”κ³Ό λ§€ν•‘λ˜λŠ” μ—”ν‹°ν‹° 객체 정보λ₯Ό μ˜μ†μ„± μ»¨ν…μŠ€νŠΈ(Persistence Context)에 λ³΄κ΄€ν•˜μ—¬ μ• ν”Œλ¦¬μΌ€μ΄μ…˜ λ‚΄μ—μ„œ 였래 지속 λ˜λ„λ‘ 함
    β €β €
    ➜ μΈν„°νŽ˜μ΄μŠ€λ‘œ JPAλΌλŠ” ν‘œμ€€ 사양이 μ •μ˜λ˜μ–΄ 있기 λ•Œλ¬Έμ—, 이 사양을 κ΅¬ν˜„ν•œ κ΅¬ν˜„μ²΄λŠ” λ”°λ‘œ 있음
    ( μš°λ¦¬λŠ” 이 사양을 κ΅¬ν˜„ν•œ κ΅¬ν˜„μ²΄μ— λŒ€ν•΄ ν•™μŠ΅ν•˜λŠ” 것 )

    πŸ’‘ 사양 (Specification)
    ➜ 섀계ꡬ쑰 / 기술 μ„€λͺ…μ„œ 등을 의미

βœ”οΈ JPA ν‘œμ€€ 사양을 κ΅¬ν˜„ν•œ κ΅¬ν˜„μ²΄
Hibernate ORM, EclipseLink, DataNucleus λ“±
( μš°λ¦¬λŠ” μ—¬κΈ°μ„œ Hibernate ORM 에 λŒ€ν•΄μ„œ ν•™μŠ΅ )
[μ°Έκ³ ] https://docs.jboss.org/hibernate/orm/6.0/javadocs/

❗ Spring Data JPA κΈ°μˆ μ„ ν¬ν•¨ν•œ JPA APIμ‚¬μš©μ„ μœ„ν•΄μ„œλŠ”
build.gradle 파일의 dependncies 내에 μ•„λž˜μ™€ 같은 μ˜μ‘΄μ„± 좔가해야함 ⬇️

implementation 'org.springframework.boot:spring-boot-starter-data-jpa'

( Spring Data JPAκ°€ μ•„λ‹Œ JPA API만 μ‚¬μš©ν•˜κ³  μ‹Άλ‹€λ©΄ JPA κ΄€λ ¨ 의쑴 라이브러리λ₯Ό λ³„λ„λ‘œ μΆ”κ°€ )

βœ” JPA의 4가지 Lifecycle μƒνƒœ


[μ°Έκ³ ] https://thorben-janssen.com/entity-lifecycle-model/

βœ” 데이터 μ•‘μ„ΈμŠ€ κ³„μΈ΅μ—μ„œμ˜ JPA μœ„μΉ˜

  • 데이터 μ•‘μ„ΈμŠ€ κ³„μΈ΅μ˜ 상단에 μœ„μΉ˜

    • 데이터 μ €μž₯, 쑰회 λ“±μ˜ μž‘μ—…μ€ JPAλ₯Ό 거쳐 JPA의 κ΅¬ν˜„μ²΄μΈ Hibernate ORM을 ν†΅ν•΄μ„œ 이루어짐

    • Hibernate ORM은 λ‚΄λΆ€μ μœΌλ‘œ JDBC APIλ₯Ό μ΄μš©ν•΄μ„œ λ°μ΄ν„°λ² μ΄μŠ€μ— μ ‘κ·Ό

βœ”οΈ μ˜μ†μ„± μ»¨ν…μŠ€νŠΈ(Persistence Context)

  • ν…Œμ΄λΈ”κ³Ό λ§€ν•‘λ˜λŠ” μ—”ν‹°ν‹° 객체 정보λ₯Ό 보관
    ➜ μ• ν”Œλ¦¬μΌ€μ΄μ…˜ λ‚΄μ—μ„œ 였래 지속 되게 ν•˜κ³ , 이 λ³΄κ΄€λœ μ—”ν‹°ν‹° μ •λ³΄λŠ” λ°μ΄ν„°λ² μ΄μŠ€ ν…Œμ΄λΈ”μ— 데이터λ₯Ό CRUD ν•˜λŠ”λ° μ‚¬μš©λ¨

  • 1μ°¨ μΊμ‹œ / μ“°κΈ° 지연 SQL μ €μž₯μ†Œλ‘œ ꡬ뢄
    ➜ JPA API 쀑 persist() λ©”μ„œλ“œ μ‚¬μš©ν•˜λ©΄, 1μ°¨ μΊμ‹œμ— μ—”ν‹°ν‹° 정보 μ €μž₯됨

πŸ’‘ μ“°κΈ° 지연 SQL μ €μž₯μ†Œ

  • κ°œλ…μ μœΌλ‘œλŠ” μ €μž₯μ†ŒλΌκ³  ν‘œν˜„ν–ˆμ§€λ§Œ,
    λ‚΄λΆ€μ μœΌλ‘œλŠ” Entity 기반으둜 SQL 쿼리문이 commit ν•˜λŠ” μ‹œμ μ— λ™μ μœΌλ‘œ μƒμ„±λ˜λŠ” 것을 말함

✏️ μ—”ν‹°ν‹° 맀핑 μ’…λ₯˜

  • μ—”ν‹°ν‹° - ν…Œμ΄λΈ” κ°„ 맀핑
  • κΈ°λ³Έν‚€ 맀핑
  • μ—”ν‹°ν‹°ν•„λ“œ(멀버 λ³€μˆ˜) - ν…Œμ΄λΈ” 컬럼 κ°„ 맀핑
  • μ—”ν‹°ν‹° - μ—”ν‹°ν‹°μ˜ μ—°κ΄€ 관계 맀핑

✏️ μ—”ν‹°ν‹° - ν…Œμ΄λΈ” κ°„ 맀핑

βœ”οΈ @Entity

  • μ—”ν‹°ν‹° ν΄λž˜μŠ€μ™€ ν…Œμ΄λΈ” λ§€ν•‘ν•˜λŠ” μ• λ„ˆν…Œμ΄μ…˜ (ν•„μˆ˜)
    ➜ @Id와 κΌ­ ν•¨κ»˜ ν•„μˆ˜λ‘œ μ‚¬μš©

    πŸ’‘ @Entity만 뢙이고 @Id μ•ˆλΆ™μΌ 경우
    Caused by: org.hibernate.AnnotationException: No identifier specified for entity: com.codestates.entity_mapping.single_mapping.Member 이 μ—λŸ¬ λ°œμƒ

  • 클래슀 λ ˆλ²¨μ— λΆ™μž„
    ➜ JPA 관리 λŒ€μƒ μ—”ν‹°ν‹°κ°€ 됨

  • μ• νŠΈλ¦¬λ·°νŠΈ name μ‚¬μš© κ°€λŠ₯
    ➜ μ—”ν‹°ν‹°μ˜ 이름 μ„€μ •
    ( μ„€μ • μ•ˆν•˜λ©΄ 클래슀λͺ…을 μ—”ν‹°ν‹° μ΄λ¦„μœΌλ‘œ 함 )
    Ex. @Entity(name = "USERS")

    πŸ’‘ @Entity 주의 사항

    • μ ‘κ·Ό μ œμ–΄μžκ°€ public / protected인 κΈ°λ³Έ μƒμ„±μžκ°€ ν•„μˆ˜
    • final 클래슀, enum, interface, inner ν΄λž˜μŠ€μ—λŠ” μ‚¬μš©μ΄ λΆˆκ°€
    • μ €μž₯ν•˜λ €λŠ” 속성은 final X

βœ”οΈ @Table

  • μ—”ν‹°ν‹° ν΄λž˜μŠ€μ™€ ν…Œμ΄λΈ” λ§€ν•‘ν•˜λŠ” μ• λ„ˆν…Œμ΄μ…˜ (μ˜΅μ…˜)

  • 클래슀 λ ˆλ²¨μ— λΆ™μž„

  • μ• νŠΈλ¦¬λ·°νŠΈ name μ‚¬μš© κ°€λŠ₯
    -> λ°μ΄ν„°λ² μŠ€μ˜ ν…Œμ΄λΈ” 이름 μ„€μ •
    ( μ„€μ • μ•ˆν•˜λ©΄ 클래슀λͺ…을 ν…Œμ΄λΈ” μ΄λ¦„μœΌλ‘œ 함 )

βœ”οΈ @Entity(name = "") vs @Table(name = "")
@Entity(name = "")λŠ” Entityλ₯Ό 식별할 이름을 μ •ν•˜λŠ” 것이고,
@Table(name = "")λŠ” λ°μ΄ν„°λ² μ΄μŠ€μ— 생성될 Table의 이름을 μ •ν•˜λŠ” 것
β €
❗ @Table이 μ—†κ³  @Entity(name ="")만 μ‘΄μž¬ν•˜λŠ” 경우,
@Entity의 name 속성에 μ˜ν•΄, Entity와 Table 이름이 λͺ¨λ‘ κ²°μ •
[μ°Έκ³ ] https://www.inflearn.com/questions/75556
β €
❗ @Table μ• λ„ˆν…Œμ΄μ…˜μ€ μ˜΅μ…˜μ΄μ§€λ§Œ, @Entity μ• λ„ˆν…Œμ΄μ…˜κ³Ό @Id μ• λ„ˆν…Œμ΄μ…˜μ€ ν•„μˆ˜

βœ”οΈ @NoArgsConstructor

  • νŒŒλΌλ―Έν„°κ°€ μ—†λŠ” κΈ°λ³Έ μƒμ„±μž ν•„μˆ˜λ‘œ μΆ”κ°€
    ( Spring Data JPA의 κΈ°μˆ μ„ μ μš©ν•  λ•Œ κΈ°λ³Έ μƒμ„±μžκ°€ μ—†λŠ” 경우 μ—λŸ¬κ°€ λ°œμƒν•˜λŠ” κ²½μš°κ°€ 있음 )

✏️ κΈ°λ³Έν‚€ 맀핑

βœ”οΈ @Id

  • 이 μ• ν„°ν…Œμ΄μ…˜μ„ μΆ”κ°€ν•œ ν•„λ“œκ°€ κΈ°λ³Έν‚€(Primary Key) 컬럼이 됨

βœ”οΈ @GeneratedValue(strategy = GenerationType.생성방법)

  • κΈ°λ³Έν‚€ 생성 방법을 정해쀄 λ•Œ μ‚¬μš©ν•˜λŠ” μ• λ„ˆν…Œμ΄μ…˜

βœ”οΈ κΈ°λ³Έν‚€ 생성 μ „λž΅
β €
1. κΈ°λ³Έν‚€ 직접 ν• λ‹Ή

  • μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μ½”λ“œμƒμ— 직접 ν• λ‹Ήν•΄μ£ΌλŠ” 방식
  • @Id μ• λ„ˆν…Œμ΄μ…˜ μ‚¬μš©ν•˜λŠ” 방식
    ( μ•„λž˜λŠ” DIRECT λ°©μ‹μ˜ 좜λ ₯ κ²°κ³Ό )

    β €
  1. κΈ°λ³Έν‚€ μžλ™ 생성
    • IDENTITY
      ➜ λ°μ΄ν„°λ² μ΄μŠ€μ— κΈ°λ³Έν‚€ 생성을 μœ„μž„ν•˜λŠ” 방식
      Ex. MySQL의 AUTO_INCREMENT κΈ°λŠ₯ ( κΈ°λ³Έν‚€μ˜ μˆ«μžκ°€ μžλ™μœΌλ‘œ +1 )
      ➜ commit() μ „ κΉŒμ§€λŠ” μ˜μ†μ„± μ»¨ν…μŠ€νŠΈμ˜ 1μ°¨ μΊμ‹œμ—μ„œ μ‹λ³„μžκ°€ μ—†λŠ” 객체만 가지고 μžˆλ‹€κ°€, commit() ν•˜λ©΄μ„œ ν…Œμ΄λΈ”μ— 데이터가 μ €μž₯될 λ•Œ μ‹λ³„μžλ„ λ™μ‹œμ— μƒκ²¨μ„œ ν…Œμ΄λΈ”μ— 듀어감 ➜ 이 ν›„, 1μ°¨ μΊμ‹œμ˜ 객체에도 κ·Έ μ‹λ³„μžκ°€ 적용됨
      ( μ•„λž˜λŠ” IDENTITY 생성 λ°©μ‹μ˜ 좜λ ₯ κ²°κ³Ό )
      β €
      β €
    • SEQUENCE
      ➜ λ°μ΄ν„°λ² μ΄μŠ€μ—μ„œ μ œκ³΅ν•˜λŠ” μ‹œν€€μŠ€λ₯Ό μ‚¬μš©ν•΄ κΈ°λ³Έν‚€λ₯Ό μƒμ„±ν•˜λŠ” 방식
      ➜ 데이터λ₯Ό ν…Œμ΄λΈ”μ— μ €μž₯ν•˜κΈ° 전에 μ˜μ†μ„± μ»¨ν…μŠ€νŠΈμ˜ 1μ°¨ μΊμ‹œ 내에 μ €μž₯λ˜μ–΄ μžˆλŠ” 객체에 μ‹œν€€μŠ€λ‘œ κ°€μ Έμ˜¨ μ‹λ³„μžλ₯Ό μ±„μ›Œ λ„£μŒ ➜ commit() ν•˜λ©΄ ν…Œμ΄λΈ”μ— μ‹λ³„μž λ°”λ‘œ μ±„μ›Œμ§
      ( μ•„λž˜λŠ” SEQUENCE 생성 λ°©μ‹μ˜ 좜λ ₯ κ²°κ³Ό )

      β €
    • TABLE
      ➜ ν‚€ 생성 μ „μš© TABLE을 λ³„λ„λ‘œ λ§Œλ“€κ³ , ν‚€λ₯Ό 쑰회/μ—…λ°μ΄νŠΈ ν•˜λŠ” 쿼리λ₯Ό μΆ”κ°€μ μœΌλ‘œ μ „μ†‘ν•΄μ•Όν•΄μ„œ μ„±λŠ₯λ©΄μ—μ„œ 쒋은 선택 X
      β €
      ❗ IDENTITY / SEQUENCE 방식을 μ‚¬μš©ν•˜λŠ” 것이 μ’‹μŒ

✏️ μ—”ν‹°ν‹° ν•„λ“œ(멀버 λ³€μˆ˜) - ν…Œμ΄λΈ” 컬럼 κ°„ 맀핑

βœ”οΈ @Column

  • ν•„λ“œμ™€ μ»¬λŸΌμ„ λ§€ν•‘ν•΄μ£ΌλŠ” μ• λ„ˆν…Œμ΄μ…˜

    πŸ’‘ @Column μ• λ„ˆν…Œμ΄μ…˜μ΄ μ—†κ³  ν•„λ“œλ§Œ μ •λ¦¬λ˜μ–΄ μžˆλ‹€λ©΄,
    JPA λŠ” 기본적으둜 이 ν•„λ“œκ°€ ν…Œμ΄λΈ”μ˜ 컬럼과 λ§€ν•‘λ˜λŠ” ν•„λ“œλΌκ³  간주함
    ( μ• νŠΈλ¦¬λ·°νŠΈλŠ” λ””ν΄νŠΈ 값이 적용됨 )


    πŸ’‘ @Column μ• λ„ˆν…Œμ΄μ…˜μ΄ μƒλž΅λ˜μ—ˆκ±°λ‚˜ μ• νŠΈλ¦¬λ·°νŠΈκ°€ 기본값을 μ‚¬μš©ν•  경우 주의 사항
    @Column(nullable = true, updatable = true, unique = false)
    μ—¬κΈ°μ„œ nullable κ°’μ˜ λ””ν΄νŠΈκ°€ true인데
    이 경우, ν•„λ“œμ˜ 데이터 νƒ€μž…μ΄ int, long 값은 Java의 μ›μ‹œ νƒ€μž…μΌ 경우 null κ°’ μž…λ ₯ λΆˆκ°€!
    ( null은 객체 νƒ€μž…μΌ κ²½μš°μ—λ§Œ μ μš©λ˜λ‹ˆκΉŒ )
    ➜ ❗ μ΅œμ†Œν•œ nullable=falseλŠ” μ„€μ •ν•˜μ—¬ μ—λŸ¬ λ°©μ§€ν•˜κΈ° !!

  • λ³€μˆ˜λ§ˆλ‹€ 적어야함
    ➜ 번거둭긴 ν•˜μ§€λ§Œ ν…Œμ΄λΈ” 섀계가 μ–΄λ–€ μ‹μœΌλ‘œ λ˜μ–΄μžˆλŠ”μ§€ ν•œλˆˆμ— 확인 κ°€λŠ₯

βœ”οΈ @Column의 μ• νŠΈλ¦¬λ·°νŠΈ

  • nullable
    ➜ μ»¬λŸΌμ— null κ°’ ν—ˆμš©ν• μ§€ μ—¬λΆ€ ( λ””ν΄νŠΈ - true ) / email 은 둜그인 ID 둜 많이 μ‚¬μš©λ˜μ–΄ ν•„μˆ˜κΈ° λ•Œλ¬Έμ— false 둜 지정함
    β €
  • updatable
    ➜ 컬럼 데이터λ₯Ό μˆ˜μ •ν•  수 μžˆλŠ”μ§€ μ—¬λΆ€ 지정 ( λ””ν΄νŠΈ - true )
    Ex. email을 둜그인 ID 둜 μ‚¬μš©ν•œλ‹€κ³  κ°€μ •ν•˜κ³  λ“±λ‘ν•˜λ©΄ μˆ˜μ • λΆˆκ°€μ΄κΈ° λ•Œλ¬Έμ— false 둜 지정해야함
    β €
  • unique
    ➜ ν•˜λ‚˜μ˜ μ»¬λŸΌμ— μœ λ‹ˆν¬ μ œμ•½ 쑰건 μ„€μ •(κ³ μœ ν•œ κ°’μœΌλ‘œ μ„€μ •) ( λ””ν΄νŠΈ - false )
    Ex. email은 고유 κ°’μ΄λ―€λ‘œ true둜 지정
    β €
  • length
    ➜ μ»¬λŸΌμ— μ €μž₯ν•  수 μžˆλŠ” 문자 길이 지정 ( λ””ν΄νŠΈ - 255 )
    β €
  • name
    ➜ μ—”ν‹°ν‹° 클래슀 ν•„λ“œλͺ…κ³Ό λ‹€λ₯Έ μ΄λ¦„μœΌλ‘œ μ»¬λŸΌμ„ 생성 κ°€λŠ₯
    β €
    [μ°Έκ³ ] https://docs.oracle.com/javaee/7/api/

βœ”οΈ @Transient

  • 이 μ• λ„ˆν…Œμ΄μ…˜ μΆ”κ°€ν•˜λ©΄ ν…Œμ΄λΈ” 컬럼과 λ§€ν•‘ν•˜μ§€ μ•Šκ² λ‹€λŠ” 의미둜 JPA κ°€ 인식
    ➜ 데이터 λ² μ΄μŠ€μ— μ €μž₯ X / μ‘°νšŒν•  λ•Œ 맀핑 X
    (주둜 μž„μ‹œ 데이터λ₯Ό λ©”λͺ¨λ¦¬μ—μ„œ μ‚¬μš©ν•˜κΈ° μœ„ν•œ μš©λ„)

βœ”οΈ @Enumerated(EnumType.νƒ€μž…) / @Enumerated(values = EnumType.νƒ€μž…)

  • enum νƒ€μž…κ³Ό 맀핑할 λ•Œ μ‚¬μš©ν•˜λŠ” μ• λ„ˆν…Œμ΄μ…˜
  • μ•„λž˜μ˜ 두가지 Enumνƒ€μž…μ„ κ°€μ§ˆ 수 있음

βœ”οΈ EnumType μ’…λ₯˜
β €β €

  • ORDINAL
    ➜ enum의 μˆœμ„œλ₯Ό λ‚˜νƒ€λ‚΄λŠ” 숫자λ₯Ό ν…Œμ΄λΈ”μ— μ €μž₯
    Ex. 우리 μ‹€μŠ΅μ—μ„œ enum orderStatus() μ•ˆμ˜ μƒνƒœλ₯Ό 4개λ₯Ό μ§€μ •ν–ˆλŠ”λ°,
    이게 String으둜 μ €μž₯λ˜λŠ” 것이 μ•„λ‹ˆλΌ 숫자둜 인덱슀처럼 μ €μž₯됨
    But, 이 경우 쀑간에 μƒˆλ‘œμš΄ enum ν•˜λ‚˜κ°€ μΆ”κ°€λ˜λ©΄ μˆœμ„œ,λ²ˆν˜Έκ°€ μ΄μƒν•΄μ Έμ„œ 잘 μ‚¬μš© X
    β €β €
  • STRING
    ➜ enum의 이름을 ν…Œμ΄λΈ”μ— μ €μž₯
    β €
    ❗ EnumType.STRING μ‚¬μš© ꢌμž₯

✏️ μ—”ν‹°ν‹° - μ—”ν‹°ν‹°μ˜ μ—°κ΄€ 관계 맀핑

  • 보톡 λ‹€(N)에 ν•΄λ‹Ήν•˜λŠ” ν΄λž˜μŠ€μ— 일(1)에 ν•΄λ‹Ήν•˜λŠ” 객체λ₯Ό μ™Έλž˜ν‚€λ‘œ κ°€μ Έμ˜€λŠ” 방식 !

  • 단방ν–₯ μ—°κ΄€ 관계
    ➜ ν•œμͺ½ 클래슀만 λ‹€λ₯Έ μͺ½ 클래슀의 μ°Έμ‘° 정보λ₯Ό 가지고 μžˆλŠ” 관계

  • μ–‘λ°©ν–₯ μ—°κ΄€ 관계
    ➜ μ–‘μͺ½ ν΄λž˜μŠ€κ°€ μ„œλ‘œμ˜ μ°Έμ‘° 정보λ₯Ό 가지고 μžˆλŠ” 관계

πŸ’¬ 무쑰건 μ–‘λ°©ν–₯ 관계λ₯Ό ν•˜λ©΄ 쉽지 μ•Šμ„κΉŒ?
NO. λΆˆν•„μš”ν•œ μ—°κ΄€κ΄€κ³„λ‘œ 였히렀 μ—”ν‹°ν‹°κ°€ λ³΅μž‘ν•΄μ§ˆ 수 있음
Ex. μ‚¬μš©μž(User) μ—”ν‹°ν‹°κ°€ λ§Žμ€ 엔티티와 연관관계λ₯Ό κ°€μ§€λŠ”λ° 이 경우 λͺ¨λ“  ν΄λž˜μŠ€μ™€ μ–‘λ°©ν–₯ κ΄€κ³„λ‘œ 맀핑을 ν•œλ‹€λ©΄ User 클래슀 λ‚΄μ˜ μ½”λ“œμ˜ λ³΅μž‘μ„±μ΄ 증가할 것
➜ 기본적으둜 단방ν–₯ 맀핑을 ν•˜κ³  후에 ν•„μš”κ°€ μžˆλ‹€κ³  μƒκ°λ˜λ©΄ μ—­λ°©ν–₯ 맀핑을 μΆ”κ°€

πŸ’‘ JPA vs Spring Data JDBC 의 λ°©ν–₯μ„±

  • JPA
    ➜ 단방ν–₯ μ—°κ΄€ 관계와 μ–‘λ°©ν–₯ μ—°κ΄€ 관계λ₯Ό λͺ¨λ‘ 지원
    β €
  • Spring Data JDBC
    ➜ 단방ν–₯ μ—°κ΄€ κ΄€κ³„λ§Œ 지원

βœ”οΈ μΌλŒ€λ‹€ 단방ν–₯ μ—°κ΄€ 관계 ( One To Many )

  • 일(1)에 ν•΄λ‹Ήν•˜λŠ” ν΄λž˜μŠ€κ°€ λ‹€(N)에 ν•΄λ‹Ήν•˜λŠ” 객체λ₯Ό μ°Έμ‘°ν•  수 μžˆλŠ” 관계

Ex. ν•œλͺ…μ˜ νšŒμ›μ΄ μ—¬λŸ¬ 건의 μ£Όλ¬Έ
➜ Member ν΄λž˜μŠ€μ— Order의 Listκ°€ μ°Έμ‘°λ˜μ–΄ μžˆλŠ” λͺ¨μŠ΅

❗ But, μΌλŒ€λ‹€ 단방ν–₯ μ—°κ΄€ κ΄€κ³„λŠ” 잘 μ‚¬μš© X
ν…Œμ΄λΈ” κ°„ κ΄€κ³„λ‘œ λ³΄μ•˜μ„ λ•Œ,
λ‹€(N)에 ν•΄λ‹Ήν•˜λŠ” ν…Œμ΄λΈ”μ΄ 일(1)에 ν•΄λ‹Ήν•˜λŠ” ν…Œμ΄λΈ”μ˜ κΈ°λ³Έν‚€λ₯Ό μ™Έλž˜ν‚€λ‘œ κ°€μ§€λŠ” ν˜•νƒœμΈλ°,
κΈ°λ³Έ 객체 μ°Έμ‘° κ΄€κ³„λ‘œ λ³΄μ•˜μ„ λ•Œ,
일(1)에 ν•΄λ‹Ήν•˜λŠ” ν΄λž˜μŠ€κ°€ λ‹€(N)에 ν•΄λ‹Ήν•˜λŠ” 객체λ₯Ό μ°Έμ‘°λ°›κΈ° λ•Œλ¬Έμ—
λ‹€(N)의 μž…μž₯μ—μ„œλŠ” ν…Œμ΄λΈ”μ—μ„œ μ™Έλž˜ν‚€μ— ν•΄λ‹Ήν•˜λŠ” 일(1) 객체의 참쑰값을 가지고 μžˆμ§€ μ•Šμ•„μ„œ 일반적인 ν…Œμ΄λΈ” κ°„ 관계 ν‘œν˜„ X
➜ λ‹€(N) 클래슀의 정보λ₯Ό ν…Œμ΄λΈ”μ— μ €μž₯ν•˜λ”λΌλ„ μ™Έλž˜ν‚€μ— ν•΄λ‹Ήν•˜λŠ” 일(1) 클래슀의 id 값이 μ—†λŠ” μ±„λ‘œ μ €μž₯이 됩

➜ ❗ λ‹€λŒ€μΌ 단방ν–₯ 맀핑을 λ¨Όμ € ν•œ 후에 ν•„μš”ν•œ 경우, μΌλŒ€λ‹€ 단방ν–₯ 맀핑을 μΆ”κ°€ν•΄μ„œ μ–‘λ°©ν–₯ μ—°κ΄€ 관계λ₯Ό λ§Œλ“œλŠ” 것이 일반적

πŸ’¬ κΆκΈˆν–ˆλ˜ 점 !!!

μœ„μ˜ 단방ν–₯ μΌλŒ€λ‹€ λ§€ν•‘μ—μ„œ Member(1) ν΄λž˜μŠ€μ— Order(N) 객체가 List둜 μ°Έμ‘°κ°€ λ˜μ–΄μžˆλŠ”λ°,
μ—¬κΈ°μ„œ @JoinColumn(name = "") μ• λ„ˆν…Œμ΄μ…˜μ€ μ™Έλž˜ν‚€μ˜ λͺ…을 μ •ν•΄μ£ΌλŠ” 것이고, Member(1)κ°€ μ™Έλž˜ν‚€λ‘œ Order(N)에 μ°Έμ‘°λ˜μ–΄μ•Ό ν•˜κΈ° λ•Œλ¬Έμ— κ·Έλž˜μ„œ μ™Έλž˜ν‚€μ˜ 이름을 MEMBER_ID둜 ν•˜λŠ” 것이닀.
그런데, Member 클래슀 내에 Order 객체λ₯Ό List둜 κ°€μ Έμ™”λŠ”λ°
μ™œ κ·Έ Order 객체의 pkλ₯Ό MEMBER_IDλΌλŠ” μ™Έλž˜ν‚€ μ΄λ¦„μœΌλ‘œ μ„€μ •ν•˜λŠ” 건지
잘 이해가 가지 μ•Šμ•˜λ‹€.

πŸ’¬ Answer )

보면 μ΄μƒν•˜μ§€λ§Œ, 단방ν–₯이기 λ•Œλ¬Έμ— Orderμ—μ„œλŠ” Memberλ₯Ό μ°Έμ‘°ν•˜μ§€ μ•ŠμŒ
κ·Έλž˜μ„œ @JoinColumn을 κ·Έμͺ½μ— μΆ”κ°€ν•˜λ €κ³ ν•΄λ„ μΆ”κ°€ν•  수 μ—†μŒ
λ”°λΌμ„œ Member μͺ½μ—μ„œ μ—°κ΄€ 관계λ₯Ό λ§Ίμ–΄μ£ΌλŠ” μͺ½μ— μΆ”κ°€ν•΄μ£ΌλŠ” 것 !
β €
➜ 단뱑ν–₯μ΄λΌμ„œ ν•œμͺ½μ—λ‹€λ§Œ λͺ¨λ‘ λ„£μ–΄μ•Όν•˜λ‹ˆκΉŒ Order도 μ°Έμ‘° ν•˜κ³ , μ°Έμ‘°κ°€ 될 μ™Έλž˜ν‚€μΈ Member(1)클래슀의 memberId도 MEMBER_IDλΌλŠ” μ΄λ¦„μœΌλ‘œ μΆ”κ°€ν•΄μ£ΌλŠ” 것 !

βœ”οΈ λ‹€λŒ€μΌ μ—°κ΄€ 관계 ( Many To One )

  • λ‹€(N)에 ν•΄λ‹Ήν•˜λŠ” ν΄λž˜μŠ€κ°€ 일(1)에 ν•΄λ‹Ήν•˜λŠ” 객체λ₯Ό μ°Έμ‘°ν•  수 μžˆλŠ” 관계

  • κ°€μž₯ 기본으둜 μ‚¬μš©λ˜λŠ” 맀핑 방식

Ex. ν•œλͺ…이 μ—¬λŸ¬κ±΄μ˜ μ£Όλ¬Έ

➜ Order ν΄λž˜μŠ€μ— memberκ°€ μ°Έμ‘°λ˜μ–΄ μžˆλŠ” λͺ¨μŠ΅

  • @ManyToOne μ• λ„ˆν…Œμ΄μ…˜μœΌλ‘œ λ‹€λŒ€μΌ 관계λ₯Ό λͺ…μ‹œν•΄μ€Œ

  • @JoinColumn(name = "μ™Έλž˜ν‚€λͺ…") μ• λ„ˆν…Œμ΄μ…˜μœΌλ‘œ μ™Έλž˜ν‚€ 이름 μ„€μ •

  • 참쑰될 Member 객체λ₯Ό κ°€μ Έμ˜΄

➜ Member ν΄λž˜μŠ€μ— Orderκ°€ List둜 μ°Έμ‘°λ˜μ–΄ μžˆλŠ” λͺ¨μŠ΅

  • @OneToMany μ• λ„ˆν…Œμ΄μ…˜μœΌλ‘œ μΌλŒ€λ‹€ 관계λ₯Ό λͺ…μ‹œν•΄μ€Œ

  • μœ„ μ• λ„ˆν…Œμ΄μ…˜μ˜ μ• νŠΈλ¦¬λ·°νŠΈλ‘œ (mappedBy = "μ™Έλž˜ν‚€ μ—­ν• ν•˜λŠ” ν•„λ“œ")λ₯Ό λ„£μ–΄μ£Όμ–΄ μ™Έλž˜ν‚€μ˜ 역할을 ν•˜κ³  μžˆμŒμ„ μ•Œλ €μ€Œ

  • μ°Έμ‘°λ₯Ό λ°›λŠ” Order 객체λ₯Ό List둜 κ°€μ Έμ˜΄
    ( ν•œ νšŒμ›μ΄ μ—¬λŸ¬ μ£Όλ¬Έ κ°€λŠ₯μ΄λ‹ˆκΉŒ )

πŸ’‘ mappedBy에 μ˜€λŠ” 값이 ν—·κ°ˆλ¦΄ λ•Œ !
β €
1. 두 객체듀 간에 μ™Έλž˜ν‚€μ˜ 역할을 ν•˜λŠ” ν•„λ“œλŠ” 무엇인가?
2. μ™Έλž˜ν‚€μ˜ 역할을 ν•˜λŠ” ν•„λ“œλŠ” λ‹€(N)에 ν•΄λ‹Ήν•˜λŠ” 클래슀 μ•ˆμ— 있음
β €
이 두가지λ₯Ό 생각해보면 쉬움!

βœ”οΈ λ‹€λŒ€λ‹€ μ—°κ΄€ 관계 ( Many To Many )

  • @ManyToMany μ• λ„ˆν…Œμ΄μ…˜μ„ μ‚¬μš©ν•˜μ§€ μ•Šκ³  Join ν…Œμ΄λΈ”κ³Ό 같은 클래슀λ₯Ό ν•˜λ‚˜ 더 λ§Œλ“€μ–΄ 1-N-1 κ΄€κ³„λ‘œ,
    λ‹€λŒ€μΌ 관계λ₯Ό λ‘λ²ˆ μ„€μ •ν•˜λ©΄ 됨!

❗ @ManyToMany μ• λ„ˆν…Œμ΄μ…˜μ„ μ¨μ„œ λ”°λ‘œ 클래슀λ₯Ό λ§Œλ“€μ§€ μ•Šκ³  μ—°κ΄€ 관계λ₯Ό 맺어쀄 수 μžˆμ§€λ§Œ, 이 경우 쀑간에 값이 μΆ”κ°€κ°€ μ•ˆλ˜κΈ° λ•Œλ¬Έμ— μ‚¬μš© X

Ex. Coffee ν΄λž˜μŠ€μ™€ Order ν΄λž˜μŠ€κ°€ μžˆμ„ λ•Œ,
ν•œ 컀피λ₯Ό μ—¬λŸ¬λͺ…이 μ£Όλ¬Έ κ°€λŠ₯ / ν•œλͺ…이 μ—¬λŸ¬ 컀피 μ£Όλ¬Έ κ°€λŠ₯ ➜ λ‹€λŒ€λ‹€ 관계

➜ 이λ₯Ό λ‹€λŒ€μΌ κ΄€κ³„λ‘œ 풀어쀄 OrderCoffee 클래슀 생성

κ²°κ΅­ κ΄€κ³„λŠ” Coffee(1) - OrderCoffee(N) / OrderCoffee(N) - Order(1) 이 λ˜λŠ” 것!

이 ν›„λŠ” λ‹€λŒ€μΌ 관계와 같이 μ§„ν–‰ν•˜λ©΄ 됨 !

➜ OrderCoffee ν΄λž˜μŠ€μ— Order / Coffeeκ°€ μ°Έμ‘°λ˜μ–΄ μžˆλŠ” λͺ¨μŠ΅

➜ Order ν΄λž˜μŠ€μ— OrderCoffeeκ°€ μ°Έμ‘°λ˜μ–΄ μžˆλŠ” λͺ¨μŠ΅

➜ Coffee ν΄λž˜μŠ€μ— OrderCoffeeκ°€ μ°Έμ‘°λ˜μ–΄ μžˆλŠ” λͺ¨μŠ΅

βœ”οΈ μΌλŒ€μΌ μ—°κ΄€ 관계 ( One To One )

  • @OneToOne μ• λ„ˆν…Œμ΄μ…˜μ„ μ‚¬μš©ν•˜κ³ ,
    λ‹€λŒ€μΌ μ–‘λ°©ν–₯ 맀핑 처럼 μ™Έλž˜ν‚€κ°€ μžˆλŠ” 곳이 μ—°κ΄€ κ΄€κ³„μ˜ 주인
    ( 이 μ™Έλž˜ν‚€λ₯Ό 어디에 λ‘λŠλƒλŠ” μš°λ¦¬κ°€ μ •ν•˜κΈ° λ‚˜λ¦„ ! )

Ex. ν•œλͺ…μ˜ νšŒμ›μ΄ ν•œκ°œμ˜ μŠ€νƒ¬ν”„λ₯Ό 찍을 수 μžˆλ‹€κ³  ν•  λ•Œ,

λ‚˜λŠ” Stampκ°€ Member의 μ™Έλž˜ν‚€λ₯Ό 가지고 μžˆλ‹€κ³  μƒκ°ν•˜μ—¬ μ•„λž˜μ™€ 같이 λ§Œλ“€μ—ˆλ‹€

➜ Stamp ν΄λž˜μŠ€μ— Memberκ°€ μ°Έμ‘°λ˜μ–΄ μžˆλŠ” λͺ¨μŠ΅

➜ Member ν΄λž˜μŠ€μ— Stampκ°€ μ°Έμ‘°λ˜μ–΄ μžˆλŠ” λͺ¨μŠ΅

[μ°Έκ³ ] https://beagle-dev.tistory.com/306

πŸ’‘ μ—°κ΄€ κ΄€κ³„μ˜ 주인

  • μ–‘λ°©ν–₯ 관계일 λ•Œ μ—°κ΄€ κ΄€κ³„μ˜ 주인을 지정해야함
    ( 두 단방ν–₯ 관계 쀑, μ œμ–΄μ˜ κΆŒν•œ(μ €μž₯,μˆ˜μ •,μ‚­μ œ λ“±)을 κ°–λŠ” μ‹€μ§ˆμ μΈ κ΄€κ³„μ˜ 주체가 λˆ„κ΅¬μΈμ§€ JPAμ—κ²Œ μ•Œλ €μ£ΌλŠ” 것 )
    ➜ mappedBy 속성을 μ‚¬μš©ν•΄μ„œ 주인을 지정
    β €
    ❗ μ™Έλž˜ ν‚€κ°€ μžˆλŠ” κ³³ = μ—°κ΄€ κ΄€κ³„μ˜ 주인 !!

πŸ’‘ μ—°κ΄€ κ΄€κ³„μ˜ 주인을 μ§€μ •ν•΄μ•Όν•˜λŠ” 이유

  • ν…Œμ΄λΈ”μ˜ 맀핑을 λ‹΄λ‹Ήν•˜λŠ” JPA μž…μž₯μ—μ„œ 두 클래슀 쀑 μ–΄λŠ 것을 μˆ˜μ •ν•΄μ•Όν•  지 ν˜Όλž€μ„ 주게 됨
    ➜ μ—°κ΄€ κ΄€κ³„μ˜ 주인을 μ •ν•΄ λͺ…ν™•ν•˜κ²Œ μ–΄λŠ ν΄λž˜μŠ€μ—μ„œ 뭐λ₯Ό μˆ˜μ •ν•˜κ² λ‹€κ³  μ •ν•˜λŠ” 것 !

βœ” μ˜μ†μ„± 전이

  • νŠΉμ • μ—”ν‹°ν‹°λ₯Ό μ˜μ†μ„± μ»¨ν…μŠ€νŠΈμ—μ„œ 관리할 λ•Œ μ—°κ΄€λœ 엔티티도 같이 κ΄€λ¦¬ν•˜κ³ μž ν•˜λŠ”
    것
    ( μ—°κ΄€λœ μ—”ν‹°ν‹°μ˜ μ •λ³΄κΉŒμ§€ ν•œκΊΌλ²ˆμ— μ‘°νšŒν•˜κ±°λ‚˜ μ‚­μ œν•˜λŠ” λ“±μ˜ λ™μž‘ ν•  수 있음 )

  • 연관관계 맀핑 μ• λ„ˆν…Œμ΄μ…˜μ˜ cascade μ• νŠΈλ¦¬λ·°νŠΈλ‘œ μ„€μ •
    Ex. @OneToOne(mappedBy = "member", cascade = CascadeType.PERSIST)

βœ”οΈ Cascade Type μ’…λ₯˜

  • PERSIST
    • μ—°κ΄€λœ μ—”ν‹°ν‹°κΉŒμ§€ μ˜μ†ν™”μ‹œν‚΄
  • REMOVE
    • μ—°κ΄€λœ μ—”ν‹°ν‹°κΉŒμ§€ μ˜μ†μ„± μ»¨ν…μŠ€νŠΈμ—μ„œ 제거
  • MERGE
    • μ˜μ† μƒνƒœμ˜ 엔티티와 μ€€μ˜μ† μƒνƒœμ˜ μ—”ν‹°ν‹°λ₯Ό 병합할 λ•Œ μ—°κ΄€λœ μ—”ν‹°ν‹°κΉŒμ§€
      병합을 적용
  • REFRESH
    • μ—”ν‹°ν‹°λ₯Ό λ‹€μ‹œ 읽어 올 λ•Œ, μ—°κ΄€λœ μ—”ν‹°ν‹°κΉŒμ§€ λ‹€μ‹œ μ½μ–΄μ˜΄
  • DETACH

✏️JPA API

private EntityManager em;
// JPA 의 μ˜μ†μ„± μ»¨ν…μŠ€νŠΈλŠ” EntityManager μΈν„°νŽ˜μ΄μŠ€μ— μ˜ν•΄μ„œ 관리됨
private EntityTransaction tx;
// 이 객체λ₯Ό κΈ°μ€€μœΌλ‘œ 데이터λ₯Ό λ°μ΄ν„°λ² μ΄μŠ€ ν…Œμ΄λΈ”μ— μ €μž₯

βœ”οΈ tx.begin();

  • Transaction μ‹œμž‘μ„ μœ„ν•œ λ©”μ„œλ“œ 호좜

βœ”οΈ em.persist(new 객체(κ°’));

  • 객체λ₯Ό μ˜μ†μ„± μ»¨ν…μŠ€νŠΈμ— μ €μž₯

  • 이 λ©”μ„œλ“œ 호좜 μ‹œ, 1μ°¨ μΊμ‹œμ— 객체가 μ €μž₯되고, 이 κ°μ²΄λŠ” μ“°κΈ° 지연 SQL μ €μž₯μ†Œμ— INSERT 쿼리 ν˜•νƒœ(INSERT ...(객체λͺ…))둜 등둝됨

But, μ‹€μ œ ν…Œμ΄λΈ”μ—λŠ” 이 정보λ₯Ό μ €μž₯ν•˜μ§€ μ•Šκ³ , μ‹€μ œ λ‘œκ·Έμ—λ„ INSET 쿼리 μ•ˆλ³΄μž„
➜ commit()으둜 λ”°λ‘œ μ €μž₯ν•΄μ€˜μ•Ό 함

❗ μˆœμ„œ μ£Όμ˜ν•˜λ©΄μ„œ persist() 해야함 !

Ex. Coffee(1) / Order(1) / OrderCoffee(N) ν΄λž˜μŠ€κ°€ μžˆμ„ λ•Œ,
OrderCoffee ν΄λž˜μŠ€λŠ” Coffee와 Order의 μ™Έλž˜ν‚€λ₯Ό μ°Έμ‘°λ°›κ³  있기 λ•Œλ¬Έμ—
Coffee / Order 보닀 늦게 persist() 해야함

βœ”οΈ em.find(μ‘°νšŒν•  μ—”ν‹°ν‹° 클래슀 νƒ€μž…, μ‘°νšŒν•  μ—”ν‹°ν‹° 클래슀의 μ‹λ³„μž κ°’);

  • commit()으둜 ν…Œμ΄λΈ”μ— μ €μž₯된 객체λ₯Ό μ˜μ†μ„± μ»¨ν…μŠ€νŠΈμ˜ 1μ°¨ μΊμ‹œμ—μ„œ 쑰회
    ( ν…Œμ΄λΈ”μ—μ„œ 쑰회 X )

βœ”οΈ em.remove();

  • μ˜μ†μ„± μ»¨ν…μŠ€νŠΈμ˜ 1μ°¨ μΊμ‹œμ— μžˆλŠ” μ—”ν‹°ν‹° 제거 μš”μ²­
    ➜ μ“°κΈ° 지연 SQL μ €μž₯μ†Œμ— DELETE 쿼리 등둝

βœ”οΈ em.flush();

  • commit() λ©”μ„œλ“œ ν˜ΈμΆœμ‹œ JPA λ‚΄λΆ€μ μœΌλ‘œ em.flush() λ©”μ„œλ“œκ°€ ν˜ΈμΆœλ˜μ–΄ μ˜μ†μ„± μ»¨ν…μŠ€νŠΈμ˜ λ³€κ²½ λ‚΄μš©μ„ λ°μ΄ν„°λ² μ΄μŠ€μ— 반영

βœ”οΈ tx.commit();

  • μ˜μ†μ„± μ»¨ν…μŠ€νŠΈμ˜ μ“°κΈ° 지연 SQL μ €μž₯μ†Œμ— λ“±λ‘λœ 쿼리 μ‹€ν–‰
    ➜ λ°μ΄ν„°λ² μ΄μŠ€μ— 데이터 μ €μž₯

😜 μ‹€μŠ΅

  • projects λ‚΄μ˜ be-template-jdbc 2


μœ„ 사진과 같이 yml νŒŒμΌμ— μ•„λž˜ λ‘κ°œ μΆ”κ°€ν•΄μ£ΌκΈ° !

  • ddl-auto: create
    ➜ μŠ€ν‚€λ§ˆ μžλ™ 생성
    ( μ—”ν‹°ν‹° ν΄λž˜μŠ€μ™€ λ§€ν•‘λ˜λŠ” ν…Œμ΄λΈ”μ„ λ°μ΄ν„°λ² μ΄μŠ€μ— μžλ™ μƒμ„±ν•΄μ€Œ )
    ( schema.sql 파일 생성 ν•„μš” X )

  • show-sql: true
    ➜ SQL 쿼리 좜λ ₯
    ( JPA API λ₯Ό ν†΅ν•΄μ„œ μ‹€ν–‰λ˜λŠ” SQL 쿼리λ₯Ό 둜그둜 좜λ ₯ )
    ( λ™μž‘ κ³Όμ • 이해 쉬움 )

클래슀λ₯Ό μƒμ„±ν•˜μ—¬ λ‚΄λΆ€ μ½”λ“œλ₯Ό μž‘μ„±ν•˜κ³  좜λ ₯ν•˜λ©΄ μ•„λž˜μ™€ 같이 ν…Œμ΄λΈ”μ΄ μžλ™μƒμ„±λœ 것을 λ³Ό 수 있음 !

μ•„λž˜λŠ” find() λ©”μ„œλ“œλ‘œ IDκ°€ 1인 Member의 email μ£Όμ†Œλ₯Ό μ˜μ†μ„± μ»¨ν…μŠ€νŠΈμ—μ„œ μ‘°νšŒν•˜κ³ μžˆλŠ” 것 확인 κ°€λŠ₯ !

application.yml νŒŒμΌμ— μ•„λž˜μ™€ 같이 μΆ”κ°€ν•œλ‹€λ©΄

spring: //이건 이미 μ“°μ—¬ 있음
  jpa: //이것도 μ“°μ—¬ 있음
    properties: //μΆ”κ°€
      hibernate: //μΆ”κ°€
        format_sql: true //μΆ”κ°€

μœ„μ˜ μ˜ˆμ‹œ 사진듀과 같이 ν•œμ€„λ‘œ λ°‹λ°‹ν–ˆλ˜ λ‘œκ·Έλ“€μ„ μ•„λž˜μ™€ 같이 예쁘게 보기 κ°€λŠ₯ !!

[μ°Έκ³ ] https://lannstark.tistory.com/14


μ•„λž˜μ˜ μ½”λ“œλ₯Ό μ‹€ν–‰ν•˜λ©΄,

Member resultMember2 = em.find(Member.class, 2L);
//μ‹λ³„μž 값이 2L 인 member 객체 쑰회
//쑰회된 객체가 μ—†λ‹€λ©΄ ν…Œμ΄λΈ”μ—λ„ SELECT 쿼리 μ „μ†‘ν•˜μ—¬ 쑰회

System.out.println(resultMember2 == null); //μœ„μ—μ„œ μ‘°νšŒν•˜λŠ” 객체가 μ—†μœΌλ‹ˆκΉŒ 이 κ²°κ³Ό true

SELECT 쿼리가 μ‹€ν–‰λœ 것을 λ³Ό 수 있고,

이 SELECT 쿼리λ₯Ό 톡해 em.find(Member.class, 2L)둜 쑰회λ₯Ό ν–ˆλŠ”λ°

μ‹λ³„μž κ°’ 2L에 ν•΄λ‹Ήν•˜λŠ” member2 객체가 μ˜μ†μ„± μ»¨ν…μŠ€νŠΈμ˜ 1μ°¨ μΊμ‹œμ— μ—†κΈ° λ•Œλ¬Έμ—

μΆ”κ°€μ μœΌλ‘œ ν…Œμ΄λΈ”μ—μ„œ ν•œλ²ˆ 더 μ‘°νšŒν•œλ‹€λŠ” 것 μ•Œ 수 있음


μ•„λž˜μ™€ 같은 λ©”μ„œλ“œλ₯Ό μ‹€ν–‰μ‹œν‚€λ©΄,

private void example03() {
	tx.begin();

	Member member1 = new Member("hgd@gmail.com");
	Member member2 = new Member("hgd@gmail.com");

	em.persist(member1);
	em.persist(member2);
    //member1, member2 객체λ₯Ό μ˜μ†μ„± μ»¨ν…μŠ€νŠΈμ— μ €μž₯
    //--> 1μ°¨ μΊμ‹œ - member2 객체 / μ“°κΈ° 지연 SQL μ €μž₯μ†Œ - INSERT ...(member2)
    //--> ν…Œμ΄λΈ”μ—λŠ” μ €μž₯ X

	tx.commit();
    //μ˜μ†μ„± μ»¨ν…μŠ€νŠΈμ˜ μ“°κΈ° 지연 SQL μ €μž₯μ†Œμ— 있던 INSERT 쿼리문 μ‹€ν–‰
    //--> λ°μ΄ν„°λ² μ΄μŠ€μ— 데이터 μ €μž₯
}

μ•„λž˜μ™€ 같이 좜λ ₯ 결과에 두 member 객체가 μ €μž₯된 것을 μ•Œ 수 있음!

++μΆ”κ°€λ‘œ

@Setter μ• λ„ˆν…Œμ΄μ…˜μ„ 클래슀 λ ˆλ²¨μ—μ„œ μ‚¬μš©ν•˜λŠ” 것은 λ°”λžŒμ μ΄μ§€ μ•ŠμŒ !

ν•΄λ‹Ή 클래슀의 μ‹λ³„μž(Id)처럼 μˆ˜μ •μ΄λ˜λ©΄ μ•ˆλ˜λŠ” μ •λ³΄λŠ” λ°”λ€Œμ§€ μ•Šμ•„μ•Όν•˜λŠ”λ°

클래슀 λ ˆλ²¨μ— @Setter μ• λ„ˆν…Œμ΄μ…˜μ„ 뢙일 경우 변경될 수 있음 !

➜ @Setter μ• λ„ˆν…Œμ΄μ…˜μ€ μˆ˜μ •μ΄ ν•„μš”ν•œ ν•„λ“œ(λ©”μ„œλ“œ) λ ˆλ²¨μ—λ§Œ μ‚¬μš©ν•˜λŠ” 것이 λ°”λžŒμ§ !


🌈 λŠλ‚€μ 

ν™•μ‹€νžˆ JDBC 보닀 쉽고 κ·Έλž˜μ„œ κ·ΈλŸ°μ§€ μž¬λ°Œλ‹€ !!
λ­”κ°€ 이해도 잘 되고 정리도 더 잘 λ˜λŠ” λŠλ‚Œ
JDBC μ—μ„œλŠ” 아직 이해 λͺ»ν•œ 뢀뢄이 μžˆμ§€λ§Œ μ‹œκ°„μ΄ μ—†μ–΄μ„œ 일단 λ„˜μ–΄κ°”μ—ˆλŠ”λ°,
μ‹€λ¬΄μ—μ„œλŠ” JPAλ₯Ό 보톡 μ‚¬μš©ν•œλ‹€κ³  ν•˜λ‹ˆ 정말 닀행이닀 γ…Žγ…Ž

0개의 λŒ“κΈ€