Visão geral
Neste guia, você pode aprender como chamar as funções extract() e format() da Hibernate linguagem de query (HQL) em um campo de data e hora usando a MongoDB Extension para Hibernate 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 Hibernate ORM traduz cada chamar 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 Hibernate ORM resolve cada função de data e hora na zona horária padrão da JVM que executa o aplicativo. Ele passa essa zona para o MongoDB como o argumento timezone do operador gerado. A mesma query pode retornar valores diferentes em hospedar configurados com zonas de horário diferentes.
Como a extensão Hibernate ORM não oferece suporte a chamadas de função como operandos de uma expressão computada, você não pode combinar uma função de data e hora com um operador aritmético. Para aprender mais, consulte a seção Usar expressões computadas do guia Especificar uma query.
Dados de amostra
Os exemplos neste guia usam a entidade Movie, que representa a coleção sample_mflix.movies dos conjuntos de dados de amostra do Atlas. A entidade Movie 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;
@Entity@Table(name = "movies")public class Movie { @Id @ObjectIdGenerator private ObjectId id; private String title; private String plot; private int year; private List<String> cast; private List<String> directors; private Instant released; @Embedded private Awards awards; @OneToMany(mappedBy = "movie", fetch = FetchType.LAZY) 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 campo released da entidade Movie, que armazena um valor Instant.
Extrair um campo de data e hora
Você pode usar a função extract() para retornar uma parte específica de um valor de data e 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 e hora. A extensão Hibernate ORM suporta os seguintes valores para field:
Campo | Tradução do MongoDB |
|---|---|
|
|
| Calculado dividindo |
|
|
|
|
| Calculado a partir de |
| Calculado a partir de |
|
|
|
|
|
|
|
|
|
|
| Calculado a partir de |
| Calculado a partir de |
| Calculado como o número de segundos inteiros desde a Era UNIX |
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 Hibernate ORM traduz a query anterior para o seguinte estágio $project, no qual America/New_York é a zona padrão da JVM:
{ "$project": { "title": true, "releaseYear": { "$year": { "date": "$released", "timezone": { "$literal": "America/New_York" } } }, "_id": 0 }}Importante
Numeração do dia da semana
O campo day of week retorna o valor $dayOfWeek do MongoDB, que numera os dias de 1 para domingo até 7 para sábado. Isso difere da enumeração Java DayOfWeek, que numera os dias de 1 para segunda-feira até 7 para domingo.
A extensão Hibernate ORM não oferece suporte aos campos date, time, offset, timezone_hour e timezone_minute. Uma query que extrai um campo não suportado gera um FeatureNotSupportedException.
Formate uma Datetime como uma string
A função format(x as pattern) renderiza um valor de data e hora como uma string. A extensão Hibernate ORM traduz chamar 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 do Hibernate ORM oferece suporte aos seguintes códigos de padrão:
Código de padrão | Descrição | Especificador do MongoDB |
|---|---|---|
| Ano com quatro dígitos |
|
| Ano de quatro dígitos baseado na semana ISO-8601 |
|
| Mês com dois dígitos |
|
| Nome do mês abreviado |
|
| Nome do mês inteiro |
|
| Número da semana ISO-8601 com dois dígitos |
|
| Dia do mês com dois dígitos |
|
| Dia do ano |
|
| Hora com dois dígitos em um relógio de 24horas |
|
| Minuto com dois dígitos |
|
| Segundo com dois dígitos |
|
| Milissegundos de três dígitos |
|
| UTC Offset |
|
O MongoDB retorna os nomes dos meses e dias na locale dos EUA. Os caracteres que você coloca entre aspas simples são passados 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 você quiser usar especificadores de formato do MongoDB, você pode chamar 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 você quiser usar especificadores de formato do MongoDB, você pode chamar a função como format(m.released, '%Y-%m-%d').
A extensão Hibernate ORM 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 um especificador equivalente para eles. Um código de zona de tempo repetido de mais de três caracteres, como ZZZZZZZ, é ambíguo e também gera uma exceção.
Informações adicionais
Para aprender mais sobre como criar filtros de queries e como usar operadores em suas declarações de query, consulte o guia Especifique 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.