1. SQL 중심적인 개발의 문제점
1.1 반복되는 CRUD 쿼리 작성 작업
INSERT, SELECT, UPDATE, DELETE....계속 반복만하는 지루한 작업의 연속이다.
1.2 필드 추가시 객체 변환, 관련 쿼리 일괄 변경
(이건 실제 내 경험)최근 프로젝트에서 실제로 일어난 일이다.
기존의 정책에서는 회원 정보 테이블에서 NAME이라는 컬럼을 사용하고 있었다. 이 안에 사용자 성, 이름 모두 포함되었다.
그런데, "우리는 글로벌 서비스니까, 외국인들도 사용하기 쉽게 성, 이름을 구분해서 입력 받아야겠다!"라는 요구사항이 들어왔다.
FIRST_NAME, LAST_NAME으로 필드 추가는 쉬웠지만, NAME 컬럼을 사용하는 쿼리를 조회한 결과 수백개의 쿼리가 나왔다 (흑흑)
결국 몇 일에 걸쳐 FIRST_NAME 과 LAST_NAME을 추가하는 노가다를 수행해야만 했다. (ㅂㄷㅂㄷ)
"성, 이름 추가해주세요"라고 해맑게 웃는 기획자에게 차마 나쁜 말은 못하고.. JPA를 사용했더라면 금방 끝날 작업이었을 것이다.
1.3 패러다임의 불일치 : 관계형 VS 객체지향형
관계형 접근의 불편함
- 개발자는 객체를 관계형 DB에 저장하기 위해 매번 쿼리를 작성해야한다.
- 상속 관계의 객체를 만들기 위해 JOIN을 해줘야한다.
예)
즉. COMIC BOOK을 가져오기 위해, 아래 코드처럼 매번 조인해야한다.
SELECT NAME, PRICE, GENRE
FROM BOOK a
INNER JOIN COMIC BOOK b
ON a.ID = b.ID
깔끔하게 자바 컬렉션에서 조회하자
ComicBook book1 = list.get(comicBookId)
2. JPA 소개
2.1 애노테이션
- @Entity: JPA가 관리할 대상으로 지정함.
- @Id: PK로 지정
- @Table(name="EXAMPLE"): 테이블의 명을 별도로 지정할 경우
- @Column(name="username"): 컬럼명 별도 지정
2.2 JPA 사용시 주의 사항
- 주의사항 1. 엔티티 매니저 팩토리는 하나만 생성하여 애플리케이션 전체에서 공유한다.
- 주의사항 2. 하나의 작업 (예. 고객이 가입)을 할 때마다 EntityManager를 새로 만들것
-
- EntityManager는 각 변경 사항의 상태값을 지닌다. 따라서 엔티티 매니저는 쓰레드간 공유해서는 안된다.
- 주의사항 3. 모든 DB 로직은 transaction 내부에서 실행되어야 한다.
EntityTransaction tx = em.getTransaction();
tx.begin();
// DB 로직
tx.commit
- 주의사항 4. UPDATE 쿼리 동작 방식을 꼭 기억하자.
EntityTransaction tx = em.getTransaction();
tx.begin();
try {
Member findMember = em.find(Member.class, 2L);
findMember.setName("helloJPA");
tx.commit();
}
** setName 이후 em.persist(member)를 해줄 필요가 없다.
왜냐면, findMember는 JPA에서 관리하는 대상이되고, 트랜젝션을 커밋하기전 객체에 변환이 있을 경우, JPA가 알아서 update 쿼리를 날리기 때문이다.
2.3 persistence.xml 의 주요 설정값
2.3.1 EntityFactoryManager의 이름 지정
<persistence-unit name="hello">
2.3.2 JPA 추가/수정 로직 실행시, 쿼리 내용을 로그로 보여줌,
<property name="hibernate.show_sql" value="true"/>
2.3.3 쿼리 로그를 보기 좋게 포맷팅
<property name="hibernate.format_sql" value="true"/>
2.3.4 실행된 쿼리의 내용을 코멘트로 알려줌.
<property name="hibernate.use_sql_comments" value="true"/>
# 코멘트 예시
예) /* insert hellojpa.Member */
2.4 JPQL(Java Persistence Query Language)이란?
JPA에서 제공하는 메서드만으로는 복잡한 쿼리 작성이 어렵다.
(예. 키가 150cm이상인 학생을 출력하는 조건문)
-> 조건 검색에 적합하도록 JPQL 탄생
정리
1. JPA의 모든 변경은 트랜젝션 안에서 일어나야만 한다.
2. 트랜젝션은 commit을 해주자.
EntityTransaction tx = em.getTransaction();
tx.begin();
// CRUD 로직
tx.commit();
3. 자원을 다 사용하면 entityManager는 닫아주자. (데이터 베이스 커넥션 반환 위해서)
EntityManager em = emf.createEntityManager();
// JPA 로직
em.close();
4. WAS 내려갈 때 entityManagerFactory도 닫아주자.
Connection pooling 등 내부 리소스 반환해야하니까!
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
// JPA 로직
emf.close();
'개발 > JPA' 카테고리의 다른 글
[강의 요약 노트]실전! 스프링 부트와 JPA 활용1 : (3) 애플리케이션 구현 준비 (0) | 2021.12.26 |
---|---|
[강의 요약 노트]실전! 스프링 부트와 JPA 활용1 : (2)도메인 분석 설계 (0) | 2021.12.26 |
[강의 요약 노트]실전! 스프링 부트와 JPA 활용1 : (1) 프로젝트 환경 설정 (0) | 2021.12.26 |
[JPA 기본] 1. 강좌 소개 (0) | 2021.12.02 |
[JPA] Entity 설계시 ID 값을 Long으로 지정하는 이유 (0) | 2021.11.07 |