java - 在 JPQL 中将表修剪为 500 条记录

标签 java jpa jpql

我处理某种缓存,有时,我们需要根据 last_access_date 将表修剪为 500 条记录(仅保留最近访问的 500 行)。

使用“普通”SQL,可以通过以下方式完成:

DELETE FROM records WHERE id not in 
    (SELECT id FROM records ORDER BY last_access_date DESC LIMIT 500)

现在 JPQL 中没有 LIMIT 或类似 ROWNUM 的东西,我找到的唯一解决方案是使用原生 SQL,这是次优的,因为我们在多个 DBMS 上运行(至少 Oracle 和 MSSQL)。

此外,setMaxResults() (LIMIT 的 JPQL 版本)似乎对 DELETE 语句无效。

真的没有办法用 JPQL 解决这个问题吗?

最佳答案

你可以这样做:

String sql = "SELECT x.id FROM records x ORDER BY x.last_access_date DESC";
TypedQuery<Long> query = em.createQuery(sql, Long.class);

List<Long> ids = query.setMaxResults(500).getResultList();

String delete = "DELETE FROM records x where x.id not in :ids";
em.createQuery(delete).setParameter("ids", ids).executeUpdate();

我不记得删除查询的确切语法,因此您可能必须将 :ids 放在括号之间,例如:

String delete = "DELETE FROM records x where x.id not in (:ids)";

编辑: dkb提出了一个更快的评论解决方案(取决于唯一日期以确保剩余行数的完美准确性):

String sql = "SELECT x.last_access_date FROM records x ORDER BY x.last_access_date DESC";

//If you're not using calendar, change to your specific date class
TypedQuery<Calendar> query = em.createQuery(sql, Calendar.class);

Calendar lastDate = query.setFirstResult(499).setMaxResults(1).getSingleResult();

String delete = "DELETE FROM records x where x.last_access_date < :lastDate";
em.createQuery(delete).setParameter("lastDate", lastDate, TemporalType.DATE).executeUpdate();

关于java - 在 JPQL 中将表修剪为 500 条记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54648282/

相关文章:

hibernate - 为什么在 JPQL 中使用 "SELECT c"而不是 "SELECT * "?

java - JPQL查询异常异常AST节点: {vector}

java - JPA冗余数据库

java.lang.ClassCastException : com. example.Entity 无法转换为 com.example.Entity

java - 使用 Hibernate 在 CollectionTable 的列上创建索引

mysql - 定期删除数据库中超过一个月的所有条目的最有效方法

java - 如何在 Java 中比较字符串?

java - jTextField 和 Jpanel 颜色输出

Java,创建 JComboBox 并添加到年份范围

java - 将 SQLite 数据库导出到 Android 中的 XML 文件