我处理某种缓存,有时,我们需要根据 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/