[JPA] Persistence, ๋งคํ
Categories: Spring
๐ ๊ฐ์ธ์ ์ธ ๊ณต๊ฐ์ผ๋ก ๊ณต๋ถ๋ฅผ ๊ธฐ๋กํ๊ณ ๋ณต์ตํ๊ธฐ ์ํด ์ฌ์ฉํ๋ ๋ธ๋ก๊ทธ์
๋๋ค.
์ ํํ์ง ์์ ์ ๋ณด๊ฐ ์์ ์ ์์ผ๋ ์ฐธ๊ณ ๋ฐ๋๋๋ค :๐ธ
[ํ๋ฆฐ ๋ด์ฉ์ ๋๊ธ๋ก ๋จ๊ฒจ์ฃผ์๋ฉด ๋ณต๋ฐ์ผ์ค๊ฑฐ์์]
JPA(Java Persistence API)
- ๊ณต์๋ฌธ์ ์ฐธ๊ณ ํ๊ธฐ
https://docs.spring.io/spring-data/jpa/reference/jpa.html
JPA๋?
JPA
- ORM(Object-Relational Mapping) ๊ธฐ์ ์ ํ์ค ์ฌ์(๋๋ ๋ช ์ธ, Specification)
- ํ์ค์ฌ์์ด๋ ์ธํฐํ์ด์ค๋ก ์ฌ์์ด ์ ์๋์๊ธฐ ๋๋ฌธ์
- JPA๊ตฌํํ ๊ตฌํ์ฒด๋ ๋ฐ๋ก ์๋ค๋ ๊ฒ์ ์๋ฏธ
- ๊ตฌํ์ฒด๋ก๋ Hibernate ORM, EclipseLink, DataNucleus ๋ฑ์ด ์๋๋ฐ Hiberante ORM์ ๊ฐ์ฅ ๊ธฐ๋ณธ์ผ๋ก ์ฌ์ฉ
- JPA๋ Java Persistence API์ ์ฝ์์ด์ง๋ง ํ์ฌ๋ Jakarta Persistence๋ผ๊ณ ๋ ๋ถ๋ฆผ
Data Access Layer์์ JPA์ ์์น
- Layerd Architecture์์ ๋ฐ์ดํฐ ์ก์ธ์ค ๊ณ์ธต์ ์๋จ์ ์์น
- ๋ฐ์ดํฐ ์ ์ฅ, ์กฐํ ๋ฑ์ ์์ ์ JPA๋ฅผ ๊ฑฐ์ณ JPA์ ๊ตฌํ์ฒด์ธ Hibernate ORM์ ํตํด์ ์ด๋ฃจ์ด์ง
-
Hibernate ORM์ ๋ด๋ถ์ ์ผ๋ก JDBC API๋ฅผ ์ด์ฉํด์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ๊ทผ
Persistence
- JPA์์ P๋ Persistence๋ฅผ ๋ปํจ.
- ORM์ ๊ฐ์ฒด(Object)์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ํ ์ด๋ธ์ ๋งคํ์ ํตํด ์ํฐํฐ ํด๋์ค ๊ฐ์ฒด ์์ ํฌํจ๋ ์ ๋ณด๋ฅผ ํ ์ด๋ธ์ ์ ์ฅํ๋ ๊ธฐ์
- JPA์์๋ ํ ์ด๋ธ๊ณผ ๋งคํ๋๋ ์ํฐํฐ ๊ฐ์ฒด์ ๋ณด๋ฅผ ์์์ฑ ์ปจํ ์คํธ์ ๋ณด๊ดํด์ ์ ํ๋ฆฌ์ผ์ด์ ๋ด์ ์ค๋ ์ง์๋๋๋ก ํจ.
-
์์์ฑ ์ปจํ ์คํธ์๋ 1์ฐจ ์บ์์ ์ฐ๊ธฐ์ง์ฐ SQL ์ ์ฅ์์ ์์ญ์ด ์์.
์์์ฑ ์ปจํ ์คํธ์ EntityManger
-
์ํฐํฐ ํด๋์ค ์์ฑ
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
import lombok.Getter; import javax.persistence.*; @Getter @Setter @NoArgsConstructor @Entity //(1) public class Member { @Id // (2) @GeneratedValue // (3) private Long memberId; private String email; public Member(String email) { this.email = email; } }
(1) JPA ์ํฐํฐ๋ก ์ฌ์ฉโ
members
๋ผ๋ ํ ์ด๋ธ์ ๋งคํ๋จ(2) ์ํฐํฐ์ ๊ธฐ๋ณธ ํค
(3)
@GeneratedValue
์ด๋ ธํ ์ด์ ์ ๊ธฐ๋ณธ ํค ๊ฐ์ด ์๋์ผ๋ก ์์ฑ๋จ -
์์์ฑ ์ปจํ ์คํธ ๊ด๋ จ JPA API
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
@Configuration public class JpaBasicConfig { private EntityManager em; private EntityTransaction tx; @Bean public CommandLineRunner testJpaBasicRunner(EntityManagerFactory emFactory) { this.em = emFactory.createEntityManager(); this.tx = em.getTransaction(); return args -> { Member member = new Member("hgd@gmail.com"); em.persist(member); //์์์ฑ ์ปจํ ์คํธ์ member ๊ฐ์ฒด์ ์ ๋ณด๋ค์ด ์ ์ฅ tx.commit(); Member resultMember = em.find(Member.class, 1L); System.out.println("Id: " + resultMember.getMemberId() + ", email: " + resultMember.getEmail()); }; }
- EntityManger
- JPA์ ์์์ฑ ์ปจํ ์คํธ๋ EntityManager ํด๋์ค์ ์ํด์ ๊ด๋ฆฌ๋๋ค.
- EntityManager ํด๋์ค์ ๊ฐ์ฒด๋ (1)๊ณผ ๊ฐ์ด EntityManagerFactory ๊ฐ์ฒด๋ฅผ Spring์ผ๋ก๋ถํฐ DI ๋ฐ์
- EntityManagerFactory์ createEntityManager() ๋ฉ์๋๋ฅผ ์ด์ฉํด์ EntityManager ํด๋์ค์ ๊ฐ์ฒด๋ฅผ ์ป์ ์ ์๋ค.
- createEntityManager๋ @Entity ๋ถ์ ํด๋์ค๋ฅผ ๋ฐ์ดํฐ๋ฒ ์ด์ค ํ ์ด๋ธ๋ก ์๋์ผ๋ก ๋งคํ๋๊ณ , ์ ํ๋ฆฌ์ผ์ด์ ์์ ์์ ์ ํ ์ด๋ธ์ด ์์ฑ์์ผ์ค.
- hibernate.hbm2ddl.auto ์์ฑ์ ๋ฐ๋ฆ. โ ์์ ๋ create๊ฐ ์ ์ฉ๋์ด ์์.
create
: ์ ํ๋ฆฌ์ผ์ด์ ์ด ์คํ๋ ๋ ๊ธฐ์กด ํ ์ด๋ธ์ ์ญ์ ํ๊ณ ์๋ก ์์ฑcreate-drop
:create
์ ๋์ผํ์ง๋ง, ์ ํ๋ฆฌ์ผ์ด์ ์ด ์ข ๋ฃ๋ ๋ ํ ์ด๋ธ์ ์ญ์ ํจupdate
: ๊ธฐ์กด ํ ์ด๋ธ์ ์ ์งํ๋ฉฐ ํ์ํ ๊ฒฝ์ฐ ํ ์ด๋ธ ๊ตฌ์กฐ๋ฅผ ์ ๋ฐ์ดํธ ํจvalidate
: ํ ์ด๋ธ์ด ์กด์ฌํ๋์ง ํ์ธ ํ ๋งคํ ์ ๋ณด๊ฐ ์ผ์นํ๋์ง ๊ฒ์ฆ, ๋ณ๊ฒฝ์ ์ํํ์ง ์์none
: ์๋ฌด๋ฐ ๋์๋ ํ์ง ์์
- Transaction์ ์์ํ๊ธฐ ์ํด์ tx.begin() ๋ฉ์๋๋ฅผ ๋จผ์ ํธ์ถ
- find() : ์กฐํ ๊ธฐ๋ฅ , commit ๋๋ฉด Select ์ฟผ๋ฆฌ ๋ ๋ฆผ
- ์ฒซ ๋ฒ์งธ ํ๋ผ๋ฏธํฐ : ์กฐํํ ์ํฐํฐ ํด๋์ค์ ํ์
- ๋ ๋ฒ์งธ ํ๋ผ๋ฏธํฐ : ์กฐํํ ์ํฐํฐ ํด๋์ค์ ์๋ณ์ ๊ฐ
- em.persist() : ์ํฐํฐ ๊ฐ์ฒด๋ฅผ ์์์ฑ ์ปจํ ์คํธ์ ์ ์ฅ
- em.flush() : ์์์ฑ ์ปจํ ์คํธ์ ๋ณ๊ฒฝ ์ฌํญ์ ํ ์ด๋ธ์ ๋ฐ์ โ tx.commit()์ด ํธ์ถ๋๋ฉด ๋ด๋ถ์ ์ผ๋ก em.flush()๊ฐ ํธ์ถ๋จ.
- tx.commit() : ์์์ฑ ์ปจํ ์คํธ์ ์ ์ฅ๋์ด ์๋ member ๊ฐ์ฒด๋ฅผ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ํ ์ด๋ธ์ ์ ์ฅ
1์ฐจ ์บ์์ ์ฐ๊ธฐ์ง์ฐ SQL ์ ์ฅ์
-
Entity Create, Insert, Select
- ์ ํ๋ฆฌ์ผ์ด์
์ด ์์๋๋ฉด์ hibernate.hbm2ddl.auto : create ์์ฑ์ ๋ฐ๋ผ ๊ธฐ์กด ํ
์ด๋ธ์ ์ญ์ ํ๊ณ ์๋ก ์์ฑํจ
(@Entity ๊ฐ ๋ถ์ ํด๋์ค๋ฅผ ํ ์ด๋ธ๋ก ๋ง๋ค์ด์ค๋ค) -
๋ถํ๋ฐ์ค์ em.persist(member); โ ์ฌ๊ธฐ์ member๊ฐ 1์ฐจ ์บ์์ ์ ์ฅ๋๊ณ ์ฐ๊ธฐ์ง์ฐ์ ์ฅ์์ insert์ฟผ๋ฆฌ๊ฐ ์ ์ฅ๋๊ณ (์์์ฑ์ปจํ ์คํธ์ ์ ์ฅ)
-
์๋ซ์ค์ tx.commit();์ด ์คํ๋๋ฉด ์ฟผ๋ฆฌ๋ฌธ์ด ์คํ๋๊ณ DB์ ์ ์ฅ๋จ.
์ฐ๊ธฐ์ง์ฐ์ ์ฅ์์๋ ์ฟผ๋ฆฌ๋ฌธ์ด ์คํ๋์ด ์ฌ๋ผ์ง๊ณ 1์ฐจ์บ์์ ์๋ member๋ ๋จ์์์
- Member result =em.find(Member.class, 1L);
์์ 1์ฐจ ์บ์์ member๊ฐ ์กด์ฌํ๊ธฐ ๋๋ฌธ์ select ์ฟผ๋ฆฌ๋ฅผ ๋ ๋ฆฌ์ง ์์๋ ์กฐํ ๊ฐ๋ฅ โ ์ฝ์์ ์ถ๋ ฅ๋ ์ ๋จ. - ๊ทธ๋ฌ๋ member_Id๊ฐ 2์ธ ๊ฐ์ฒด๋ 1์ฐจ ์บ์์ ์์ผ๋ฏ๋ก select ์ฟผ๋ฆฌ๋ฅผ ๋ ๋ ค์ DB๋ฅผ ์กฐํ ํ๊ณ ์๊ธฐ ๋๋ฌธ์ null ์ด ๋ง์.
- ์ ํ๋ฆฌ์ผ์ด์
์ด ์์๋๋ฉด์ hibernate.hbm2ddl.auto : create ์์ฑ์ ๋ฐ๋ผ ๊ธฐ์กด ํ
์ด๋ธ์ ์ญ์ ํ๊ณ ์๋ก ์์ฑํจ
-
์ํฐํฐ ์ ๋ฐ์ดํธ
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
private void example(){ tx.begin(); em.persist(new Member("jerry5@gmail.com")); // 1์ฐจ ์บ์์ ๋ณด๊ด - snapshot ์ฐ์ด์ ๋ณด๊ด tx.commit(); //commit ํ๋ ์๊ฐ ๊ฐ์ฒด์ ๋ณด๊ฐ ๋ฌ๋ผ์ก๋์ง ๋น๊ต ํจ // ์ฃผ์๊ฐ ๊ณต์ ํด์ ์บ์์ DB๊ฐ ๋ง์ง ์์ผ๋ฉด ์ ๋ฐ์ดํธ๊ฐ ์ถ๊ฐ ๋๊ณ commit์ ์ฟผ๋ฆฌ๊ฐ ์คํ๋จ. //๋ค์ transaction ์์ฑ tx.begin(); Member member1 =em.find(Member.class,1L); //์์์ ์์ฑ๋ ๋ฉค๋ฒ๋ฅผ ๊ฐ์ ธ์ด. -> 1์ฐจ ์บ์์์ ์กฐํ member1.setEmail("jerry5@yahoo.co.kr"); //๋ถ๋ฌ์จ ๊ฐ์ฒด(1์ฐจ์บ์์ ์๋)๋ฅผ ๋ฐ๊ฟ. // ์ด๋ฏธ ์ด์ ์ ์ฐ์ด๋๊ณ ๋ณ๊ฒฝ์ฌํญ์ด ์์ผ๋ฉด ์ฐ๊ธฐ์ง์ฐ์ ์ฅ์์ ์ฟผ๋ฆฌ๋ฑ๋ก //update ์คํ๋จ.(JPA๊ฐ ์์์ ๋ณ๊ฒฝ์ฌํญ์ ์ถ์ ํ์ฌ update ์ฟผ๋ฆฌ ๋ ๋ ค์ค) }
-
์ํฐํฐ ์ญ์
- select ์ฟผ๋ฆฌ๋ 1์ฐจ ์บ์์ ์ด๋ฏธ ์กด์ฌํ๊ธฐ ๋๋ฌธ์ ๋๊ฐ์ง ์์.
- remove ํ๋ฉด 1์ฐจ ์บ์๋ฅผ ์ง์ฐ์ง๋ง ์ฌ๋ผ์ก๋ค๋ ์ํ๋ ๋ณด๊ดํจ.
- tx.commit()์ ์คํํ๋ฉด ์์์ฑ ์ปจํ ์คํธ์ 1์ฐจ ์บ์์ ์๋ ์ํฐํฐ๋ฅผ ์ ๊ฑฐํ๊ณ , ์ฐ๊ธฐ ์ง์ฐ SQL ์ ์ฅ์์ ๋ฑ๋ก๋ DELETE ์ฟผ๋ฆฌ๊ฐ ์คํ
- tx๋ฅผ ์ปค๋ฐํ ๋ ํ๋ฌ์๋ฅผ ๊ฐ์ ๋ก ๋ฐ์์ํด. โ ์ปค๋ฅ์ ํ ๋ด๋น ํ์นด๋ฆฌ ํ
์ํฐํฐ๋งคํ
์ํฐํฐ์ ํ ์ด๋ธ
- @Entity
- ์ํฐํฐ ํด๋์ค์ ํ ์ด๋ธ์ ๋งคํ
- attribute
- name: ์ํฐํฐ์ ์ด๋ฆ ์ค์ ๊ฐ๋ฅ, ์ฐธ๊ณ ๋ก ์ด๋ฆ์ด ์ค๋ณต๋๋ ํด๋์ค๊ฐ ์์ผ๋ฉด ์ ๋ ์๋จ!
- @Table
- ์ฃผ๋ก ํ ์ด๋ธ ์ด๋ฆ์ด ํด๋์ค ์ด๋ฆ๊ณผ ๋ฌ๋ผ์ผ ํ ๊ฒฝ์ฐ์ ์ถ๊ฐ
- name attribute๋ก ํ ์ด๋ธ ์ด๋ฆ ์ค์ ๊ฐ๋ฅ.
@Table
์ ๋ํ ์ด์ ์ ์ต์ ์ด๋ฉฐ, ์ถ๊ฐํ์ง ์์ ๊ฒฝ์ฐ ํด๋์ค ์ด๋ฆ์ ํ ์ด๋ธ ์ด๋ฆ์ผ๋ก ์ฌ์ฉ
- ์ฃผ์์ฌํญ
@Entity
์ ๋ํ ์ด์ ๊ณผ@Id
์ ๋ํ ์ด์ ์ ํ์-
ํ๋ผ๋ฏธํฐ๊ฐ ์๋ ๊ธฐ๋ณธ ์์ฑ์๋ ํ์๋ก ์ถ๊ฐ
โ ์์ฑ์๊ฐ ์์๋๋ ๊ธฐ๋ณธ ์์ฑ์๊ฐ ์๋์ผ๋ก ์์ฑ๋์ง๋ง ๊ทธ๋ ์ง ์์ ๊ฒฝ์ฐ์๋ ๊ธฐ๋ณธ ์์ฑ์๊ฐ ํ์๋ก ์์ด์ผ ํ๋ฏ๋ก ์ต๊ด์ ์ผ๋ก ๊ธฐ๋ณธ ์์ฑ์ ์ถ๊ฐํ๊ธฐ.
- ํ ์ด๋ธ ์ด๋ฆ์ ๋ฐ๋ก ๋ฐ๊ฟ ํ์๊ฐ ์๋ ๊ฒฝ์ฐ์๋ ํด๋์ค ์ด๋ฆ์ผ๋ก ์ฌ์ฉํ๋ ๊ฒ์ ๊ถ์ฅ.
๊ธฐ๋ณธํค ๋งคํ
@ID ์ ๋ํ ์ด์ ์ ์ถ๊ฐํ ํ๋๊ฐ ๊ธฐ๋ณธ ํค ์ด์ด ๋๋๋ฐ JPA์์๋ ๊ธฐ๋ณธ ํค๋ฅผ ์ด๋ค ๋ฐฉ์์ผ๋ก ์์ฑํด์ค์ง ๋ค์ํ ์ ๋ต์ ์ง์
- IDENTITY
- @GeneratedValue(strategy = GenerationType.IDENTITY
- ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ๊ธฐ๋ณธ ํค ๋์ ์์ฑ
- Ex) MySQL์ AUTO_INCREMENT ๊ธฐ๋ฅ
- SEQUENCE
- @GeneratedValue(strategy = GenerationType.SEQUENCE)
- ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ์ ๊ณตํ๋ ์ํ์ค๋ฅผ ์ฌ์ฉํด์ ๊ธฐ๋ณธ ํค๋ฅผ ์์ฑํ๋ ์ ๋ต
- TABLE
- ๋ณ๋์ ํค ์์ฑ ํ ์ด๋ธ์ ์ฌ์ฉํ๋ ์ ๋ต
- AUTO
- @GeneratedValue(strategy =
GenerationType.AUTO
- JPA๊ฐ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ Dialect์ ๋ฐ๋ผ์ ์ ์ ํ ์ ๋ต์ ์๋์ผ๋ก ์ ํ
- @GeneratedValue(strategy =
ํ๋(๋ฉค๋ฒ๋ณ์)์ Column ๊ฐ์ ๋งคํ
Annotation
annotation | Description |
---|---|
@Column | ์ด ๋งคํ |
@Temporal | ๋ ์ง ํ์ ๋งคํ |
LocalDateTime ํ์ ์ผ ๊ฒฝ์ฐ, @Temporal ์ ๋ํ ์ด์ ์ ์๋ต ๊ฐ๋ฅ(LocalDateTime์ ์ด์ TIMESTAMP ํ์ ๊ณผ ๋งคํ) | ย |
@Enumerated | enum ํ์ ๋งคํ |
@Lob | BLOB, CLOB ๋งคํ |
@Transient | ํน์ ํ๋๋ฅผ ์ปฌ๋ผ์ ๋งคํํ์ง ์์ (๋งคํ ๋ฌด์) |
์์ ๋ฐ์ดํฐ๋ฅผ ๋ฉ๋ชจ๋ฆฌ์์ ์ฌ์ฉํ๊ธฐ ์ํ ์ฉ๋๋ก ์ฌ์ฉ | ย |
attribute
์์ฑ | ๊ธฐ๋ณธ๊ฐ | Description |
---|---|---|
updatable | true | ์์ ์ฌ๋ถ ์ง์ |
nullable(DDL) | true | null ๊ฐ์ ํ์ฉ์ฌ๋ถ ์ค์ |
false ์ค์ ์ DDL ์์ฑ์์ NOT NULL ์ ์ฝ์กฐ๊ฑด ๋ถ์ | ย | ย |
columnDefinition(DDL) | ย | @Table์ uniqueConstraints์ ๊ฐ์ง๋ง ํ ์ปฌ๋ผ์ ๊ฐ๋จํ ์ ๋ํฌ ์ ์ฝ์กฐ๊ฑด์ ๊ฑธ ๋ ์ฌ์ฉ |
length(DDL) | 255 | ์ด์ ์ ์ฅํ ์ ์๋ ๋ฌธ์ ๊ธธ์ด |
unique | false | ๊ณ ์ ํ ๊ฐ๋ง, ์ค๋ณต ๋ถ๊ฐ |
ย | ย | ย |
์ ํธ๋ฆฌ๋ทฐํธ๊ฐ ๊ธฐ๋ณธ๊ฐ์ ์ฌ์ฉํ ๊ฒฝ์ฐ ์ฃผ์ ์ฌํญ
@Column
์ ๋ํ ์ด์ ์ด ์๋ต๋๋ฉด ๊ธฐ๋ณธ์ ์ผ๋กnullable=true ์.
int price not null
์ผ ๊ฒฝ์ฐ์๋@Column(nullable=false)
๋ผ๊ณ ๋ช ์์ ์ผ๋ก ์ง์ ํด์ผ ํจ.
@Enumerated
์ ๋ํ
์ด์
์ ์๋์ ๋ ๊ฐ์ง ํ์
EnumType.ORDINAL
: enum์ ์์๋ฅผ ๋ํ๋ด๋ ์ซ์๋ฅผ ํ ์ด๋ธ์ ์ ์ฅ โ ์์๊ฐ ์ผ์นํ์ง ์๊ฒ ๋๋ ๋ฌธ์ ๊ฐ ๋ฐ์EnumType.STRING
: enum์ ์ด๋ฆ์ ํ ์ด๋ธ์ ์ ์ฅEnumType.STRING
์ ์ฌ์ฉํ๋ ๊ฒ์ ๊ถ์ฅ-
์์
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
public enum Day { SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY } @Entity public class Event { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Enumerated(EnumType.ORDINAL) private Day day; // getters and setters }
Enum ์์ ๋ณ๊ฒฝ
1 2
public enum Day { MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY}
0์ MONDAY๋ฅผ, 1์ TUESDAY๋ฅผ ์๋ฏธํ๊ฒ ๋์ด ์๋ชป๋ ์ฐธ์กฐ๊ฐ ๋ฐ์
์ํฐํฐ๊ฐ์ ์ฐ๊ด๊ด๊ณ ๋งคํ
์ํฐํฐ ํด๋์ค ๊ฐ์ ๊ด๊ณ๋ฅผ ๋ง๋ค์ด์ฃผ๋ ๊ฒ์ด ๋ฐ๋ก ์ฐ๊ด ๊ด๊ณ ๋งคํ
๋ฐฉํฅ (๋จ๋ฐฉํฅ/์๋ฐฉํฅ)
-
๋จ๋ฐฉํฅ ์ฐ๊ด ๊ด๊ณ
ํ์ชฝ ํด๋์ค๋ง ๋ค๋ฅธ ์ชฝ ํด๋์ค์ ์ฐธ์กฐ ์ ๋ณด๋ฅผ ๊ฐ์ง๊ณ ์๋ ๊ด๊ณ๋ฅผ ๋จ๋ฐฉํฅ ์ฐ๊ด ๊ด๊ณ
- Member ํด๋์ค๊ฐ Order ๊ฐ์ฒด๋ฅผ ์์๋ก ํฌํจํ๊ณ ์๋ List ๊ฐ์ฒด๋ฅผ ๊ฐ์ง๊ณ ์์ผ๋ฏ๋ก, Order๋ฅผ ์ฐธ์กฐ
- Order ์ ์ฅ์์๋ Member ์ ๋ณด๋ฅผ ์ ์ ์์
-
์๋ฐฉํฅ ์ฐ๊ด ๊ด๊ณ
์์ชฝ ํด๋์ค๊ฐ ์๋ก์ ์ฐธ์กฐ ์ ๋ณด๋ฅผ ๊ฐ์ง๊ณ ์๋ ๊ด๊ณ๋ฅผ ์๋ฐฉํฅ ์ฐ๊ด ๊ด๊ณ
์๋ก ๋ค๋ฅธ ๋จ๋ฐฉํฅ ๊ด๊ณ 2๊ฐ์.- ๋ ํด๋์ค๊ฐ ๋ชจ๋ ์๋ก์ ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ ์ ์์ผ๋ฏ๋ก, Member๋ Order ์ ๋ณด๋ฅผ ์ ์ ์๊ณ , Order๋ Member ์ ๋ณด๋ฅผ ์ ์ ์์
-
JPA๋ ๋จ๋ฐฉํฅ ์ฐ๊ด ๊ด๊ณ์ ์๋ฐฉํฅ ์ฐ๊ด ๊ด๊ณ๋ฅผ ๋ชจ๋ ์ง์ํ๋ ๋ฐ๋ฉด์ Spring Data JDBC๋ ๋จ๋ฐฉํฅ ์ฐ๊ด ๊ด๊ณ๋ง ์ง์
๋ค์ค์ฑ(๋ค๋์ผ/์ผ๋๋ค/์ผ๋์ผ/๋ค๋๋ค)
๋ค๋์ผ[N:1] : @ManyToOne
-
๋ค๋์ผ ๋จ๋ฐฉํฅ : ๊ฐ์ฅ ๋ง์ด ์ฌ์ฉ, ๋ค(N)์ ํด๋นํ๋ ํด๋์ค๊ฐ ์ผ(1)์ ํด๋นํ๋ ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ ์ ์๋ ๊ด๊ณ๋ฅผ ์๋ฏธ
- Order๋ง Member ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ ์ ์์ผ๋ฏ๋ก ๋จ๋ฐฉํฅ ๊ด๊ณ
-
์์
1 2 3 4 5 6 7 8 9 10 11 12 13
@NoArgsConstructor @Getter @Setter @Entity(name = "ORDERS") public class Order { ... @ManyToOne // (1) @JoinColumn(name = "MEMBER_ID") // (2) private Member member; public void addMember(Member member) { this.member = member; }
(1)
@ManyToOne
์ ๋ํ ์ด์ ์ผ๋ก ๋ค๋์ผ์ ๊ด๊ณ๋ฅผ ๋ช ์(2)
@JoinColumn
์ ๋ํ ์ด์ ์ผ๋ก ์ธ๋ ํค์ ํด๋นํ๋ ์ด ์ด๋ฆ ์์ฑ- MEMBER ํ
์ด๋ธ์ ๊ธฐ๋ณธํค ์ด ์ด๋ฆ์ด โ
MEMBER_ID
โ ์ด๊ธฐ ๋๋ฌธ์ ๋์ผํ๊ฒ ์์ฑ
- MEMBER ํ
์ด๋ธ์ ๊ธฐ๋ณธํค ์ด ์ด๋ฆ์ด โ
-
์์ ) ๋ค๋์ผ์์ ์ผ๋๋ค๋ฅผ ์ถ๊ฐํด์ผ ํ๋ ๊ฒฝ์ฐ
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
tx.begin(); Member member = new Member("hgd@gmail.com", "Hong Gil Dong", "010-1111-1111"); em.persist(member); Order order = new Order(); order.addMember(member); // (2) em.persist(order); // (3) tx.commit(); // (4) Order findOrder = em.find(Order.class, 1L); // (5) ์ฃผ๋ฌธ์ ํด๋นํ๋ ํ์ ์ ๋ณด๋ฅผ ๊ฐ์ ธ์ฌ ์ ์๋ค. System.out.println("findOrder: " + findOrder.getMember().getMemberId() + ", " + findOrder.getMember().getEmail());
(2) order ๊ฐ์ฒด์ member ๊ฐ์ฒด๋ฅผ ์ถ๊ฐ, member ๊ฐ์ฒด๋ ์ด MEMBER_ID ๊ฐ์ ์ธ๋ํค์ ์ญํ
(3) ์์ ์ฃผ๋ฌธ ์ ๋ณด๋ฅผ ์ ์ฅ
(4) ๋ฑ๋กํ ํ์์ ํด๋นํ๋ ์ฃผ๋ฌธ ์ ๋ณด๋ฅผ ์กฐํ
(5)
findOrder.getMember()
์ ๊ฐ์ด ์ฃผ๋ฌธ์ ํด๋นํ๋ ํ์ ์ ๋ณด๋ฅผ ๊ฐ์ ธ์์ ์ถ๋ ฅโ๏ธ๊ทธ๋ฌ๋ ๋ด๊ฐ ์ฃผ๋ฌธํ ์ฃผ๋ฌธ ์ ๋ณด๋ ์กฐํํ ์ ์์ โ ์ผ๋๋ค ๋งคํ์ ์ถ๊ฐํด ์๋ฐฉํฅ ๊ด๊ณ ๋ง๋ค์ด์ผ ํจ.
-
๋ค๋์ผ ์๋ฐฉํฅ
- ์์ชฝ์ ์๋ก ์ฐธ์กฐ, ๋ค ์ ํด๋นํ๋ ์ชฝ์ด ๊ฐ์ฒด, ์ผ์ ํด๋นํ๋ ์ชฝ์ด List
- @ManyToOne
@JoinColumn(name = โMEMBER_IDโ) - @OneToMany(mappedBy = โmemberโ)
- @ManyToOne
- ๋ง์ฝ์ ์๋ก์ด ์ฃผ๋ฌธ์ด ๋ฐ์ํ๋ฉด ๋ค๋์ผ ์๋ฐฉํฅ์์๋ ์๋ก ์ฐธ์กฐํ๊ณ ์์ผ๋ ์๋ก๋ฅผ update ํด์ฃผ์ด์ผ ํจ.
-
์์ชฝ์ add ๋ฉ์๋ ์์ฑํ commit ํ๋ฉด StackOverFlow ๋ฐ์ - ์๋ก๊ฐ ์๋ก๋ฅผ ํธ์ถํ๊ธฐ ๋๋ฌธ โ ์ข ๋ฃ์์ ํ์
-
์ด๋ ๊ฒ ํด์ฃผ์ด์ผ ํจ!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
public void addOrder(Order order) { orders.add(order); // Order ๊ฐ์ฒด๋ฅผ orders ๋ฆฌ์คํธ์ ์ถ๊ฐ // Order ๊ฐ์ฒด์ member ํ๋๊ฐ ํ์ฌ Member ๊ฐ์ฒด(this)๋ฅผ ๊ฐ๋ฆฌํค์ง ์๋ ๊ฒฝ์ฐ if (order.getMember() != this) { order.addMember(this); // Order ๊ฐ์ฒด์ member ํ๋๋ฅผ ํ์ฌ Member ๊ฐ์ฒด(this)๋ก ์ค์ } } public void addMember(Member member){ this.member = member; // Order ๊ฐ์ฒด์ member ํ๋๋ฅผ ์ฃผ์ด์ง Member ๊ฐ์ฒด๋ก ์ค // Member ๊ฐ์ฒด์ orders ๋ฆฌ์คํธ์ ํ์ฌ Order ๊ฐ์ฒด(this)๊ฐ ํฌํจ๋์ง ์์ ๊ฒฝ์ฐ if (!member.getOrders().contains(this)) { member.addOrder(this); // Member ๊ฐ์ฒด์ orders ๋ฆฌ์คํธ์ ํ์ฌ Order ๊ฐ์ฒด(this)๋ฅผ ์ถ๊ฐ } }
์๋ก์ด ์ฃผ๋ฌธ์ ํ๋๋ฐ ์ฃผ๋ฌธ๋ชฉ๋ก์ ๋ฉค๋ฒ๊ฐ ์๋ค๋ฉด ํ์ฌ ๋ฉค๋ฒ๋ฅผ ์ถ๊ฐ
๋ฉค๋ฒ์ ์ฃผ๋ฌธ๋ชฉ๋ก์ ์๋ก์ด ์ฃผ๋ฌธ์ด ๋ฑ๋ก๋์ง ์์๋ค๋ฉด ์๋ก์ด ์ฃผ๋ฌธ์ ์ถ๊ฐ.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
tx.begin(); Member member = new Member("hgd@gmail.com", "Hong Gil Dong", "010-1111-1111"); Order order = new Order(); member.addOrder(order); // (1) order.addMember(member); // (2) em.persist(member); // (3) ํ์์ ๋ณด ์ ์ฅ em.persist(order); // (4) ์ฃผ๋ฌธ์ ๋ณด ์ ์ฅ tx.commit(); // (5) 1์ฐจ ์บ์์์ ์กฐํ Member findMember = em.find(Member.class, 1L); // (6) ์ด์ ์ฃผ๋ฌธํ ํ์์ ํ์ ์ ๋ณด๋ฅผ ํตํด ์ฃผ๋ฌธ ์ ๋ณด๋ฅผ ๊ฐ์ ธ์ฌ ์ ์๋ค. findMember .getOrders() .stream() .forEach(findOrder -> { System.out.println("findOrder: " + findOrder.getOrderId() + ", " + findOrder.getOrderStatus()); });
(1) member์ order๋ฅผ ์ถ๊ฐํ์ง ์์๋ ํ ์ด๋ธ์ order ์๋ ์ ์ฅ๋จ.
But, order๋ฅผ ์กฐํํ ์ ์์, 1์ฐจ ์บ์์ ์ ์ฅ๋ member๋ order๋ฅผ ๊ฐ์ง๊ณ ์์ง ์๊ธฐ ๋๋ฌธ
(2) order ๊ฐ์ฒด์ member ๊ฐ์ฒด๋ฅผ ์ถ๊ฐ, member๊ฐ order์ ์ธ๋ํค ์ญํ ์ ํ๊ธฐ ๋๋ฌธ์ order ๊ฐ์ฒด ์ ์ฅ ์, ๋ฐ๋์ ํ์ โ ํ์ง ์์ผ๋ฉด ์ฃผ๋ฌธ์ ๋ณด์ MEBER_ID ๋ Null์ด ๋จ.
- ์์ชฝ์ ์๋ก ์ฐธ์กฐ, ๋ค ์ ํด๋นํ๋ ์ชฝ์ด ๊ฐ์ฒด, ์ผ์ ํด๋นํ๋ ์ชฝ์ด List
์ผ๋๋ค[1:N] : @OneToMany
-
์ผ๋๋ค ๋จ๋ฐฉํฅ ์ฐ๊ด๊ด๊ณ
์ผ(1)์ ํด๋นํ๋ ํด๋์ค๊ฐ ๋ค(N)์ ํด๋นํ๋ ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ ์ ์๋ ๊ด๊ณ๋ฅผ ์๋ฏธ
- Member๋ง List
๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ ์ ์์ผ๋ฏ๋ก ๋จ๋ฐฉํฅ ๊ด๊ณ - ์ํฐํฐ๊ฐ ๊ด๋ฆฌํ๋ ์ธ๋ ํค๊ฐ ๋ค๋ฅธ ํ ์ด๋ธ์ ์์
- Order ํด๋์ค์ ์ ๋ณด๋ฅผ ํ ์ด๋ธ์ ์ ์ฅํ๋๋ผ๋ ์ธ๋ ํค์ ํด๋นํ๋ MEMBER ํด๋์ค์ memberId ๊ฐ์ด ์๋ ์ฑ๋ก ์ ์ฅ๋จ โ ์ด๋ฐ ๋ฌธ์ ์ ๋๋ฌธ์ ์ ์ฌ์ฉํ์ง ์์.
- ๋ค๋์ผ ๋จ๋ฐฉํฅ ๋งคํ์ ๋จผ์ ํ ํ์ ํ์ํ ๊ฒฝ์ฐ, ์ผ๋๋ค ๋จ๋ฐฉํฅ ๋งคํ์ ์ถ๊ฐํด์ ์๋ฐฉํฅ ์ฐ๊ด ๊ด๊ณ๋ฅผ ๋ง๋๋ ๊ฒ์ด ์ผ๋ฐ์
-
์์
1 2 3 4 5 6 7
@Entity public class Member{ ... @OneToMany private List<Order> orders = new ArrayList<>(); ... }
- Member๋ง List
์ผ๋์ผ[1:1] : @OneToOne
- ์ผ๋์ผ์ ๋จ๋ฐฉํฅ ๊ด๊ณ๋ JPA์์ ์ง์ํ์ง ์๋๋ค.
- ๋ค๋์ผ ์๋ฐฉํฅ ๋งคํ ์ฒ๋ผ ๊ตฌํํ๋ฉด ๋๋ค.
๋ค๋๋ค[N:M] : @ManyToMany
- ์ค๋ฌด์์ ๊ฑฐ์ ์ฌ์ฉํ์ง ์์ผ๋ฏ๋ก ์ด๋ฐ๊ฒ ์๋ค ์ ๋๋ง ์ฐธ๊ณ !
Comment
์ค๋ ์ฝ๋ ๋ฐ๋ผ์ง๋ฉด์ Enum์ ์๋ฌด์๊ฐ์์ด enum์ผ๋ก ์ฌ์ฉํ๋๋ฐ ์๋ฌ๊ฐ๋์ ์๊ทธ๋ฐ๊ฐ ํ๋๋
Enum์ ์๋ฐ์์ ์ ๊ณตํ๋ ๊ธฐ๋ณธ ํด๋์ค(java.lang.Enum)์ด๋ฉฐ,
๋ชจ๋ enum ํ์
์ java.lang.Enum ํด๋์ค๋ฅผ ์์๋ฐ์ผ๋, extends๋ฅผ ์ฌ์ฉํ๊ณ ์์ง ์์(์ฌ์ฉ๋ชปํจ)
์๋์ผ๋ก ์ปดํ์ผ๋ฌ๊ฐ extend๋ฅผ ์๋์ผ๋ก ์ถ๊ฐํด์ฃผ๊ธฐ ๋๋ฌธ์ด๋ค!
๊ทธ๋ฆฌ๊ณ ๊ผญ ๊ธฐ์ตํด์ผ ํ ๊ฒ ํ๋ ๋๋ Order๋ Orderby๋ก ์ธ์ํ๋๊น Orders๋ก ํ
์ด๋ธ๋ช
๋ฐ๊ฟ์ค์ผํจ.
๋ค๋ฅธ ๊ฒ ๋ณด๋ค ๋ค๋์ผ ์๋ฐฉํฅ์์ ์์ง ํท๊ฐ๋ ค์ ๋ ๋ด์ผํ ๊ฒ ๊ฐ๋ค..!
Leave a comment