Spring

13. 객체지향 쿼리 언어(JPQL)

공대키메라 2021. 7. 24. 13:31

 

이제 객체 지향 쿼리에 대해 알아볼것임!

 

  • JPQL
  • jpa Criteria
  • QueryDSL
  • 네이티브 SQL
  • JDBC API 직접 사용, MyBatis, SpringJdbcTemplate함께 사용

 

JPQL 소개

가장 단순한 조회 방법

1. EntityManager.find()

2. 객체 그래프 탐색(a.getB().getC())

 

  • JPA를 사용하면 엔티티 객체를 중심으로 개발
  • 문제는 검색 쿼리이다!
  • 검색을 할 떄도 테이블이 아닌 엔티티 객체를 대상으로 검색
  • 모든 DB 데이터를 객체를 변환해서 검색하는 것은 불가능
  • 애플리케이션이 필요한 데이터만 DB에서 불러오려면 결국 검색 조건이 포함된 SQL이 필요

그래서...

JPA는 SQL를 추상화한 JPQL이라는 객체 지향 쿼리 언어를 제공한다

SQL과 문법이 유사하다. SELECT, FROM, WHERE, GROUP BY, HAVING, JOIN 지원

JPQL은 엔티티 객체를 대상으로 쿼리

SQL은 데이터베이스 테이블을 대상으로 쿼리

 

이런 것을 실행시키고 한번 실행해봣다.

그러면 나오는 select 쿼리가 어떻게 실행되는지 확인해보면...

package hellojpa;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
import java.util.List;
import java.util.Set;

public class jpaMain {

    public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");

        EntityManager em = emf.createEntityManager();

        EntityTransaction   tx = em.getTransaction();
        tx.begin();

        try {

			List<Member> resultList = em.createQuery("select m from Member m where m.username like '%kim%'", Member.class)
				.getResultList();
	

            em.flush();
            em.clear();
        }catch (Exception e){
            tx.rollback();
        } finally {
            em.close();
        }

        emf.close();
    }
}

 

실행결과

...
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%'

뭔가 select가 된것을 확인할 수 있다.

 

우리가 입력한 SQL(우리가 설정한 Entity기준)은 주석처리가 되있는 것을 볼 수 있고 

 

그것을 알아서 만들어준 쿼리를 날려줌

 

JPQL은 그래서 정리하면....

  1. 테이블이 아닌 객체를 대상으로 검색하는 객체 지향 쿼리
  2. SQL을 추상화해서 특정 테이터베이스 SQL에 의존하지 않는다!
  3. JPQL을 한마디로 정의하면 객체 지향 SQL!

 

CRITERIA??

JPQL은 잘 보면 단순한 String임 

이것은 동적 쿼리를 만들기 엄청 어려움!

if문 넣던지 뭐할건지 직접 해주면 지옥이라능 ㅠㅠ

 

그래서 ibatis, mybatis가 편하긴 함(동적 쿼리 짜기 좋음)

 

어찌됏든 criteria 예시를 먼저 보자

 

package hellojpa;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import java.util.List;
import java.util.Set;

public class jpaMain {

    public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");

        EntityManager em = emf.createEntityManager();

        EntityTransaction   tx = em.getTransaction();
        tx.begin();

        try {

            CriteriaBuilder cb = em.getCriteriaBuilder();
            CriteriaQuery<Member> query = cb.createQuery(Member.class);

            Root<Member> m = query.from(Member.class);

            CriteriaQuery<Member> cq = query.select(m).where(cb.equal(m.get("username"), "kim"));
            List<Object> resultList = em.createQuery(cq).getResultList();
            

            em.flush();
            em.clear();
        }catch (Exception e){
            tx.rollback();
        } finally {
            em.close();
        }

        emf.close();
    }
}

 

근데 criteria를 쓰면 유지보수하기에 힘들다고 해서 안쓴다고 함

=> teacher는 안쓰는 망한 스펙이라고...  ㅠㅠㅠ

 

그렇다네요... 휴... 

QuerytDSL이라는 OpenSource Library를 권장한다!

 

흠... 굉장히 직관적이다. 보기도 깔끔하고

 

 

 

 

 

배울거 많네 ㅎㅎ

 

근데 JQPL을 잘해야한다고 함!

(query랑 크게 다르지 않음)

'Spring' 카테고리의 다른 글

15. 조인  (0) 2021.07.24
14. 기본 문법과 쿼리 API  (0) 2021.07.24
12. 값 타입의 비교 ~  (0) 2021.07.22
11. 값 타입과 불변 객체~  (0) 2021.07.21
11. 스프링 / 영속성 전이  (0) 2021.07.20