[JPA] JPA (Java Persistence API) ?!
- -
์ค๋์ JPA (Java Persistence API)๋ ๋ฌด์์ธ์ง ํ๋ฒ ์์๋ณด๋ ค๊ณ ํฉ๋๋ค. ์ค๋๋ ๊ทธ๋ผ ๊ฐ์ด ๊ณต๋ถ๋ฅผ ํด๋ณผ๊น์?
#1. JPA ?!
JPA (Java Persistence API)๋ ์๋ฐ์์ ORM(Object-Relational Mapping)์ ์ง์ํ๊ธฐ ์ํ API์ด๋ฉฐ, ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๊ฐ์ฒด ์งํฅ ํ๋ก๊ทธ๋๋ฐ ๊ฐ์ ๋ถ์ผ์น๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํ ๊ธฐ์ ์ ๋๋ค.
JPA์ ๊ธฐ๋ณธ ๋ฌธ๋ฒ ๋ฐ ํ์ฉ ๋ฐฉ๋ฒ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
#2. JPA ๊ธฐ๋ณธ ๋ฌธ๋ฒ
#2. 1. ์ํฐํฐ ํด๋์ค ์์ฑ
JPA๋ ์ํฐํฐ ํด๋์ค๋ฅผ ์ฌ์ฉํ์ฌ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ํ ์ด๋ธ๊ณผ ๋งคํํฉ๋๋ค. ์ํฐํฐ ํด๋์ค๋ ๋ค์๊ณผ ๊ฐ์ ํํ๋ก ์์ฑ๋ฉ๋๋ค.
@Entity
@Table(name = "table_name")
public class EntityName {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "column_name")
private String columnName;
// getter, setter, constructor ๋ฑ
}
- @Entity: ํด๋น ํด๋์ค๊ฐ ์ํฐํฐ์์ ๋ํ๋ ๋๋ค.
- @Table(name = "table_name"): ์ํฐํฐ ํด๋์ค๊ฐ ๋งคํ๋ ํ ์ด๋ธ์ ์ด๋ฆ์ ์ง์ ํฉ๋๋ค.
- @Id: ์ํฐํฐ์ ๊ธฐ๋ณธ ํค(primary key)๋ฅผ ๋ํ๋ ๋๋ค.
- @GeneratedValue(strategy = GenerationType.IDENTITY): ๊ธฐ๋ณธ ํค ๊ฐ์ด ์๋์ผ๋ก ์์ฑ๋๋๋ก ํฉ๋๋ค.
- @Column(name = "column_name"): ํ๋๊ฐ ๋งคํ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค ํ ์ด๋ธ์ ์ปฌ๋ผ๋ช ์ ์ง์ ํฉ๋๋ค.
#2. 2. EntityManager ์์ฑ
EntityManager๋ JPA์์ ๊ฐ์ฅ ์ค์ํ ๊ฐ์ฒด๋ก, ์ํฐํฐ ๊ฐ์ฒด๋ฅผ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ์ฅํ๊ฑฐ๋ ์กฐํํ ๋ ์ฌ์ฉ๋ฉ๋๋ค. EntityManager๋ ๋ค์๊ณผ ๊ฐ์ด ์์ฑํฉ๋๋ค.
EntityManagerFactory emf = Persistence.createEntityManagerFactory("persistence-unit-name");
EntityManager em = emf.createEntityManager();
- Persistence.createEntityManagerFactory("persistence-unit-name"): persistence.xml ํ์ผ์์ ์ ์ํ persistence-unit์ ์ด๋ฆ์ ์ธ์๋ก ์ ๋ฌํ์ฌ EntityManagerFactory๋ฅผ ์์ฑํฉ๋๋ค.
- emf.createEntityManager(): EntityManagerFactory๋ฅผ ์ฌ์ฉํ์ฌ EntityManager๋ฅผ ์์ฑํฉ๋๋ค.
#2. 3. ์ํฐํฐ ์ ์ฅ
EntityManager๋ฅผ ์ฌ์ฉํ์ฌ ์ํฐํฐ๋ฅผ ์ ์ฅํ๋ ๋ฐฉ๋ฒ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
EntityTransaction tx = em.getTransaction();
tx.begin();
em.persist(entity);
tx.commit();
- em.getTransaction(): ํ์ฌ EntityManager์ EntityTransaction์ ๋ฐํํฉ๋๋ค.
- tx.begin(): ํธ๋์ญ์ ์ ์์ํฉ๋๋ค.
- em.persist(entity): ์ํฐํฐ๋ฅผ ์ ์ฅํฉ๋๋ค.
- tx.commit(): ํธ๋์ญ์ ์ ์ปค๋ฐํฉ๋๋ค.
#2. 4. ์ํฐํฐ ์กฐํ
EntityManager๋ฅผ ์ฌ์ฉํ์ฌ ์ํฐํฐ๋ฅผ ์กฐํํ๋ ๋ฐฉ๋ฒ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
EntityTransaction tx = em.getTransaction();
tx.begin();
EntityName entity = em.find(EntityName.class, id);
tx.commit();
- em.find(EntityName.class, id): ์ํฐํฐ ํด๋์ค์ ๊ธฐ๋ณธ ํค ๊ฐ์ ์ ๋ฌํ์ฌ ์ํฐํฐ๋ฅผ ์กฐํํฉ๋๋ค.
#2. 5. ์ํฐํฐ ์์
EntityManager๋ฅผ ์ฌ์ฉํ์ฌ ์ํฐํฐ๋ฅผ ์์ ํ๋ ๋ฐฉ๋ฒ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
EntityTransaction tx = em.getTransaction();
tx.begin();
EntityName entity = em.find(EntityName.class, id);
entity.setColumnName("new value");
tx.commit();
- em.find(EntityName.class, id): ์์ ํ ์ํฐํฐ๋ฅผ ์กฐํํฉ๋๋ค.
- entity.setColumnName("new value"): ํ๋ ๊ฐ์ ๋ณ๊ฒฝํฉ๋๋ค.
- ๋ณ๊ฒฝ๋ ์ํฐํฐ๋ ํธ๋์ญ์ ์ ์ปค๋ฐํ ๋ ์๋์ผ๋ก ์ ๋ฐ์ดํธ๋ฉ๋๋ค.
#2. 6. ์ํฐํฐ ์ญ์
EntityManager๋ฅผ ์ฌ์ฉํ์ฌ ์ํฐํฐ๋ฅผ ์ญ์ ํ๋ ๋ฐฉ๋ฒ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
EntityTransaction tx = em.getTransaction();
tx.begin();
EntityName entity = em.find(EntityName.class, id);
em.remove(entity);
tx.commit();
- em.remove(entity): ์ํฐํฐ๋ฅผ ์ญ์ ํฉ๋๋ค.
#3. JPA ํ์ฉ ๋ฐฉ๋ฒ
JPA๋ฅผ ํ์ฉํ์ฌ ๋ณต์กํ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ์ฐ์ ๊ฐ๋จํ๊ฒ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค.
#3. 1. ๊ฐ์ฒด ๊ทธ๋ํ ํ์
JPA๋ ์ํฐํฐ ํด๋์ค์ ๊ด๊ณ๋ฅผ ์๋์ผ๋ก ๋งคํํฉ๋๋ค. ๋ฐ๋ผ์ ๊ฐ์ฒด ๊ทธ๋ํ๋ฅผ ํ์ํ๋ ๊ฒ๋ ๊ฐ๋จํฉ๋๋ค.
EntityName entity = em.find(EntityName.class, id);
entity.getRelatedEntity().getRelatedField();
#3. 2. JPQL
JPQL (Java Persistence Query Language)์ JPA์์ ์ ๊ณตํ๋ ๊ฐ์ฒด ์งํฅ ์ฟผ๋ฆฌ ์ธ์ด์ ๋๋ค. JPQL์ ์ฌ์ฉํ๋ฉด SQL๊ณผ ์ ์ฌํ ๊ตฌ๋ฌธ์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์กฐํํ ์ ์์ต๋๋ค.
TypedQuery<EntityName> query = em.createQuery("SELECT e FROM EntityName e WHERE e.columnName = :columnName", EntityName.class);
query.setParameter("columnName", "value");
List<EntityName> results = query.getResultList();
- em.createQuery("JPQL", EntityName.class): JPQL์ ์ฌ์ฉํ์ฌ ์กฐํํ ์ํฐํฐ์ ๋ฐํํ ํ์ ์ ์ง์ ํฉ๋๋ค.
- query.setParameter("columnName", "value"): JPQL์์ ์ฌ์ฉํ ํ๋ผ๋ฏธํฐ์ ๊ฐ์ ์ ๋ฌํฉ๋๋ค.
- query.getResultList(): ์กฐํ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํฉ๋๋ค.
#4. ์๋ชป๋ JPA ์ฌ์ฉ๋ฒ
JPA๋ฅผ ์๋ชป ์ฌ์ฉํ๋ฉด ์ฑ๋ฅ ์ ํ๋ ๋ฐ์ดํฐ ๋ถ์ผ์น ๋ฑ์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค.
#4. 1. N+1 ๋ฌธ์
N+1 ๋ฌธ์ ๋ ์ํฐํฐ์ ๊ด๋ จ๋ ๋ค๋ฅธ ์ํฐํฐ๋ฅผ ์ฟผ๋ฆฌํ ๋ ๋ฐ์ํ๋ ๋ฌธ์ ์ ๋๋ค. ์๋ฅผ ๋ค์ด, ๊ฒ์๊ธ ์ํฐํฐ์ ๋๊ธ ์ํฐํฐ๊ฐ ์์ ๋, ๊ฒ์๊ธ์ ์กฐํํ๋ฉด์ ๋๊ธ์ ํจ๊ป ์กฐํํ๋ ๊ฒฝ์ฐ, ๊ฒ์๊ธ์ ๊ฐ์๋งํผ ๋๊ธ ์ฟผ๋ฆฌ๋ฅผ ๋ฐ๋ณตํด์ผ ํ๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํฉ๋๋ค. ์ด ๋ฌธ์ ๋ FetchType.LAZY๋ฅผ ์ฌ์ฉํ์ฌ ํด๊ฒฐํ ์ ์์ต๋๋ค.
#4. 2. Cascade ์ค์ ๋ฌธ์
Cascade๋ ๋ถ๋ชจ ์ํฐํฐ์ ์ฐ๊ด๋ ์์ ์ํฐํฐ์ ์ํ ๋ณํ๋ฅผ ์๋์ผ๋ก ์ ํํ๋ ๊ธฐ๋ฅ์ ๋๋ค. ๊ทธ๋ฌ๋ Cascade๋ฅผ ์ฌ์ฉํ๋ฉด ์ํฐํฐ์ ์ํ ๋ณํ๋ฅผ ์์ธกํ๊ธฐ ์ด๋ ค์์ง๊ธฐ ๋๋ฌธ์ ์ฃผ์ํด์ ์ฌ์ฉํด์ผ ํฉ๋๋ค.
#4. 3. ์ง์ฐ ๋ก๋ฉ(Lazy Loading) ๋ฌธ์
์ง์ฐ ๋ก๋ฉ์ ํ์ํ ์์ ์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ๋ฐฉ์์ ๋๋ค. ํ์ง๋ง ์ง์ฐ ๋ก๋ฉ์ ์ฌ์ฉํ๋ฉด ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๊ธฐ ์ํด ๋งค๋ฒ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ฟผ๋ฆฌ๋ฅผ ์คํํ๋ฏ๋ก ์ฑ๋ฅ์ด ์ ํ๋ ์ ์์ต๋๋ค. ์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด FetchType.EAGER๋ฅผ ์ฌ์ฉํ์ฌ ์ฆ์ ๋ก๋ฉํ๊ฑฐ๋, Batch Size๋ฅผ ์ค์ ํ์ฌ ์ผ๊ด ์ฒ๋ฆฌํ๋ ๋ฐฉ์์ผ๋ก ๊ฐ์ ํ ์ ์์ต๋๋ค.
#4. 4. ์ฑ๋ฅ ๋ฌธ์
JPA๋ ์ ํ๋ฆฌ์ผ์ด์ ๊ณผ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฌ์ด์์ ๋งคํ ์์ ์ ์ํํ๊ธฐ ๋๋ฌธ์ ์ผ๋ถ ์์ ์์๋ SQL ์ง์ ์คํ๋ณด๋ค ์ฑ๋ฅ์ด ๋จ์ด์ง ์ ์์ต๋๋ค. ์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด์๋ ์บ์ ์ค์ ๋ฑ์ ํตํด ์ฑ๋ฅ์ ์ต์ ํํด์ผ ํฉ๋๋ค.
๋ง์น๋ฉฐ..
JPA๋ ORM ๊ธฐ์ ๋ก, ๊ฐ์ฒด๋ฅผ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์๋์ผ๋ก ๋งคํํ๋ ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค. JPA๋ฅผ ์ฌ์ฉํ๋ฉด ๊ฐ๋ฐ์๋ SQL ์ฟผ๋ฆฌ๋ฅผ ์์ฑํ๋ ๋์ ์ํฐํฐ ํด๋์ค๋ฅผ ์กฐ์ํ์ฌ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ์ฐ์ ์ํํ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ JPA๋ฅผ ์๋ชป ์ฌ์ฉํ๋ฉด ์ฑ๋ฅ ์ ํ๋ ๋ฐ์ดํฐ ๋ถ์ผ์น ๋ฑ์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์์ผ๋ฏ๋ก ์ฃผ์ํด์ ์ฌ์ฉํด์ผ ํฉ๋๋ค.
'Back-End > JPA' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Error] JPA Cannot resolve table (0) | 2023.02.04 |
---|
์์คํ ๊ณต๊ฐ ๊ฐ์ฌํฉ๋๋ค. ๐