자바 ORM 표준 JPA 프로그래밍 공부 기록
목차
테이블이 아닌 엔티티 객체를 대상으로 검색 필요함
예제 - 회원이름이 KIM인 엔티티 조회
List<Member> memberList = em.createQuery(
"select m from Member m where m.userName like '%KIM%'", Member.class
).getResultList();
Hibernate:
/* select
m
from
Member m
where
m.userName like '%KIM%' */ select
member0_.MEMBER_ID as MEMBER_I1_6_,
member0_.city as city2_6_,
member0_.street as street3_6_,
member0_.zipcode as zipcode4_6_,
member0_.userName as userName5_6_
from
Member member0_
where
member0_.userName like '%KIM%'
JPQL을 생성하는 빌더 클래스
문자가 아닌 프로그래밍 코드로 JPQL을 작성할 수 있다.
//Criteria 사용준비
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Member> query = cb.createQuery(Member.class);
//Root 클래스
Root<Member> m = query.from(Member.class);
//쿼리 생성
CriteriaQuery<Member> cq = query.select(m).where(cb.equal(m.get("userName"), "KIM"));
List<Member> memberList = em.createQuery(cq).getResultList();
Hibernate:
/* select
generatedAlias0
from
Member as generatedAlias0
where
generatedAlias0.userName=:param0 */ select
member0_.MEMBER_ID as MEMBER_I1_6_,
member0_.city as city2_6_,
member0_.street as street3_6_,
member0_.zipcode as zipcode4_6_,
member0_.userName as userName5_6_
from
Member member0_
where
member0_.userName=?
장점은 많지만 실무에선 안씀
복잡해서 실용성이 없고 운영하기 어려움
Criteria처럼 JPQL 빌더 역할을 함
코드 기반이면서 단순하고 사용하기 쉽다
컴파일 시점에 문법 오류를 찾을 수 있음
• 동적쿼리 작성 편리함
• 단순하고 쉬움
• 실무 사용 권장
JPA가 제공하는 SQL을 직접 사용하는 기능
특정 DB에 의존하는 기능을 사용할 때 필요
표준화 되어 있지 않은 것들은 JPQL에서 사용할 수 없다. 또한 SQL은 지원하지만 JPQL이 지원하지 않는 기능도 있다.
=> 네이티브 SQL
단점은 특정 DB에 의존적이므로 DB를 변경하면 네이티브 SQL도 수정해야 한다.
JPA와 함께 JDBC 커넥션을 직접 사용하거나, 스프링
JdbcTemplate, MyBatis 등 함께 사용 가능하다
flush
는 commit되기 직전에도 호출되지만 em을 통해 JPQL query가 날아갈 때도 직전에 flush
가 된다 (auto)
JPA 관련된 기술을 쓸 때는 크게 문제가 안된다.
다만 DB 커넥션을 따로 얻어와서 JPA를 우회해서 DB에 접근할 경우에는 문제가 된다. 영속성 컨텍스트와 DB를 불일치 상태로 만들어서 데이터 무결성을 훼손할 수 있다.
JDBC나 MyBatis를 JPA와 함께 사용하려면 영속성 컨텍스트를 적절한 시점에 강제로 플러시 해야한다.
JPA 우회해서 SQL 실행하기 직전에 영속성 컨텍스트를 수동으로 flush
해서 DB와 영속성 컨텍스트를 동기화한다.