[JPA] 10. 객체지향 쿼리 언어 - 객체지향 쿼리 소개

DAUN JO·2021년 11월 11일
0

JPA

목록 보기
9/11
post-thumbnail

자바 ORM 표준 JPA 프로그래밍 공부 기록


목차

  • 객체지향 쿼리 소개
  • JPQL
  • Criteria
  • QueryDSL
  • Native SQL
  • 객체지향 쿼리 심화

📍 10.1 객체지향 쿼리 소개

테이블이 아닌 엔티티 객체를 대상으로 검색 필요함

💭 JPQL

  • 테이블이 아닌 객체를 대상으로 검색하는 객체지향 쿼리
  • SQL을 추상화해서 특정 DB SQL에 의존 X

예제 - 회원이름이 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%'

💭 Criteria 쿼리

JPQL을 생성하는 빌더 클래스
문자가 아닌 프로그래밍 코드로 JPQL을 작성할 수 있다.

  • 컴파일 시점에 오류 발견
  • IDE를 사용하면 코드 자동완성 지원
  • 동적 쿼리 작성 편함
//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=?

장점은 많지만 실무에선 안씀
복잡해서 실용성이 없고 운영하기 어려움


💭 QueryDSL

Criteria처럼 JPQL 빌더 역할을 함
코드 기반이면서 단순하고 사용하기 쉽다
컴파일 시점에 문법 오류를 찾을 수 있음

• 동적쿼리 작성 편리함
• 단순하고 쉬움
• 실무 사용 권장


💭 네이티브 SQL

JPA가 제공하는 SQL을 직접 사용하는 기능
특정 DB에 의존하는 기능을 사용할 때 필요
표준화 되어 있지 않은 것들은 JPQL에서 사용할 수 없다. 또한 SQL은 지원하지만 JPQL이 지원하지 않는 기능도 있다.

=> 네이티브 SQL

단점은 특정 DB에 의존적이므로 DB를 변경하면 네이티브 SQL도 수정해야 한다.


💭 JDBC 직접 사용, SpringJdbcTemplate 등

JPA와 함께 JDBC 커넥션을 직접 사용하거나, 스프링
JdbcTemplate, MyBatis 등 함께 사용 가능하다


flush가 되는 시점은 commit될 때와 query가 날아갈 때이다.

flush는 commit되기 직전에도 호출되지만 em을 통해 JPQL query가 날아갈 때도 직전에 flush가 된다 (auto)
JPA 관련된 기술을 쓸 때는 크게 문제가 안된다.


다만 DB 커넥션을 따로 얻어와서 JPA를 우회해서 DB에 접근할 경우에는 문제가 된다. 영속성 컨텍스트와 DB를 불일치 상태로 만들어서 데이터 무결성을 훼손할 수 있다.

JDBC나 MyBatis를 JPA와 함께 사용하려면 영속성 컨텍스트를 적절한 시점에 강제로 플러시 해야한다.

JPA 우회해서 SQL 실행하기 직전에 영속성 컨텍스트를 수동으로 flush해서 DB와 영속성 컨텍스트를 동기화한다.



profile
🍕

0개의 댓글