๋ชฉ์ฐจ
์์ ์ ์งํํ๋ ํ๋ก์ ํธ(Mybatis DTO)๋ฅผ JPA ๋ก ๋ณํํด๋ณด๊ธฐ๋ก ํ๋ค.
์ ์ฒด๋ฅผ ๋ณ๊ฒฝํ๊ธฐ์ ์๊ฐ์ ์ผ๋ก ๋๋ฌด ์ค๋๊ฑธ๋ฆด ๊ฒ ๊ฐ์์๐ฐ
์ฐ์ต์ฐจ์์์ ๊ฐ๋จํ ์กฐํ ๊ตฌ๋ฌธ๋ง ๋ณํ ํด ๋ณผ ๊ฒ์ด๋ค.
์ฐธ๊ณ ์ฉ ERD ์ ๊ธฐ์กด Mapper
1) ๊ธฐ์กด EmployeeDTO ๋ฅผ Entity ๋ก ๋ณ๊ฒฝ
์ด๋ DTO ์์๋ authorityName ์ ์ง์ ๋ฐ์์๋๋ฐ
JPA ์์๋ Authority ๊ฐ์ฒด๋ก ๋ฐ๊ธฐ ๋๋ฌธ์ ์ด ์ ์ ์ฐธ๊ณ ํด์ ์ ๋ถ ์์ ํด์ค์ผํ๋ค.
2) Employee Repository ์์ฑ
- JpaRepository ๋ฅผ ์์ ๋ฐ์ผ๋ฉด , ๊ธฐ๋ณธ CRUD ๋ฉ์๋๊ฐ ์๋์ผ๋ก ์ ๊ณต๋ผ์ ๊ธฐ๋ณธ์ ์ธ crud ๋ ์ปค์คํ ๋ฉ์๋๋ฅผ ์์ฑํ์ง ์์๋ ๋๋ค. ex) findAll() , findByAll() ๋ฑ๋ฑ
์ฌ๊ธฐ์๋ถํฐ๋ ์ปค์คํ ๋ฐฉ์์ ๋ํด์ ์ค๋ช .
- ์ฟผ๋ฆฌ ๋ฉ์๋(Query Methods) ๋ผ๋ ๊ธฐ๋ฅ๋ ์๋๋ฐ, ๋ฉ์๋ ์ด๋ฆ๋ง์ผ๋ก ์๋์ผ๋ก ์ฟผ๋ฆฌ๋ฅผ ์์ฑํ์ฌ ์คํํ ์ ์๋ค. ์ํฐํฐ์ ํ๋ ์ด๋ฆ์ ๊ธฐ์ค์ผ๋ก ๋ฉ์๋ ์ด๋ฆ์ ๊ตฌ์ฑํ๋ฉด ์๋์ผ๋ก JPA ๊ฐ ์ฟผ๋ฆฌ๋ฅผ ์์ฑํด์ฃผ๋ ์๋ฆฌ์ด๋ค.
์ ๋ ฌ์ ์๋์ด์๊ณ ์กฐํ + ํ์ฑํ๋(Y) ๋ ๊ฐ๋ง ๊ฐ์ ธ์จ ์ํ
- @Query ์ ๋ํ ์ด์ ์ ๊ฐ๋ฐ์๊ฐ JPQL(Java Persistence Query Language) ๋๋ ๋ค์ดํฐ๋ธ SQL ์ฟผ๋ฆฌ๋ฅผ ์ง์ ์์ฑํ์ฌ ์ ์ํ ์ ์๊ฒ ํ๋ค.
์ ๋ ฌ์ ์๋์ด์๊ณ ์กฐํ+ ํ์ฑํ๋(Y) + ์ ๋ ฌ๊น์ง ๋ ์ํ (๊ธฐ์กด ์ฟผ๋ฆฌ๋ ๊ฐ์ ๊ธฐ๋ฅ์ ํ๊ฒ ๋จ)
package com.project.tobe.repository;
import com.project.tobe.entity.Employee;
import com.project.tobe.entity.Authority;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Repository;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.criteria.*;
import java.util.List;
@Repository
@Primary
public class EmployeeCustomRepositoryImpl implements EmployeeCustomRepository {
@PersistenceContext
private EntityManager entityManager;
@Override
public List<Employee> findEmployeesByAuthorityOrdered() {
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Employee> cq = cb.createQuery(Employee.class);
Root<Employee> employee = cq.from(Employee.class);
// Authority ์ํฐํฐ์์ Join
Join<Employee, Authority> authority = employee.join("authority", JoinType.INNER);
// authorityGrade์ ๋ํ ์ ๋ ฌ ๊ธฐ์ค
Expression<Object> authorityOrder = cb.selectCase()
.when(cb.equal(authority.get("authorityGrade"), "S"), 1)
.when(cb.equal(authority.get("authorityGrade"), "A"), 2)
.when(cb.equal(authority.get("authorityGrade"), "B"), 3)
.when(cb.equal(authority.get("authorityGrade"), "C"), 4)
.when(cb.equal(authority.get("authorityGrade"), "D"), 5);
// ์ฟผ๋ฆฌ ์์ฑ
cq.select(employee)
.where(cb.equal(employee.get("emplYn"), "Y")) // ์ง์ ์ํ๊ฐ 'Y'์ธ ๊ฒฝ์ฐ๋ง ํํฐ๋ง
.orderBy(cb.asc(authorityOrder)); // authorityGrade์ ๋ฐ๋ฅธ ์ ๋ ฌ
// ์ฟผ๋ฆฌ ์คํ ๋ฐ ๊ฒฐ๊ณผ ๋ฐํ
return entityManager.createQuery(cq).getResultList();
}
}
- Criteria API๋ฅผ ํตํด JPA์์ ๋์ ์ผ๋ก ์ฟผ๋ฆฌ ์์ฑ (์ปค์คํ ๋ ํฌ์งํ ๋ฆฌ) : ์ปค์คํ ๋ ํฌ interface + ๊ตฌํ ํ ๊ธฐ๋ณธ ๋ ํฌ์ interface ๋ฅผ ์์ ๋ฐ๋ ๋ฐฉ์์ด๋ค. ์์์ ์ค๋ช ํ @Query ๋ก๋ ๊ตฌํ์ด ํ๋ ๋ณต์กํ ์ฟผ๋ฆฌ๋ ๋ก์ง์ ๊ตฌํํ ๋ ์ฌ์ฉํ๋ค .
๊ธฐ์กด ์ฟผ๋ฆฌ๋ฌธ๊ณผ ๋์ผํ๊ฒ ์ ๊ฐ์ ธ์ค๋ ๊ฒ์ ํ์ธ ํ ์ ์๋ค.
3) DTO๋ก ์ฌ์ฉ๋๋ ๋ถ๋ถ๋ค์ ์ ๋ถ Entity๋ก ๋ณ๊ฒฝ
- controller
- service
- serviceImpl
repository ์ฌ์ฉ์ ์ํด ์ฃผ์ ์ ํด์ค๋๋ค.
jpa ๋ฉ์๋ํธ์ถ
jpa ๊ฐ ์คํ๋๋ฉด ์๋์ผ๋ก ์ด๋ ๊ฒ ์ฟผ๋ฆฌ๋ฌธ์ด ์ฝ์์ฐฝ์ ๋ฌ๋ค.
(+) ์ฟผ๋ฆฌ๋ฌธ์ application.properties ์ ํด๋น ์ค์ ์ ์ถ๊ฐํ๋ฉด ๋ณผ ์ ์๋ค
# Hibernate์ SQL ์ฟผ๋ฆฌ ์ถ๋ ฅ ํ์ฑํ
spring.jpa.show-sql=true
# SQL ์ฟผ๋ฆฌ์ ํ์์ ์ข ๋ ๋ณด๊ธฐ ์ข๊ฒ ์ถ๋ ฅ (์ต์
)
spring.jpa.properties.hibernate.format_sql=true
# ์คํ๋ SQL ์ฟผ๋ฆฌ์ ํ๋ผ๋ฏธํฐ๋ฅผ ์ถ๋ ฅ (Hibernate์ ๋ก๊ทธ ๋ ๋ฒจ์ DEBUG๋ก ์ค์ )
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type.descriptor.sql=trace
(+) React ์์ฒญ ๊ฐ์ฒด ๊ตฌ์กฐ ๋ณ๊ฒฝ
select ๋ ์๊ด ์์ง๋ง
entity ์ ๋์ผํ ๊ตฌ์กฐ๋ก ๋ณ๊ฒฝ => authority ๊ฐ์ฒด ์์ฒด๋ฅผ ๋ฐ๋ ๋ฐฉ์์ผ๋ก ๋ณ๊ฒฝํด์ค์ผํ๋ค.