본문 바로가기

스터디/JPA

객체지향 쿼리 언어 - (1)

728x90
반응형

객체 지향 쿼리 소개


식별자로 엔티티를 조회하는 기능을 넘어선 현실적이고 복잡한 검색 방법이 필요하다

 

모든 엔티티를 메모리에 올려두고 검색하는 것은 현실성이 없으므로 SQL을 통해 최대한 필터링해 조회해야 한다

이때 검색을 데이터베이스가 아닌 엔티티 객체를 대상으로 하는 방법이 필요하다

-> JPQL 사용

 

JPQL의 특징

  - 테이블이 아닌 객체를 대상으로 하는 객체지향 쿼리이다

  - SQL을 추상화해서 특정 데이터베이스 SQL에 의존하지 않는다 

    - JPA는 JPQL을 분석해 적절한 SQL을 만들어 데이터베이스를 조회해 이를 엔티티 객체로 반환한다

 

JPA가 지원하는 기능

  - JPQL

  - Criteria

  - Native SQL

 - QueryDSL

  - JDBC 직접 사용, MyBatis 같은 SQL 매퍼 프레임워크 사용

JPQL 소개

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

회원 이름이 kim인 엔티티를 조회한다

Member는 엔티티 이름이고, m.username은 엔티티 객체의 필드명이다

Criteria 쿼리 소개

JPQL을 생성하는 빌더 클래스이다

 

프로그래밍 코드로 JPQL을 작성할 수 있다

-> 잘못된 쿼리 작성시 컴파일 시점에 오류를 발견할 수 있다

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<Member> resultList = em.createQuery(cq).getResultList();

 

필드 명을 문자로 작성했는데 문자가 아닌 코드로 작성하고 싶으면 메타 모델을 사용하면 된다

m.get(Member_.username)

 

Criteria는 복잡하고 장황해 코드가 한눈에 들어오지 않는다는 단점이 있다

QueryDSL 소개

Criteria와 같이 JPQL 빌더 역할을 한다

 

코드 기반이면서 단순하고 사용하기 쉽다는 장점이 있다

JPAQuery query = new JPAQuery(em);
QMember member = Qmember.member;

List<Member> members = 
	query.from(member)
	.where(member.username.eq("kim"))
	.list(member);

네티이브 SQL 소개

SQL을 직접 사용할 수 있는 기능을 지원한다

 

특정 데이터베이스에서만 동작하는 기능을 사용할 때 사용한다 (SQL은 지원하지만 JPQL은 지원하지 않는 기능)

특정 데이터베이스에 의존하는 SQL을 작성해야 하므로 데이터베이스를 변경하면 네이티브 SQL도 수정해야 한다

String sql = "SELECT ID, AGE, TEAM_ID, NAME FROM MEMBER WHERE NAME = 'kim'";
List<Member> resultList = em.createNativeQuery(sql, Member.class).getResultList();

JDBC 직접 사용, Mybatis 같은 SQL 매퍼 프레임워크 사용

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

  - 우회하는 SQL에 대해서는 JPA가 전혀 인식하지 못하기 때문에 문제가 발생할 수 있다

 

따라서 JPA를 우회해서 SQL을 실행하기 전에 영속성 컨텍스트를 수동으로 플러시해 데이터베이스와 영속성 컨텍스트를 동기화하면 된다

  - 스프링 프레임워크의 AOP를 사용해 JPQ를 우회해 데이터베이스에 접근하는 메소드를 호출할 때마다 영속성 컨텍스트를 플러시하면 해당 문제를 해결할 수 있다

728x90
반응형

'스터디 > JPA' 카테고리의 다른 글

객체지향 쿼리 언어 - (3)  (0) 2025.02.17
객체지향 쿼리 언어 - (2)  (0) 2025.02.17
값 타입 - (2)  (0) 2025.02.16
값 타입 - (1)  (0) 2025.02.14
프록시와 연관관계 정리 - (3)  (1) 2025.02.14