Overview
En esta guía, aprenderá a llamar a las funciones extract() y format() del lenguaje de consulta de Hibernate (HQL) en un campo de fecha y hora mediante la extensión MongoDB para Hibernate ORM. Puede usar extract() para devolver parte de un valor de fecha y hora y format() para representar un valor de fecha y hora como una cadena.
La extensión Hibernate ORM traduce cada llamada a una expresión de agregación de MongoDB en la etapa $project. Puede llamar a cualquiera de las funciones en un campo de fecha y hora en una cláusula SELECT.
Nota
Zona horaria
La extensión Hibernate ORM resuelve cada función de fecha y hora en la zona horaria predeterminada de la JVM que ejecuta la aplicación. Pasa esa zona a MongoDB como el argumento timezone del operador generado. La misma consulta puede devolver valores diferentes en hosts configurados con zonas horarias distintas.
Dado que la extensión ORM de Hibernate no admite llamadas a funciones como operandos de una expresión calculada, no se puede combinar una función de fecha y hora con un operador aritmético. Para obtener más información, consulte la sección «Usar expresiones calculadas» de la guía «Especificar una consulta».
Datos de muestra
Los ejemplos de esta guía utilizan la entidad Movie, que representa la colección sample_mflix.movies del conjuntos de datos de muestras de Atlas. La entidad Movie tiene la siguiente definición:
import com.mongodb.hibernate.annotations.ObjectIdGenerator; import org.bson.types.ObjectId; import java.time.Instant; import java.util.List; import jakarta.persistence.Embedded; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; import jakarta.persistence.Id; import jakarta.persistence.OneToMany; import jakarta.persistence.Table; public class Movie { private ObjectId id; private String title; private String plot; private int year; private List<String> cast; private List<String> directors; private Instant released; private Awards awards; private List<Comment> comments; public Movie(String title, String plot, int year, List<String> cast, List<String> directors, Instant released, Awards awards) { this.title = title; this.plot = plot; this.year = year; this.cast = cast; this.directors = directors; this.released = released; this.awards = awards; } 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; } public List<String> getDirectors() { return directors; } public void setDirectors(List<String> directors) { this.directors = directors; } public Awards getAwards() { return awards; } public void setAwards(Awards awards) { this.awards = awards; } public Instant getReleased() { return released; } public void setReleased(Instant released) { this.released = released; } public List<Comment> getComments() { return comments; } public void setComments(List<Comment> comments) { this.comments = comments; } }
Para aprender a crear una aplicación Java que utilice la extensión MongoDB para Hibernate ORM para interactuar con esta colección de muestra de MongoDB, consulta el tutorial Primeros pasos.
Los ejemplos de esta guía utilizan el campo released de la entidad Movie, que almacena un valor Instant.
Extraer un campo de fecha y hora
Puedes usar la función extract() para devolver una parte específica de un valor de fecha y hora, como el año, el mes o el día.
La función extract(field from x) devuelve un único campo de un valor de fecha y hora. La extensión Hibernate ORM admite los siguientes valores para field:
Campo | Traducción de MongoDB |
|---|---|
|
|
| Calculado dividiendo |
|
|
|
|
| Calculado a partir de |
| Calculado a partir de |
|
|
|
|
|
|
|
|
|
|
| Calculado a partir de |
| Calculado a partir de |
| Calculado como el número de segundos completos desde la época Unix. |
El siguiente ejemplo devuelve el título de cada película "Hairspray" de la colección sample_mflix.movies y el año en que se estrenó:
var extractResult = session.createQuery( "select title, extract(year from released) as releaseYear from Movie where title = :title", Object[].class) .setParameter("title", "Hairspray") .getResultList(); for (var row : extractResult) { System.out.println("Title: " + row[0] + ", Release Year: " + row[1]); }
var extractResult = entityManager.createQuery( "select m.title, extract(year from m.released) as releaseYear from Movie m where m.title = :title", Object[].class) .setParameter("title", "Hairspray") .getResultList(); for (var row : extractResult) { System.out.println("Title: " + row[0] + ", Release Year: " + row[1]); }
La extensión Hibernate ORM traduce la consulta anterior a la siguiente etapa $project, en la que America/New_York es la zona horaria predeterminada de la JVM:
{ "$project": { "title": true, "releaseYear": { "$year": { "date": "$released", "timezone": { "$literal": "America/New_York" } } }, "_id": 0 } }
Importante
Numeración de los días de la semana
El campo day of week devuelve el valor $dayOfWeek de MongoDB, que numera los días desde 1 (domingo) hasta 7 (sábado). Esto difiere de la enumeración DayOfWeek de Java, que numera los días desde 1 (lunes) hasta 7 (domingo).
La extensión Hibernate ORM no admite los campos date, time, offset, timezone_hour y timezone_minute. Una consulta que extrae un campo no admitido genera un error FeatureNotSupportedException.
Formatear una fecha y hora como una cadena
La función format(x as pattern) convierte un valor de fecha y hora en una cadena de texto. La extensión Hibernate ORM traduce la llamada al operador $dateToString de MongoDB y asigna cada código de patrón al especificador de formato equivalente de MongoDB. También puede llamar a la función como format(x, pattern) y pasarle directamente los especificadores de formato de MongoDB.
La extensión Hibernate ORM admite los siguientes códigos de patrón:
Código de patrón | Descripción | Especificador de MongoDB |
|---|---|---|
| Año de cuatro dígitos |
|
| Año basado en la semana ISO-8601 de cuatro dígitos |
|
| Mes de dos dígitos |
|
| Nombre abreviado del mes |
|
| Nombre completo del mes |
|
| Número de semana ISO-8601 de dos dígitos |
|
| Día del mes de dos dígitos |
|
| Día del año |
|
| Hora de dos dígitos en un reloj de 24 horas |
|
| Minuto de dos dígitos |
|
| Segundo de dos dígitos |
|
| Milisegundos de tres dígitos |
|
| Diferencia horaria UTC |
|
MongoDB devuelve los nombres de los meses y los días en la configuración regional de EE. UU. Los caracteres que se encierran entre comillas simples se muestran en la salida sin interpretarse como códigos de patrón.
El siguiente ejemplo devuelve el título de cada película "Hairspray" y su fecha de estreno como una cadena yyyy-MM-dd:
var formatResult = session.createQuery( "select title, format(released as 'yyyy-MM-dd') as releaseDate from Movie where title = :title", Object[].class) .setParameter("title", "Hairspray") .getResultList(); for (var row : formatResult) { System.out.println("Title: " + row[0] + ", Release Date: " + row[1]); }
Si prefiere utilizar especificadores de formato de MongoDB, puede llamar a la función como format(released, '%Y-%m-%d').
var formatResult = entityManager.createQuery( "select m.title, format(m.released as 'yyyy-MM-dd') as releaseDate from Movie m where m.title = :title", Object[].class) .setParameter("title", "Hairspray") .getResultList(); for (var row : formatResult) { System.out.println("Title: " + row[0] + ", Release Date: " + row[1]); }
Si prefiere utilizar especificadores de formato de MongoDB, puede llamar a la función como format(m.released, '%Y-%m-%d').
La extensión Hibernate ORM traduce la consulta anterior a la siguiente etapa $project:
{ "$project": { "title": true, "releaseDate": { "$dateToString": { "date": "$released", "format": { "$literal": "%Y-%m-%d" }, "timezone": { "$literal": "America/New_York" } } }, "_id": 0 } }
Una consulta que utiliza un código de patrón fuera de la tabla anterior genera una excepción FeatureNotSupportedException. Esto incluye códigos de un solo carácter y de ancho variable como y, M, d, H, h, m, s y a, ya que MongoDB no tiene un especificador equivalente para ellos. Un código de zona horaria repetido de más de tres caracteres, como ZZZZZZZ, es ambiguo y también genera una excepción.
Información Adicional
Para obtener más información sobre cómo crear filtros de consulta y utilizar operadores en sus sentencias de consulta, consulte la guía Especificar una consulta.
Para aprender más sobre el uso de HQL y JPQL para ejecutar queries, consulte Una guía sobre el languaje del query de Hibernate en la documentación de Hibernate ORM.