Pergunta

Eu quero executar operações de tempo de dados usando hibernate HQL.

Eu quero somar e subtrair duas datas tão bem quanto eu quiser subtrair 1 ano ou 1 mês a partir de uma determinada data.

Como isso é possível usando HQL em hibernação?

Foi útil?

Solução

Veja Realizando Data / Hora Math Em HQL? para um exemplo.

Para usar personalizado sql você deve escreveu um dialeto próprio hibernação e registrar:

registerFunction("weekday", 
  new SQLFunctionTemplate(Hibernate.INTEGER, "to_char(?1,'D')") );

Outras dicas

Você precisa criar o seu próprio dialeto. Algo como o seguinte:

public class MyDialect extends MySQLInnoDBDialect{
      public myDialect() {
      super();
      registerFunction("date_add_interval", new SQLFunctionTemplate(Hibernate.DATE, "date_add(?1, INTERVAL ?2 ?3)"));
      }
    }

Em Hibernate / MySQL (pelo menos) Você pode converter de e para um Unix Timestamp. Desde o timestamp unix é um inteiro que você pode adicionar um número inteiro de segundos a ele.

FROM_UNIXTIME(UNIX_TIMESTAMP(date)+ (allowedTimeWindow*86400)) as deadline

Ele tem limitações, mas é muito mais fácil do que as abordagens acima.

Esta é uma questão em aberto no Hibernate. A partir de Hibernate 3.3 não há nenhuma maneira padrão para comparações de data alça puramente em HQL:

https://hibernate.atlassian.net/browse/HHH-2434

Hibernate 4.3 oferece funções para acessar data / hora no HQL que são:

current_timestamp() , current_date() , current_time()

As operações aritméticas podem ser gerenciados por:

SECOND(...) , MINUTE(...) , HOUR(...) , DAY(...) , MONTH(...) , YEAR(...)

Disclaimer: Eu sou um novato Java

Eu era capaz de usar current_date() >= fromDate AND dateadd(day, -1, getdate()) <= toDate em uma declaração HQL contra um db Sybase no Hibernate 3.5.3, sem registrar quaisquer funções.

Exemplo de Uso de aproximação com dialeto para JPA + Hibernate 4.3.1 + MySQL 5

classe pública SampleMySQL5InnoDBDialect estende org.hibernate.dialect.MySQL5InnoDBDialect {

public SampleMySQL5InnoDBDialect() {
    super();
    registerFunction("date_sub_days", new SQLFunctionTemplate(StandardBasicTypes.DATE, "date_sub(?1, interval ?2 day)"));
}

, em seguida, para a sua classe com a anotação de mapeamento:

@NamedQuery(name = "SampleEntity.getSampleEntitiesForGapOverlapCalculations", query = "from SampleEntity as se where "
    + "((se.toDate between :startDate and :endDate) or (date_sub_days(se.toDate, se.duration) between :startDate and :endDate)) order by se.toDate asc, se.duration desc")

SampleEntity tem toDate campo do tipo java.sql.Date e duração campo inteiro (duração em dias) e estamos calculando fromDate = toDate - duração e selecionar todas as entidades que têm fromDate ou toDate dentro do intervalo [startDate, endDate] .

Hibernate4.3 fornece funções nativas Datas de acesso / Timestamps e para executar operações arithmatic sobre eles

Aqui é o link para a documentação do que expressões podem ser usadas em HQL. Alguns dos quais eu estou mencionando: Para data de acesso / hora:

current_date(), current_time(), and current_timestamp()

As operações aritméticas podem ser feito seguindo. Estas funções levar tempo como entrada:

second(...), minute(...), hour(...), day(...), month(...), and year(...)

Pode-se obter diferença absoluta de em HQL por

current_timestamp() - dateInstance

onde dateInstance pode ter definição

@Column(name = "updated_at")
@Temporal(TemporalType.TIMESTAMP)
private java.util.Date updatedAt;

O resultado é em 0,1 segundos. Assim, para uma diferença absoluta de 1 segundo, a expressão acima dará resultado como 10.

Assim, uma consulta seria algo como:

select t from Table t where (current_timestamp() - updatedAt)>600

usuários Postgres ...

registerFunction("dateadd", new SQLFunctionTemplate(StandardBasicTypes.DATE, "(?1 + INTERVAL ?2)"));

com SQL uso como:

now() < dateadd(:mydate, '-1 day')
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top