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 κ΄λ ¨ μμ‘΄ λΌμ΄λΈλ¬λ¦¬λ₯Ό λ³λλ‘ μΆκ° )
[μ°Έκ³ ] https://thorben-janssen.com/entity-lifecycle-model/
λ°μ΄ν° μ‘μΈμ€ κ³μΈ΅μ μλ¨μ μμΉ
λ°μ΄ν° μ μ₯, μ‘°ν λ±μ μμ μ JPAλ₯Ό κ±°μ³ JPAμ ꡬνμ²΄μΈ Hibernate ORMμ ν΅ν΄μ μ΄λ£¨μ΄μ§
Hibernate ORMμ λ΄λΆμ μΌλ‘ JDBC APIλ₯Ό μ΄μ©ν΄μ λ°μ΄ν°λ² μ΄μ€μ μ κ·Ό
ν
μ΄λΈκ³Ό 맀νλλ μν°ν° κ°μ²΄ μ 보λ₯Ό 보κ΄
β μ ν리μΌμ΄μ
λ΄μμ μ€λ μ§μ λκ² νκ³ , μ΄ λ³΄κ΄λ μν°ν° μ 보λ λ°μ΄ν°λ² μ΄μ€ ν
μ΄λΈμ λ°μ΄ν°λ₯Ό 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
βοΈ @Id
βοΈ @GeneratedValue(strategy = GenerationType.μμ±λ°©λ²)
βοΈ κΈ°λ³Έν€ μμ± μ λ΅
β
1. κΈ°λ³Έν€ μ§μ ν λΉ
- μ ν리μΌμ΄μ μ½λμμ μ§μ ν λΉν΄μ£Όλ λ°©μ
@Id
μ λν μ΄μ μ¬μ©νλ λ°©μ
( μλλ DIRECT λ°©μμ μΆλ ₯ κ²°κ³Ό )
β
- κΈ°λ³Έν€ μλ μμ±
- 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.
β - unique
β νλμ 컬λΌμ μ λν¬ μ μ½ μ‘°κ±΄ μ€μ (κ³ μ ν κ°μΌλ‘ μ€μ ) ( λν΄νΈ - false )
Ex.
β - length
β 컬λΌμ μ μ₯ν μ μλ λ¬Έμ κΈΈμ΄ μ§μ ( λν΄νΈ - 255 )
β - name
β μν°ν° ν΄λμ€ νλλͺ κ³Ό λ€λ₯Έ μ΄λ¦μΌλ‘ 컬λΌμ μμ± κ°λ₯
β
[μ°Έκ³ ] https://docs.oracle.com/javaee/7/api/
βοΈ @Transient
βοΈ @Enumerated(EnumType.νμ
)
/ @Enumerated(values = EnumType.νμ
)
βοΈ 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
β λ¨λ°©ν₯ μ°κ΄ κ΄κ³λ§ μ§μ
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λΌλ μ΄λ¦μΌλ‘ μΆκ°ν΄μ£Όλ κ² !
λ€(N)μ ν΄λΉνλ ν΄λμ€κ° μΌ(1)μ ν΄λΉνλ κ°μ²΄λ₯Ό μ°Έμ‘°ν μ μλ κ΄κ³
κ°μ₯ κΈ°λ³ΈμΌλ‘ μ¬μ©λλ 맀ν λ°©μ
Ex. νλͺ
μ΄ μ¬λ¬κ±΄μ μ£Όλ¬Έ
β Order ν΄λμ€μ memberκ° μ°Έμ‘°λμ΄ μλ λͺ¨μ΅
@ManyToOne
μ λν
μ΄μ
μΌλ‘ λ€λμΌ κ΄κ³λ₯Ό λͺ
μν΄μ€
@JoinColumn(name = "μΈλν€λͺ
")
μ λν
μ΄μ
μΌλ‘ μΈλν€ μ΄λ¦ μ€μ
μ°Έμ‘°λ Member κ°μ²΄λ₯Ό κ°μ Έμ΄
β Member ν΄λμ€μ Orderκ° Listλ‘ μ°Έμ‘°λμ΄ μλ λͺ¨μ΅
@OneToMany
μ λν
μ΄μ
μΌλ‘ μΌλλ€ κ΄κ³λ₯Ό λͺ
μν΄μ€
μ μ λν
μ΄μ
μ μ νΈλ¦¬λ·°νΈλ‘ (mappedBy = "μΈλν€ μν νλ νλ")
λ₯Ό λ£μ΄μ£Όμ΄ μΈλν€μ μν μ νκ³ μμμ μλ €μ€
μ°Έμ‘°λ₯Ό λ°λ Order κ°μ²΄λ₯Ό Listλ‘ κ°μ Έμ΄
( ν νμμ΄ μ¬λ¬ μ£Όλ¬Έ κ°λ₯μ΄λκΉ )
π‘
mappedBy
μ μ€λ κ°μ΄ ν·κ°λ¦΄ λ !
β
1. λ κ°μ²΄λ€ κ°μ μΈλν€μ μν μ νλ νλλ 무μμΈκ°?
2. μΈλν€μ μν μ νλ νλλ λ€(N)μ ν΄λΉνλ ν΄λμ€ μμ μμ
β
μ΄ λκ°μ§λ₯Ό μκ°ν΄λ³΄λ©΄ μ¬μ!
@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κ° μ°Έμ‘°λμ΄ μλ λͺ¨μ΅
@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
private EntityManager em;
// JPA μ μμμ± μ»¨ν
μ€νΈλ EntityManager μΈν°νμ΄μ€μ μν΄μ κ΄λ¦¬λ¨
private EntityTransaction tx;
// μ΄ κ°μ²΄λ₯Ό κΈ°μ€μΌλ‘ λ°μ΄ν°λ₯Ό λ°μ΄ν°λ² μ΄μ€ ν
μ΄λΈμ μ μ₯
βοΈ tx.begin();
βοΈ 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μ°¨ μΊμμμ μ‘°νβοΈ em.remove();
βοΈ em.flush();
commit()
λ©μλ νΈμΆμ JPA λ΄λΆμ μΌλ‘ em.flush() λ©μλκ° νΈμΆλμ΄ μμμ± μ»¨ν
μ€νΈμ λ³κ²½ λ΄μ©μ λ°μ΄ν°λ² μ΄μ€μ λ°μβοΈ tx.commit();
μ μ¬μ§κ³Ό κ°μ΄ 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λ₯Ό λ³΄ν΅ μ¬μ©νλ€κ³ νλ μ λ§ λ€νμ΄λ€ γ
γ