Overview
En esta guía, puede aprender a utilizar la extensión MongoDB para Hibernate ORM para especificar una consulta de base de datos.
Puede refinar el conjunto de documentos que devuelve una consulta creando un filtro de consulta. Un filtro de consulta es una expresión que especifica los criterios de búsqueda que MongoDB utiliza para encontrar documentos en una operación de lectura o escritura. Para crear filtros de consulta de MongoDB, utilice sentencias de lenguaje de consulta de Hibernate (HQL) o lenguaje de consulta de persistencia de Jakarta (JPQL).
Tip
Para obtener más información sobre la sintaxis HQL y JPQL, consulte Una guía para el lenguaje de consulta Hibernate en la documentación de Hibernate ORM.
Nota
Soporte de query
La extensión MongoDB para Hibernate ORM no es compatible con todas las funciones de consulta de MongoDB e Hibernate. Para obtener más información, consulte Consulta de soporte en la página de compatibilidad de funciones.
Datos de muestra
Los ejemplos de esta guía utilizan el Movie Entidad que representa la sample_mflix.movies colección de los conjuntos de datos de muestra del Atlas. La Movie entidad tiene la siguiente definición:
import com.mongodb.hibernate.annotations.ObjectIdGenerator; import org.bson.types.ObjectId; import java.util.List; 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 List<String> cast; public Movie(String title, String plot, int year, List<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 List<String> getCast() { return cast; } public void setCast(List<String> cast) { this.cast = cast; } }
Para aprender a crear una aplicación Java que use la extensión MongoDB para Hibernate ORM para interactuar con esta colección de muestra de MongoDB, consulte el tutorial Primeros pasos.
Importante
Contextos de Persistencia
Para que Hibernate ORM interactúe con la base de datos, debe ejecutar operaciones dentro de un contexto de persistencia mediante Hibernate Session o Jakarta Persistence EntityManager. Utilice HQL para definir consultas de sesión y JPQL para definir consultas del administrador de entidades.
Antes de ejecutar los ejemplos de esta guía, asegúrese de agregar un contexto de persistencia y un código de administración de transacciones a su aplicación que se parezca al siguiente código:
var sf = HibernateUtil.getSessionFactory(); Session session = sf.openSession(); Transaction tx = session.beginTransaction(); // ... Perform CRUD operations here tx.commit(); session.close(); sf.close();
Para utilizar una sesión, debes crear un archivo HibernateUtil.java que configure un SessionFactory. Para obtener más información, consulta el paso Configura tu aplicación del tutorial Comenzar.
// 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 usar un,EntityManager debe crear un persistence.xml archivo que declare una unidad de persistencia. Para obtener más información, consulte el Tutorial sobre el uso de las API estándar de JPA en la documentación de Hibernate ORM.
Ejecutar una consulta
Para consultar sus datos de MongoDB, llame al método createQuery() en una sesión o un gestor de entidades. A continuación, especifique los criterios de coincidencia en una declaración de lenguaje de consulta de Hibernate (HQL) o de lenguaje de consulta de persistencia de Jakarta (JPQL).
En esta sección se describe cómo realizar las siguientes operaciones de consulta:
Recuperar todos los documentos
Para recuperar todos los documentos de una colección, pase una instrucción SELECT básica al método createQuery(). En esta instrucción, especifique la entidad que representa la colección que desea consultar.
El siguiente ejemplo recupera los valores title de todos los documentos de la colección sample_mflix.movies consultando la entidad 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 coincidentes
Para recuperar documentos que cumplan criterios específicos, pase una sentencia SELECT con una cláusula where al método createQuery(). En esta sentencia, especifique la entidad que representa la colección que desea consultar y los criterios de coincidencia.
El siguiente ejemplo recupera documentos que tienen un valor title de "Romeo and Juliet" de la colección 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 un solo documento que coincida con criterios específicos, encadene el método getSingleResult() al método createQuery().
El siguiente ejemplo recupera un único documento que tiene un valor title de "Best in Show" de la colección 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
Errores NonUniqueResultException
Si su consulta coincide con varios documentos, el getSingleResult() método genera un NonUniqueResultException error. Para evitar este error, asegúrese de que su consulta coincida solo con un documento o limite los resultados a uno solo.
Ejecutar queries de la API de criterios
En lugar de utilizar declaraciones HQL o JPQL para crear filtros de consulta, puede utilizar la API de criterios de persistencia de Jakarta para crear consultas de tipos seguros mediante programación.
Para crear una consulta utilizando la API de criterios, realice las siguientes acciones:
Crea un objeto
CriteriaBuilderdesde una sesión o un administrador de entidades.Crear un objeto
CriteriaQuerydesde el generador y especificar la entidad a query.Utilice los métodos de consulta proporcionados por la clase
CriteriaQuerypara especificar sus criterios de consulta.
Tip
Para obtener más información sobre la API de criterios, consulte Uso de la API de criterios para crear consultas en la documentación de Jakarta EE.
El siguiente ejemplo utiliza la API de Criteria para recuperar todos los documentos que tienen un valor de year igual a 1925 de la colección sample_mflix.movies:
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
Ejecuta consultas nativas
Para ejecutar consultas MongoDB que actualmente no son compatibles con la extensión ORM de Hibernate, puede pasar su consulta como una declaración de lenguaje de consulta MongoDB (MQL) al método createNativeQuery().
Para aprender a ejecutar consultas nativas, consulte la guía Realizar consultas nativas.
Personaliza tu filtro de consulta
En esta sección se describe cómo utilizar operadores para crear los siguientes tipos de filtros de consulta:
Tip
Utilice filtros de comparación
Nota
La extensión ORM de Hibernate no admite todos los operadores de comparación, incluidos LIKE BETWEENy. Para obtener más información sobre las limitaciones de compatibilidad, consulte Compatibilidad de consultas en la página de compatibilidad de funciones.
Puede utilizar los siguientes operadores en sus declaraciones de consulta para comparar valores de campo con valores de consulta especificados:
=: Igualdad de coincidencia<>: Coincidencia de desigualdades>: Mayor que las comparaciones>=: Comparaciones de mayor o igual<:Menos que comparaciones<=: Comparaciones menores o iguales
El siguiente ejemplo recupera documentos que tienen un valor year mayor o igual a 2015 de la colección 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 ...
Utilice filtros lógicos
Puede usar los siguientes operadores en sus sentencias de consulta para combinar múltiples criterios de consulta:
and:Cumple todos los criteriosor:Cumple cualquier criterionot: Invert criteria
El siguiente ejemplo recupera un documento que tiene un valor title de "The Godfather" y un valor year de 1972 de la colección sample_mflix.movies:
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 de la consulta
En esta sección se describe cómo modificar los resultados de su consulta de las siguientes maneras:
Ordenar resultados
Puede ordenar los resultados de una consulta por el valor de un campo específico usando la cláusula order by en su consulta. De forma predeterminada, la cláusula order by ordena los documentos en orden ascendente. Para ordenar los documentos en orden descendente, añada la palabra clave desc al nombre del campo.
El siguiente ejemplo recupera documentos coincidentes de la colección sample_mflix.movies y los ordena por el campo year en orden descendente:
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
Saltar resultados
Puede omitir un número específico de documentos en los resultados de su consulta encadenando el método setFirstResult() a la consulta. Pase el número de documentos iniciales que se omitirán como argumento a este método.
El siguiente ejemplo ejecuta la misma query que el ejemplo anterior pero omite el primer documento coincidente en los 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 los resultados
Puede limitar la cantidad de documentos que devuelve su consulta encadenando el método setMaxResults() a la consulta. Pase el número máximo de documentos a devolver como argumento a este método.
El siguiente ejemplo ejecuta la misma consulta que el ejemplo de ordenación, pero devuelve hasta dos documentos coincidentes en los 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
Alternativamente, puede utilizar una cláusula limit en su instrucción HQL o JPQL para restringir el número de documentos que devuelve su query, como se muestra en el siguiente código:
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();
Consultas de campo avanzadas
Esta sección describe cómo ejecutar consultas en los siguientes campos:
Consultar un campo de clave principal
Para recuperar un documento según su valor ObjectId, puede pasar este valor como argumento al método get(), si está usando una sesión, o al método find(), si está usando un administrador de entidades.
El siguiente ejemplo recupera un documento de la colección sample_mflix.movies por su valor ObjectId:
var movieById = session.get(Movie.class, new ObjectId("573a13a8f29313caabd1d53c"));
var movieById = entityManager.find(Movie.class, new ObjectId("573a13a8f29313caabd1d53c"));
Consultar un campo incrustado
Puede representar documentos incrustados de MongoDB creando @Struct incrustables agregados. No puede crear filtros de consulta para valores incrustables individuales, pero puede usar la extensión ORM de Hibernate para obtener @Struct incrustables agregados asociados a entidades principales específicas.
Tip
Para obtener más información sobre cómo representar documentos incrustados, consulte Datos incrustados en la guía Crear entidades.
Importante
Limitaciones de las consultas
Para obtener más información sobre las limitaciones de consulta para elementos integrables, consulte Compatibilidad de consultas de Hibernate en la página Compatibilidad de funciones.
El siguiente ejemplo recupera documentos con un valor title de "Hairspray" de la colección sample_mflix.movies. A continuación, el código recupera el campo awards, que almacena el incrustable agregado Awards @Struct, e imprime el campo wins del tipo incrustable Awards:
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
Consultar un campo de matriz
La extensión ORM de Hibernate admite las siguientes funciones para consultar campos de matriz:
array_contains(): Coincidir con documentos donde un campo de matriz contiene un valor especificadoarray_contains_nullable(): Coincide con documentos donde un campo de matriz contiene un valor específico, incluidos los valoresnullarray_includes(): Coincidir con documentos donde un campo de matriz incluye otro valor de matrizarray_includes_nullable(): Coincidir con documentos donde un campo de matriz incluye otro valor de matriz, incluidos valoresnull
Tip
Para obtener más información sobre las funciones de matriz, consulte Funciones para trabajar con matrices en la guía del usuario de Hibernate ORM.
El siguiente ejemplo utiliza la función array_contains() para recuperar documentos que tienen el valor "Kathryn Hahn" en el campo de matriz cast de la colección 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
Información Adicional
Para obtener más información sobre cómo realizar otras operaciones en sus datos de MongoDB, consulte la guía Realizar operaciones CRUD.
Para obtener más información sobre el uso de HQL y JPQL para ejecutar consultas, consulte Una guía para el lenguaje de consulta de Hibernate en la documentación de Hibernate ORM.