我们有一个包含历史数据的表:id,部门,totalInsert,totalUpdates,createdTime
每1小时插入一次数据。
基于上述数据,我们需要按照提供的持续时间和间隔获取数据。
例如: 持续时间= 24小时,间隔= 1小时 然后应每1小时间隔获取最近24小时的数据。 (24条记录)
持续时间= 24小时,间隔= 4小时 然后应每4小时间隔获取最近24小时的数据。 (6条记录)
持续时间= 7天,间隔= 1天 那么每天应为每1个条目提取7天的数据。 (7条记录)
持续时间= 21天,间隔= 7天 那么每周应为每1个条目提取21天的数据。 (3条记录)
因此,您是否可以帮助对以上所有可能的情况进行通用查询。 不想为用户提供的每个输入单独查询。
到目前为止已尝试:
SELECT * FROM department_details哪里输入ID(SELECT MAX(id)从 department_details WHERE department ='计算机技术'AND (((date(createdDate)>'2019-01-09'AND date(createdDate)<= '2019-01-10')或(日期(createdDate)>'2019-01-15'和 date(createdDate)<='2019-01-16')OR(date(createdDate)> '2019-01-21'AND日期(createdDate)<='2019-01-22')OR
(date(createdDate)>'2019-01-27'AND date(createdDate)<= '2019-01-28')OR(日期(创建日期)>'2019-02-02'和 date(createdDate)<='2019-02-03'))GROUP BY date(createdDate))ORDER BY createdDate;
寻找通用JPA标准解决方案
答案 0 :(得分:0)
我已经建立了一个行家例子。您必须将createdTime
存储为Long
(请参阅HistoricalData#createdTime
)。在App#getData
中,您可以看到间隔的用法。
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>de.dbh.basis.legacy</groupId>
<artifactId>JpaTest</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>5.4.1.Final</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.6</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.197</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
</dependencies>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
</project>
persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="test" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name="javax.persistence.jdbc.url" value="jdbc:h2:mem:test;MVCC=1"/>
<property name="javax.persistence.jdbc.user" value="sa"/>
<property name="javax.persistence.jdbc.driver" value="org.h2.Driver"/>
<property name="javax.persistence.jdbc.password" value=""/>
<property name="javax.persistence.schema-generation.database.action" value="create"/>
</properties>
</persistence-unit>
</persistence>
HistoricalData.java (实体)
import java.io.Serializable;
import java.util.Date;
import javax.persistence.Entity;
import javax.persistence.Id;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@Entity
@Getter @Setter
@ToString
public class HistoricalData implements Serializable {
@Id
private int id;
private String department;
// The createdTime will be stored as a Long
private Long createdTime;
public HistoricalData() {
}
public HistoricalData(int id, String department, Date createdTime) {
this.id = id;
this.department = department;
this.createdTime = createdTime.getTime();
}
public Date getCreatedTime() {
return new Date(createdTime);
}
public void setCreatedTime(Date createdTime){
this.createdTime = (createdTime == null ? null : createdTime.getTime());
}
}
App.java (重要部分)
import java.util.Calendar;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import org.apache.commons.lang.time.DateUtils;
public class App {
private static EntityManagerFactory emf;
public static void main(String[] args) {
// Build the query
emf = Persistence.createEntityManagerFactory("test");
// Persistence Preparation
fillDatabase();
// Define start and end date (must be a full hour)
Calendar from = DateUtils.round(Calendar.getInstance(), Calendar.HOUR_OF_DAY);
from.add(Calendar.WEEK_OF_YEAR, -4);
Calendar to = Calendar.getInstance();
// Define interval - One day in milliseconds (must be a multiple of one hour
int interval = 1000 * 60 * 60 * 24;
// Do the query
List<HistoricalData> data = getData(from, to, interval);
System.out.println("DATA: "+data.size());
for( HistoricalData item : data ){
System.out.println(item);
}
}
private static List<HistoricalData> getData(Calendar from, Calendar to, int interval){
EntityManager em = emf.createEntityManager();
CriteriaBuilder b = em.getCriteriaBuilder();
CriteriaQuery<HistoricalData> q = b.createQuery(HistoricalData.class);
Root r = q.from(HistoricalData.class);
q.where(b.and(
// search all data between 'from' till 'to' date
b.greaterThanOrEqualTo(r.get("createdTime"), from.getTime().getTime()),
b.lessThanOrEqualTo(r.get("createdTime"), to.getTime().getTime()),
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//
// Here we have your interval
//
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
b.equal(b.mod(b.diff(r.get("createdTime"), from.getTime().getTime()), interval), 0)
));
return em.createQuery(q).getResultList();
}
private static void fillDatabase(){
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
Calendar cal = DateUtils.round(Calendar.getInstance(), Calendar.HOUR_OF_DAY);
// Insert Data into the database (8 weeks - every hour)
for (int i = 0; i < 24*8; i++) {
HistoricalData data = new HistoricalData(i, "Department " + i, cal.getTime());
em.persist(data);
cal.add(Calendar.HOUR, -1);
}
em.getTransaction().commit();
}
}