我正在使用来自Primefaces的Datatable,延迟加载。筛选值时,返回的记录的大小小于我用于寻呼机的绝对计数。因此,数据表中存在空白页。但我也不能使用从查询中获得的记录大小的大小,因为查询可能只返回一个子集。
例:数据库中有 30 条记录,数据表中的页面大小为 10,所以有 3 页,每个延迟加载请求我返回 10 条记录。
当我输入过滤器时,只剩下 20 条记录。由于绝对计数,寻呼机仍显示 3 页。但是,当我将记录计数更改为返回的 10 条记录时,没有第二页。那么如何获取所有筛选记录的计数呢?有自己的查询?
我使用以下策略。
首先,我创建了一个通用数据模型。此数据模型取决于我设计实体 (JPA)、筛选器类和可分页服务的方式。请注意,我使用 pojo 来传输搜索条件,您需要进行一些小的更改才能使用地图过滤器参数。
以下是生成的数据模型:
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.primefaces.model.LazyDataModel;
import org.primefaces.model.SortMeta;
import org.primefaces.model.SortOrder;
public class GenericDataModel<ENTITY extends AbstractEntity, FILTER extends AbstractFilter, SERVICE extends Paginable<ENTITY, FILTER>>
extends LazyDataModel<ENTITY> {
private FILTER filter;
private SERVICE service;
private boolean started;
//use this constructor if you want to show some result on page load
public GenericDataModel(FILTER filter, SERVICE service) {
this(filter, service, true);
}
public GenericDataModel(FILTER filter, SERVICE service, boolean autoStart) {
this.filter = filter;
this.service = service;
started = autoStart;
count();
}
@Override
public List<ENTITY> load(int first, int pageSize,
List<SortMeta> multiSortMeta, Map<String, String> filters) {
if (!started) {
return new ArrayList<ENTITY>();
}
if (getRowCount() <= 0) {
count();
}
//deal with sorting here. I do that by inserting them into the filter.
return service.find(filter);
}
@Override
public List<ENTITY> load(int first, int pageSize, String sortField,
SortOrder sortOrder, Map<String, String> filters) {
if (!started) {
return new ArrayList<ENTITY>();
}
if (getRowCount() <= 0) {
count();
}
//deal with sorting here. I do that by inserting them into the filter.
return service.find(filter);
}
public void count() {
if (!started) {
setRowCount(0);
return;
}
Long rowCount = service.count(filter);
setRowCount(rowCount == null ? 0 : rowCount.intValue());
}
public void start() {
started = true;
}
}
以下是我在托管 bean 上使用它的方式:
@Inject
private ProfessorService professorService;
private ProfessorFilter professorFilter;
private GenericDataModel<Professor, ProfessorFilter, ProfessorService> dataModel;
@PostConstruct
public String setup() {
professorFilter = new ProfessorFilter();
dataModel = new GenericDataModel(professorFilter, professorService, false);
return null;
}
//action for the search button on the view
public void search() {
dataModel.start();
dataModel.count();
}
paginableService.count 方法使用与paginableService.find(filter)
方法的结果查询相同的连接和 where 子句执行select count(*)
。
对于非常大的数据,您可能会发现这种额外的查询可能会浪费时间和资源,但请记住,只有在搜索条件更改时,才会完成此额外查询。
几乎是的,使用您自己的查询:
关于您的问题的一些讨论:使用 JPA 条件 API 进行分页的总行数