개요
In this guide, you can learn how to use the MongoDB Extension for Hibernate ORM to specify a database query.
쿼리 필터하다 만들어 쿼리 반환하는 문서 설정하다 를 구체화할 수 있습니다. 쿼리 필터하다 는 MongoDB 읽기 또는 쓰기 (write) 작업에서 문서를 일치시키는 데 사용하는 검색 기준을 지정하는 표현식 입니다. MongoDB 쿼리 필터를 만들려면 하이버네이트 쿼리 언어(HQL) 또는 자카르타 지속성 쿼리 언어(JPQL) 문을 사용합니다.
팁
To learn more about HQL and JPQL syntax, see A Guide to Hibernate Query Language in the Hibernate ORM documentation.
참고
쿼리 지원
The MongoDB Extension for Hibernate ORM does not support all MongoDB and Hibernate query features. To learn more, see Query Support on the Feature Compatibility page.
샘플 데이터
이 가이드 의 예제에서는 Movie Atlas sample_mflix.movies 샘플 데이터 세트의 컬렉션 나타내는 엔터티를 사용합니다.Movie 엔터티의 정의는 다음과 같습니다.
import com.mongodb.hibernate.annotations.ObjectIdGenerator; import org.bson.types.ObjectId; import jakarta.persistence.Entity; import jakarta.persistence.Id; import jakarta.persistence.Table; public class Movie { private ObjectId id; private String title; private String plot; private int year; private String[] cast; public Movie(String title, String plot, int year, String[] cast) { this.title = title; this.plot = plot; this.year = year; this.cast = cast; } public Movie() { } public ObjectId getId() { return id; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getPlot() { return plot; } public void setPlot(String plot) { this.plot = plot; } public int getYear() { return year; } public void setYear(int year) { this.year = year; } public String[] getCast() { return cast; } public void setCast(String[] cast) { this.cast = cast; } }
To learn how to create a Java application that uses the MongoDB Extension for Hibernate ORM to interact with this MongoDB sample collection, see the Get Started tutorial.
중요
지속성 컨텍스트
하이버네이트 ORM이 데이터베이스 와 상호 작용 활성화 하려면 하이버네이트 Session 또는 자카르타 퍼시스턴스 EntityManager를 사용하여 퍼시스턴스 컨텍스트 내에서 작업을 실행 해야 합니다. HQL을 사용하여 세션 쿼리를 정의하고 JPQL을 사용하여 엔터티 관리자 쿼리를 정의합니다.
이 가이드 의 예제를 실행 전에 다음 코드와 유사한 지속성 컨텍스트 및 트랜잭션 관리 코드를 애플리케이션 에 추가해야 합니다.
var sf = HibernateUtil.getSessionFactory(); Session session = sf.openSession(); Transaction tx = session.beginTransaction(); // ... Perform CRUD operations here tx.commit(); session.close(); sf.close();
세션을 HibernateUtil.java 사용하려면 를 구성하는 파일 만들어야 SessionFactory 합니다. 자세히 학습 시작하기 튜토리얼의 애플리케이션 구성 단계를 참조하세요.
// Replace <persistence unit> with the name of your persistence unit in the persistence.xml file EntityManagerFactory emf = Persistence.createEntityManagerFactory("<persistence unit>"); EntityManager entityManager = entityManagerFactory.createEntityManager(); entityManager.getTransaction().begin(); // ... Perform CRUD operations here entityManager.getTransaction().commit(); entityManager.close(); emf.close;
를 사용하려면 EntityManager persistence.xml 지속성 단위를 선언하는 파일 만들어야 합니다. 자세히 학습 하이버네이트 ORM 문서에서 JPA 표준 API를 사용하는 튜토리얼을 참조하세요.
쿼리 실행
MongoDB 데이터를 쿼리 하려면 세션 또는 엔터티 관리자에서 createQuery() 메서드를 호출합니다. 그런 다음 하이버네이트 쿼리 언어(HQL) 또는 자카르타 지속성 쿼리 언어(JPQL) 성명서 에서 일치 기준을 지정합니다.
이 섹션에서는 다음 쿼리 작업을 수행하는 방법에 대해 설명합니다.
모든 문서 검색
컬렉션 에서 모든 문서를 조회 하려면 기본 선택 성명서 createQuery() 메서드에 전달합니다. 이 성명서 에서 쿼리 하려는 컬렉션 나타내는 엔터티를 지정합니다.
다음 예시 Movie 엔티티를 쿼리하여 sample_mflix.movies 컬렉션 에서 모든 문서의 title 값을 조회합니다.
var allDocs = session.createQuery("select title from Movie", String.class) .getResultList(); for (var t : allDocs) { System.out.println("Title: " + t); }
Title: A Corner in Wheat Title: Gertie the Dinosaur Title: The Perils of Pauline Title: Civilization Title: Where Are My Children? ...
var allDocs = entityManager.createQuery("select m.title from Movie m", String.class) .getResultList(); for (var t : allDocs) { System.out.println("Title: " + t); }
Title: A Corner in Wheat Title: Gertie the Dinosaur Title: The Perils of Pauline Title: Civilization Title: Where Are My Children? ...
일치하는 문서 조회
특정 기준과 일치하는 문서를 조회 하려면 where 절이 있는 선택 성명서 createQuery() 메서드에 전달합니다. 이 성명서 에서 쿼리 하려는 컬렉션 나타내는 엔터티와 일치 기준을 지정합니다.
다음 예시 sample_mflix.movies 컬렉션 에서 title 값이 "Romeo and Juliet" 인 문서를 검색합니다.
var matchingDocs = session.createQuery("from Movie where title = :t", Movie.class) .setParameter("t", "Romeo and Juliet") .getResultList(); for (var m : matchingDocs) { System.out.println("Title: " + m.getTitle() + ", Year: " + m.getYear()); }
Title: Romeo and Juliet, Year: 1936 Title: Romeo and Juliet, Year: 1968
var matchingDocs = entityManager.createQuery("select m from Movie m where m.title = :t", Movie.class) .setParameter("t", "Romeo and Juliet") .getResultList(); for (var m : matchingDocs) { System.out.println("Title: " + m.getTitle() + ", Year: " + m.getYear()); }
Title: Romeo and Juliet, Year: 1936 Title: Romeo and Juliet, Year: 1968
Retrieve One Document
특정 기준과 일치하는 단일 문서 조회 하려면 getSingleResult() 메서드를 createQuery() 메서드에 연결합니다.
다음 예시 sample_mflix.movies 컬렉션 에서 title 값이 "Best in Show" 인 단일 문서 조회합니다.
var singleResult = session.createQuery("from Movie where title = :t", Movie.class) .setParameter("t", "Best in Show") .getSingleResult(); System.out.println("Title: " + singleResult.getTitle() + ", Year: " + singleResult.getYear());
Title: Best in Show, Year: 2000
var singleResult = entityManager.createQuery("select m from Movie m where m.title = :t", Movie.class) .setParameter("t", "Best in Show") .getSingleResult(); System.out.println("Title: " + singleResult.getTitle() + ", Year: " + singleResult.getYear());
Title: Best in Show, Year: 2000
중요
NonUniqueResultException 오류
쿼리 여러 문서와 일치하는 getSingleResult() 경우 메서드에서 NonUniqueResultException 오류가 발생합니다. 이 오류를 방지하려면 쿼리 하나의 문서 와만 일치하는지 확인하거나 쿼리 결과를 하나 문서 로 제한합니다.
기준 API 쿼리 실행
HQL 또는 JPQL 문을 사용하여 쿼리 필터를 만드는 대신 자카르타 지속성 기준 API 사용하여 프로그래밍 방식으로 유형이 안전한 쿼리를 빌드 수 있습니다.
Criteria API( 기준 API)를 사용하여 쿼리 만들려면 다음 작업을 수행합니다.
세션 또는 엔터티 관리자에서
CriteriaBuilder객체 만듭니다.빌더에서
CriteriaQuery객체 만들고 쿼리 할 엔터티를 지정합니다.CriteriaQuery클래스에서 제공하는 쿼리 메서드를 사용하여 쿼리 기준을 지정합니다.
팁
기준 API 에 대해 자세히 학습 자카르타 EE 문서에서 기준 API 사용하여 쿼리 만들기를 참조하세요.
다음 예시 Criteria API 사용하여 sample_mflix.movies 컬렉션 에서 year 값이 1925 인 모든 문서를 조회 .
CriteriaBuilder cb = session.getCriteriaBuilder(); CriteriaQuery<Movie> cq = cb.createQuery(Movie.class); Root<Movie> movieRoot = cq.from(Movie.class); cq.select(movieRoot).where(cb.equal(movieRoot.get("year"), 1925)); session.createQuery(cq).getResultList() .forEach(m -> System.out.println(m.getTitle()));
Lady Windermere's Fan Clash of the Wolves Grass: A Nation's Battle for Life
CriteriaBuilder cb = entityManager.getCriteriaBuilder(); CriteriaQuery<Movie> cq = cb.createQuery(Movie.class); Root<Movie> movieRoot = cq.from(Movie.class); cq.select(movieRoot).where(cb.equal(movieRoot.get("year"), 1925)); entityManager.createQuery(cq).getResultList() .forEach(m -> System.out.println(m.getTitle()));
Lady Windermere's Fan Clash of the Wolves Grass: A Nation's Battle for Life
네이티브 쿼리 실행
현재 하이버네이트 ORM 확장에서 지원하지 않는 MongoDB 쿼리를 실행 하려면 쿼리 MongoDB 쿼리 언어(MQL) 성명서 으로 createNativeQuery() 메서드에 전달하면 됩니다.
네이티브 쿼리를 실행 방법을 학습 네이티브 쿼리 수행 가이드 참조하세요.
쿼리 필터 사용자 지정
이 섹션에서는 연산자를 사용하여 다음 유형의 쿼리 필터를 만드는 방법에 대해 설명합니다.
팁
이 섹션에서는 사용 가능한 모든 쿼리 연산자를 설명하지 않습니다. 쿼리 연산자의 전체 목록을 보려면 하이버네이트 ORM 쿼리 가이드 에서 연산자 표현식을 참조하세요.
비교 필터 사용
참고
최대 절전 모드 ORM 확장은 LIKE 및 를 포함한 모든 비교 연산자를 지원 하지 BETWEEN 않습니다. 지원 제한에 대해 자세히 학습 기능 호환성 페이지의 쿼리 지원을 참조하세요.
쿼리 문에서 다음 연산자를 사용하여 필드 값을 지정된 쿼리 값과 비교할 수 있습니다.
=: 동등성 매칭<>: 부등호 일치>: 비교보다 큼>=: 크거나 같은 비교<: 비교보다 작음<=: 보다 작거나 같은 비교
다음 예시 sample_mflix.movies 컬렉션 에서 year 값이 2015 보다 크거나 같은 문서를 검색합니다.
var comparisonResult = session.createQuery("from Movie where year >= :y", Movie.class) .setParameter("y", 2015) .getResultList(); for (var m : comparisonResult) { System.out.println("Title: " + m.getTitle()); }
Title: Jurassic World Title: The Stanford Prison Experiment Title: Ex Machina Title: Ant-Man Title: The Danish Girl Title: The Wedding Ringer Title: Good Ol' Boy Title: A Tale of Love and Darkness Title: Aloha ...
var comparisonResult = entityManager.createQuery("select m from Movie m where m.year >= :y", Movie.class) .setParameter("y", 2015) .getResultList(); for (var m : comparisonResult) { System.out.println("Title: " + m.getTitle()); }
Title: Jurassic World Title: The Stanford Prison Experiment Title: Ex Machina Title: Ant-Man Title: The Danish Girl Title: The Wedding Ringer Title: Good Ol' Boy Title: A Tale of Love and Darkness Title: Aloha ...
논리적 필터 사용
쿼리 문에서 다음 연산자를 사용하여 여러 쿼리 기준을 결합할 수 있습니다.
and: 모든 기준 일치or: 모든 기준과 일치not: Invert criteria
다음 예시 sample_mflix.movies 컬렉션 에서 title 값이 "The Godfather" 이고 year 값이 1972 인 문서 조회합니다.
var logicalResult = session.createQuery("from Movie where title = :t and year = :y", Movie.class) .setParameter("t", "The Godfather") .setParameter("y", 1972) .getSingleResult(); System.out.println("Title: " + logicalResult.getTitle());
Title: The Godfather
var logicalResult = entityManager.createQuery("select m from Movie m where m.title = :t and m.year = :y", Movie.class) .setParameter("t", "The Godfather") .setParameter("y", 1972) .getSingleResult(); System.out.println("Title: " + logicalResult.getTitle());
Title: The Godfather
쿼리 결과 수정
이 섹션에서는 다음과 같은 방법으로 쿼리 결과를 수정하는 방법에 대해 설명합니다.
결과 정렬
쿼리 성명서 에서 order by 절을 사용하여 지정된 필드 의 값을 기준으로 쿼리 결과를 정렬할 수 있습니다. 기본값 으로 order by 절은 문서를 오름차순으로 정렬합니다. 문서를 내림차순으로 정렬하려면 필드 이름에 desc 키워드를 추가합니다.
다음 예시 sample_mflix.movies 컬렉션 에서 일치하는 문서를 검색하고 year 필드 기준으로 내림차순으로 정렬합니다.
var sortResult = session.createQuery("from Movie where title = :t order by year desc", Movie.class) .setParameter("t", "Cinderella") .getResultList(); for (var m : sortResult) { System.out.println("Title: " + m.getTitle() + ", Year: " + m.getYear()); }
Title: Cinderella, Year: 2015 Title: Cinderella, Year: 1997 Title: Cinderella, Year: 1950
var sortResult = entityManager.createQuery("select m from Movie m where m.title = :t order by m.year desc", Movie.class) .setParameter("t", "Cinderella") .getResultList(); for (var m : sortResult) { System.out.println("Title: " + m.getTitle() + ", Year: " + m.getYear()); }
Title: Cinderella, Year: 2015 Title: Cinderella, Year: 1997 Title: Cinderella, Year: 1950
결과 건너뛰기
setFirstResult() 메서드를 쿼리 에 연결하여 쿼리 결과에서 지정된 수의 문서를 건너뛸 수 있습니다. 건너뛸 초기 문서 수를 이 메서드에 인수로 전달합니다.
다음 예시 앞의 예시 와 동일한 쿼리 실행하지만 결과에서 일치하는 첫 번째 문서 건너뜁니다.
var skipResult = session.createQuery("from Movie where title = :t order by year desc", Movie.class) .setParameter("t", "Cinderella") .setFirstResult(1) .getResultList(); for (var m : skipResult) { System.out.println("Title: " + m.getTitle() + ", Year: " + m.getYear()); }
Title: Cinderella, Year: 1997 Title: Cinderella, Year: 1950
var skipResult = entityManager.createQuery("select m from Movie m where m.title = :t order by m.year desc", Movie.class) .setParameter("t", "Cinderella") .setFirstResult(1) .getResultList(); for (var m : skipResult) { System.out.println("Title: " + m.getTitle() + ", Year: " + m.getYear()); }
Title: Cinderella, Year: 1997 Title: Cinderella, Year: 1950
결과 제한
setMaxResults() 메서드를 쿼리 에 연결하여 쿼리 반환하는 문서 수를 제한할 수 있습니다. 반환할 최대 문서 수를 이 메서드에 인수로 전달합니다.
다음 예시 정렬 예시 와 동일한 쿼리 실행하지만 결과에 일치하는 문서를 최대 두 개 반환합니다.
var limitResult = session.createQuery("from Movie where title = :t order by year desc", Movie.class) .setParameter("t", "Cinderella") .setMaxResults(2) .getResultList(); for (var m : limitResult) { System.out.println("Title: " + m.getTitle() + ", Year: " + m.getYear()); }
Title: Cinderella, Year: 2015 Title: Cinderella, Year: 1997
var limitResult = entityManager.createQuery("select m from Movie m where m.title = :t order by m.year desc", Movie.class) .setParameter("t", "Cinderella") .setMaxResults(2) .getResultList(); for (var m : limitResult) { System.out.println("Title: " + m.getTitle() + ", Year: " + m.getYear()); }
Title: Cinderella, Year: 2015 Title: Cinderella, Year: 1997
또는 다음 코드와 같이 HQL 또는 JPQL 성명서 에 limit 절을 사용하여 쿼리 반환하는 문서 수를 제한할 수 있습니다.
var limitClauseResult = session.createQuery("from Movie where title = :t order by year desc limit 2", Movie.class) .setParameter("t", "Cinderella") .getResultList();
var limitClauseResult = entityManager.createQuery("select m from Movie m where m.title = :t order by m.year desc limit 2", Movie.class) .setParameter("t", "Cinderella") .getResultList();
고급 필드 쿼리
이 섹션에서는 다음 필드에 대해 쿼리를 실행 방법에 대해 설명합니다.
기본 키 필드 쿼리
ObjectId 값을 기준으로 문서 조회 하려면 세션을 사용하는 경우 이 값을 get() 메서드에 인수로 전달하고, 엔터티 관리자를 사용하는 경우 find() 메서드에 전달할 수 있습니다. .
다음 예시 ObjectId 값으로 sample_mflix.movies 컬렉션 에서 문서 검색합니다.
var movieById = session.get(Movie.class, new ObjectId("573a13a8f29313caabd1d53c"));
var movieById = entityManager.find(Movie.class, new ObjectId("573a13a8f29313caabd1d53c"));
포함된 필드 쿼리
@Struct 애그리게이션 임베더블을 생성하여 MongoDB 내장된 문서를 표현할 수 있습니다. 개별 임베딩 가능 값에 대한 쿼리 필터를 생성할 수는 없지만 Hibernate ORM 확장을 사용하여 특정 상위 엔터티와 관련된 @Struct 개의 임베딩 가능 집계를 가져올 수 있습니다.
다음 예시 sample_mflix.movies 컬렉션 에서 title 값이 "Hairspray" 인 문서를 검색합니다. 그런 다음 이 코드는 Awards @Struct 임베딩 가능 애그리게이션을 저장하는 awards 필드 가져와서 Awards 임베딩 가능 유형의 wins 필드 출력합니다.
var embeddedResult = session.createQuery("select awards from Movie where title = :title", Awards.class) .setParameter("title", "Hairspray") .getResultList(); for (var a : embeddedResult) { System.out.println("Award wins: " + a.getWins()); }
Award wins: 0 Award wins: 21
var embeddedResult = entityManager.createQuery("select m.awards from Movie m where m.title = :title", Awards.class) .setParameter("title", "Hairspray") .getResultList(); for (var a : embeddedResult) { System.out.println("Award wins: " + a.getWins()); }
Award wins: 0 Award wins: 21
배열 필드 쿼리
하이버네이트 ORM 확장은 배열 필드 쿼리를 위해 다음 함수를 지원합니다.
array_contains(): 배열 필드 에 지정된 값이 포함된 문서 일치array_contains_nullable(): 배열 필드 에null값을 포함하여 지정된 값이 포함된 문서를 일치시킵니다.array_includes(): 배열 필드 다른 배열 값이 포함된 문서 일치array_includes_nullable(): 배열 필드 에null값을 포함한 다른 배열 값이 포함된 문서 일치
팁
배열 함수에 대해 자세히 학습 하이버네이트 ORM 사용자 가이드 에서 배열을 처리하기 위한 함수를 참조하세요.
다음 예시 array_contains() 함수를 사용하여 sample_mflix.movies 컬렉션 의 cast 배열 필드 에 "Kathryn Hahn" 값을 가진 문서를 조회 .
var arrayResult = session.createQuery("from Movie where array_contains(cast, :actor)", Movie.class) .setParameter("actor", "Kathryn Hahn") .getResultList(); for (var m : arrayResult) { System.out.println("Title: " + m.getTitle()); }
Title: How to Lose a Guy in 10 Days Title: The Secret Life of Walter Mitty Title: Bad Words Title: Afternoon Delight Title: The D Train
var arrayResult = entityManager.createQuery("select m from Movie m where array_contains(m.cast, :actor)", Movie.class) .setParameter("actor", "Kathryn Hahn") .getResultList(); for (var m : arrayResult) { System.out.println("Title: " + m.getTitle()); }
Title: How to Lose a Guy in 10 Days Title: The Secret Life of Walter Mitty Title: Bad Words Title: Afternoon Delight Title: The D Train
추가 정보
MongoDB 데이터에서 다른 작업을 수행하는 방법에 대해 자세히 학습 CRUD 작업 수행 가이드 참조하세요.
HQL 및 JPQL을 사용하여 쿼리를 실행 에 대해 자세히 학습 하이버네이트 ORM 문서에서 하이버네이트 쿼리 언어 가이드를 참조하세요.