3.2.6.2.4. 去重查询

如果一个界面包含带分页的表格,以及用于加载数据的 JPQL 查询,由于应用了通用过滤器或访问组约束,JPQL 查询在运行时会被修改。在 JPQL 查询中省略 distinct 运算符时会发生以下情况:

  • 如果在数据库级别进行数据集合的组合,则加载的数据集将包含重复行。

  • 在客户端级别,由于数据被添加到 map 中(java.util.Map),重复项在数据源中会消失。

  • 对于分页表格,界面可能显示的行数少于请求的行数,而总行数超出请求的数量。

因此,我们建议在 JPQL 查询中包含 distinct,以确保从数据库返回的数据集中不存在重复项。但是,如果返回的记录数很大(超过 10000),则在使用 distinct 执行 SQL 查询时,某些数据库服务器(特别是 PostgreSQL)会出现性能问题。

为了解决这个问题,平台包含一种在 SQL 级别上没有 distinct 的情况下正常运行的机制。此机制由 cuba.inMemoryDistinct 应用程序属性启用。启用后,会执行以下操作:

  • JPQL 查询仍然应包含 select distinct

  • 在将数据发送到 ORM 之前,DataManager 会从 JPQL 查询中删除 distinct

  • 数据页由 DataManager 加载后,会删除重复项在 DB 运行其它查询,用来检索返回给客户端需要的行数。