Visão geral
Neste guia, você pode aprender a chamar as funções extract() e format() da Linguagem de Query do Hibernar (HQL) em um campo de data e hora usando a Extensão MongoDB para Hibernado ORM. Você pode usar extract() para retornar parte de um valor de data e hora e format() para renderizar um valor de data e hora como uma string.
A extensão ORM do Hibername traduz cada chamada para uma expressão de agregação do MongoDB no estágio $project. Você pode chamar qualquer função em um campo de data e hora em uma cláusula SELECT.
Observação
Fuso horário
A extensão ORM do Hibernar resolve cada função de data/hora no zona horário padrão da JVM que executa o aplicação. Ele passa essa zona para o MongoDB como o argumento timezone do operador gerado. A mesma query pode retornar valores diferentes em hosts configurados com fusos horários diferentes.
Como a extensão ORM do Hibernado não suporta chamadas de função como operandos de uma expressão computada, você não pode combinar uma função de data/hora com um operador aritmético. Para saber mais, consulte a seção Usar expressões computadas do guia Especificar uma query.
Dados de amostra
Os exemplos neste guia 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 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 como criar um aplicativo Java que use a Extensão MongoDB para Hibernate ORM para interagir com essa coleção de amostras do MongoDB, veja o tutorial Get Started.
Os exemplos neste guia usam o campoMovie da entidade released , que armazena um valor Instant.
Extrair um campo de data/hora
Você pode usar a função extract() para retornar uma parte específica de um valor de data/hora, como o ano, o mês ou o dia.
A função extract(field from x) retorna um único campo de um valor de data/hora. A extensão Hibernar ORM suporta os seguintes valores para o field:
Campo | Tradução do MongoDB |
|---|---|
|
|
| Computado dividindo |
|
|
|
|
| Computado a partir de |
| Computado a partir de |
|
|
|
|
|
|
|
|
|
|
| Computado a partir de |
| Computado de |
| Calculado como o número de segundos inteiros desde a Unix epoch |
O exemplo a seguir retorna o título de cada filme "Hairspray" na coleção sample_mflix.movies e o ano em que o filme foi lançado:
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]); }
A extensão ORM do Hibername traduz a query anterior para o seguinte estágio $project, no qual America/New_York é o zona horário padrão da JVM:
{ "$project": { "title": true, "releaseYear": { "$year": { "date": "$released", "timezone": { "$literal": "America/New_York" } } }, "_id": 0 } }
Importante
Numeração de dias da semana
O campo day of week retorna o valor do MongoDB $dayOfWeek, que numera dias de 1 para domingo a 7 para sábado. Isso difere do Java DayOfWeek enumeração, que numera dias de 1 para segunda-feira a 7 para domingo.
A extensão Hibernar ORM não suporta os campos date, time, offset, timezone_hour e timezone_minute. Uma query que extrai um campo não suportado lança um FeatureNotSupportedException.
Formatar uma data/hora como uma string
A função format(x as pattern) renderiza um valor de data/hora como uma string. A extensão Hibername ORM traduz a chamada para o operador MongoDB $dateToString e mapeia cada código de padrão para o especificador de formato MongoDB equivalente. Você também pode chamar a função como format(x, pattern) e passar os especificadores de formato do MongoDB diretamente.
A extensão Hibername ORM suporta os seguintes códigos de padrão:
Código de padrão | Descrição | Especificador do MongoDB |
|---|---|---|
| Ano de quatro dígitos |
|
| Ano baseado em semana de ISO-8601 de quatro dígitos |
|
| Mês de dois dígitos |
|
| Nome do mês abreviado |
|
| Nome do mês inteiro |
|
| Número da semana ISO-8601 de dois dígitos |
|
| Dia do mês com dois dígitos |
|
| Dia do ano |
|
| Hora de dois dígitos em um relógio de 24 horas |
|
| Minuto de dois dígitos |
|
| Segundo de dois dígitos |
|
| Milissegundo de três dígitos |
|
| UTC offset |
|
O MongoDB retorna nomes de meses e dias na locale dos EUA . Os caracteres que você coloca entre aspas simples passam para a saída sem serem interpretados como códigos de padrão.
O exemplo a seguir retorna o título de cada filme "Hairspray" e sua data de lançamento como uma string 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]); }
Se, em vez disso, você quiser usar os especificadores de formato do MongoDB , chame a função 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]); }
Se, em vez disso, você quiser usar os especificadores de formato do MongoDB , chame a função como format(m.released, '%Y-%m-%d').
A extensão ORM do Hibername traduz a query anterior para o seguinte estágio $project:
{ "$project": { "title": true, "releaseDate": { "$dateToString": { "date": "$released", "format": { "$literal": "%Y-%m-%d" }, "timezone": { "$literal": "America/New_York" } } }, "_id": 0 } }
Uma query que usa um código de padrão fora da tabela anterior gera um FeatureNotSupportedException. Isso inclui códigos de caractere único e de largura variável, como y, M, d, H, h, m, s e a, porque o MongoDB não tem equivalente especificador para eles. Um código de zona horário repetido de mais de três caracteres, como ZZZZZZZ, é ambíguo e também lança uma exceção.
Informações adicionais
Para saber mais sobre como criar filtros de query e usar operadores em suas declarações de query, consulte o guia Especificar uma query.
Para saber mais sobre como usar HQL e JPQL para executar queries, consulte Um guia para a linguagem de query do Hibernate na documentação do Hibernate ORM.