Visão geral
Neste guia, você pode aprender como usar a Extensão MongoDB para Hibernar ORM para especificar uma consulta de banco de dados .
Você pode refinar o conjunto de documentos que uma query retorna criando um filtro de query. Um filtro de query é uma expressão que especifica os critérios de pesquisa que o MongoDB usa para corresponder a documentos em uma operação de leitura ou gravação. Para criar filtros de query do MongoDB , use declarações Hibernar Query Language (HQL) ou Jakarta Persistence Query Language (JPQL).
Dica
Para saber mais sobre a sintaxe HQL e JPQL, consulte Um guia para a linguagem de query do Hibernar na documentação ORM do Hibernado.
Observação
Suporte a consultas
A extensão MongoDB para hibernação ORM não oferece suporte a todas as funcionalidades de query do MongoDB e hibernação. Para saber mais, consulte Suporte a queries do na página Compatibilidade de recursos.
Dados de amostra
Os exemplos nesta aba usam a Movie entidade, que representa a sample_mflix.movies coleção dos conjuntos de dados de amostra do Atlas. A Movie entidade tem a seguinte definição:
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; } }
Para saber como criar um aplicação Java que use a extensão MongoDB para hibernação ORM para interagir com essa coleção de amostras do MongoDB , consulte o tutorial de Introdução.
Importante
Contextos de persistência
Para habilitar o ORM do Hibernar para interagir com o banco de dados, você deve executar operações dentro de um contexto de persistência utilizando um Hibername Session ou um Jakarta Persistence EntityManager. Use o HQL para definir queries de sessão e use o JPQL para definir queries do gerenciador de entidades.
Antes de executar os exemplos neste guia, adicione o contexto de persistência e o código de gerenciamento de transações ao seu aplicação que se assemelha ao código a seguir:
var sf = HibernateUtil.getSessionFactory(); Session session = sf.openSession(); Transaction tx = session.beginTransaction(); // ... Perform CRUD operations here tx.commit(); session.close(); sf.close();
Para utilizar uma sessão, você deve criar um HibernateUtil.java arquivo que configure SessionFactory um. Para saber mais, consulte a etapa Configurar seu aplicativo do tutorial de Introdução.
// 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;
Para utilizar EntityManager um, você deve criar um persistence.xml arquivo que declara uma unidade de persistência. Para saber mais, consulte o Tutorial usando APIs padrão JPA na documentação do ORM do Hibernado.
Executar uma consulta
Para executar query de seus dados MongoDB , chame o método createQuery() em uma sessão ou um gerenciador de entidade. Em seguida, especifique seus critérios de correspondência em uma declaração Hibername Query Language (HQL) ou Jakarta Persistence Query Language (JPQL).
Esta seção descreve como executar as seguintes operações de query:
Recuperar todos os documentos
Para recuperar todos os documentos de uma collection, passe uma instrução de seleção básica para o método createQuery(). Nesta declaração, especifique a entidade que representa a collection que você deseja fazer query.
O exemplo a seguir recupera os valores title de todos os documentos da collection sample_mflix.movies fazendo query na entidade Movie:
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? ...
Recuperar documentos correspondentes
Para recuperar documentos que correspondam a critérios específicos, passe uma declaração de seleção com uma cláusula where para o método createQuery(). Nesta declaração, especifique a entidade que representa a collection que você deseja consultar e os critérios correspondentes.
O exemplo a seguir recupera documentos que têm um valor title de "Romeo and Juliet" da collection sample_mflix.movies:
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
Para recuperar um único documento que corresponda a critérios específicos, encadeie o método getSingleResult() com o método createQuery().
O exemplo a seguir recupera um único documento com um valor title de "Best in Show" da collection sample_mflix.movies:
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
Importante
Erros de NonUniqueResultException
Se a sua query corresponder a vários documentos, o getSingleResult() método gerará um NonUniqueResultException erro. Para evitar esse erro, certifique-se de que sua query corresponda a apenas um documento ou limite os resultados da query a um documento.
Executar queries de API de critérios
Em vez de usar instruções HQL ou JPQL para criar filtros de query, é possível usar a API de critérios de persistência de Jakarta para criar query de tipo seguro programaticamente.
Para criar uma query usando a API de critérios, execute as seguintes ações:
Crie um objeto
CriteriaBuildera partir de uma sessão ou de um gerenciador de entidade.Crie um objeto
CriteriaQuerydo construtor e especifique a entidade para query.Utilize métodos de query fornecidos pela classe
CriteriaQuerypara especificar seus critérios de query.
Dica
Para saber mais sobre a API de critérios, consulte Utilizando a API de critérios para criar queries na documentação do Jakarta EE.
O exemplo a seguir usa a API de critérios para recuperar todos os documentos que têm um year valor de 1925 da sample_mflix.movies coleção:
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
Executar queries nativas
Para executar queries do MongoDB que não são atualmente suportadas pela extensão Hibername ORM, você pode passar sua query como uma instrução MongoDB Query Language (MQL) para o método createNativeQuery() .
Para saber como executar queries nativas, consulte o guia Executar queries nativas.
Personalize seu filtro de query
Esta seção descreve como usar operadores para criar os seguintes tipos de filtros de query:
Dica
Esta seção não descreve todos os operadores de querydisponíveis. Para visualizar uma lista completa de operadores de query, consulte Expressões de operador no guia de query do Hibername ORM.
Usar filtros de comparação
Observação
A extensão Hibernar ORM não suporta todos os operadores de comparação, incluindo LIKE BETWEENe. Para saber mais sobre as limitações de suporte, consulte Suporte a queries na página Compatibilidade de recursos.
Você pode usar os seguintes operadores em suas declarações de query para comparar valores de campo com valores de query especificados:
=: Correspondência de igualdade<>: Correspondência de desigualdade>: maior que as comparações>=: Comparações maiores ou iguais<: menos do que comparações<=: Comparações menores ou iguais
O exemplo a seguir recupera documentos que têm um valor de year maior ou igual a 2015 da collection sample_mflix.movies:
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 ...
Usar filtros lógicos
Você pode usar os seguintes operadores em suas declarações de query para combinar vários critérios de query:
and: Corresponder a todos os critériosor: Corresponder a qualquer critérionot: Invert criteria
O exemplo a seguir recupera um documento com um title valor de "The Godfather" e um year valor de e 1972 da sample_mflix.movies collection:
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
Modificar Resultados da Query
Esta seção descreve como modificar os resultados da query das seguintes maneiras:
Classificar resultados
Você pode classificar os resultados da query pelo valor de um campo especificado usando a cláusula order by em sua declaração de query. Por padrão, a cláusula order by classifica documentos em ordem crescente. Para classificar documentos em ordem decrescente, anexe a palavra-chave desc ao nome do campo .
O exemplo a seguir recupera documentos correspondentes da collection sample_mflix.movies e os classifica pelo campo year em ordem decrescente:
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
Ignorar resultados
Você pode ignorar um número específico de documentos nos resultados da consulta encadeando o método setFirstResult() à consulta. Passe o número de documentos iniciais a serem ignorados como argumento para esse método.
O exemplo a seguir executa a mesma query do exemplo anterior, mas ignora o primeiro documento correspondente nos resultados:
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
Limitar resultados
Você pode limitar o número de documentos que sua query retorna encadeando o método setMaxResults() à query. Passe o número máximo de documentos para retornar como argumento para esse método.
O exemplo a seguir executa a mesma query que o exemplo de classificação, mas retorna até dois documentos correspondentes nos resultados:
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
Como alternativa, você pode usar uma cláusula limit em sua declaração HQL ou JPQL para restringir o número de documentos que sua query retorna, conforme mostrado no código a seguir:
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();
Queries de campo avançadas
Esta seção descreve como executar queries nos seguintes campos:
Executar queries de um campo de chave primária
Para recuperar um documento com base em seu valor ObjectId, você pode passar esse valor como argumento para o método get(), se estiver usando uma sessão, ou o método find(), se estiver usando um gerenciador de entidades .
O exemplo a seguir recupera um documento da collection sample_mflix.movies por seu valor ObjectId:
var movieById = session.get(Movie.class, new ObjectId("573a13a8f29313caabd1d53c"));
var movieById = entityManager.find(Movie.class, new ObjectId("573a13a8f29313caabd1d53c"));
Executar queries de um campo incorporado
Você pode representar documentos incorporados do MongoDB criando @Struct documentos incorporados agregados. Você não pode criar filtros de query em valores incorporáveis individuais, mas pode usar a extensão ORM do Hibernado para buscar @Struct incorporáveis agregados associados a entidades matrizes específicas.
Dica
Para saber mais sobre como representar documentos incorporados, consulte Dados incorporados no guia Criar entidades.
Importante
Limitações de query
Para saber mais sobre as limitações de query para incorporáveis, consulte Suporte de query do hibernado na página Compatibilidade de recursos.
O exemplo a seguir recupera documentos que têm um valor title de "Hairspray" da collection sample_mflix.movies. Em seguida, o código obtém o campo awards , que armazena o Awards @Struct agregado incorporável e imprime o campo wins do tipo Awards incorporável:
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
Executar query de um campo de array
A extensão Hibernar ORM suporta as seguintes funções para consultar campos de array:
array_contains(): Corresponde a documentos em que um campo de array contém um valor especificadoarray_contains_nullable(): Corresponde a documentos onde um campo de array contém um valor especificado, incluindo valoresnullarray_includes(): Corresponde a documentos onde um campo de array inclui outro valor de arrayarray_includes_nullable(): Corresponde a documentos onde um campo de array inclui outro valor de array, incluindo valoresnull
Dica
Para saber mais sobre as funções de array, consulte Funções para lidar com arrays no guia do usuário do Hibername ORM.
O exemplo a seguir usa a função array_contains() para recuperar documentos que têm o valor "Kathryn Hahn" no campo de array cast da collection sample_mflix.movies:
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
Informações adicionais
Para saber mais sobre como executar outras operações em seus dados do MongoDB , consulte o guia Executar operações CRUD.
Para saber mais sobre como usar HQL e JPQL para executar queries, consulte Um guia para a linguagem de query do Hibernar na documentação do ORM do Hibernado.