Знаете ли вы это чувство, когда каждый код, который вы пишете, работает мгновенно и вы нарушаете свой график :-P Это похоже на «о да, теперь у меня есть время, чтобы сделать его идеальным» ». Вот где я сейчас нахожусь ^^
Так что я реализовал ретранслятор с JSF (ui: repeat), и я подумал о подкачке для всех сущностей. Есть ли простой способ сделать это? Какие моменты я должен думать?
Было бы неплохо, если бы кто-нибудь помог мне. Мои навыки googleskills не помогли мне до сих пор :-P
Приветствия ...
Вот простой пример, который должен дать вам представление о том, как это реализовать.
RepeatPaginator:
public class RepeatPaginator {
private static final int DEFAULT_RECORDS_NUMBER = 2;
private static final int DEFAULT_PAGE_INDEX = 1;
private int records;
private int recordsTotal;
private int pageIndex;
private int pages;
private List<?> origModel;
private List<?> model;
public RepeatPaginator(List<?> model) {
this.origModel = model;
this.records = DEFAULT_RECORDS_NUMBER;
this.pageIndex = DEFAULT_PAGE_INDEX;
this.recordsTotal = model.size();
if (records > 0) {
pages = records <= 0 ? 1 : recordsTotal / records;
if (recordsTotal % records > 0) {
pages++;
}
if (pages == 0) {
pages = 1;
}
} else {
records = 1;
pages = 1;
}
updateModel();
}
public void updateModel() {
int fromIndex = getFirst();
int toIndex = getFirst() + records;
if(toIndex > this.recordsTotal) {
toIndex = this.recordsTotal;
}
this.model = origModel.subList(fromIndex, toIndex);
}
public void next() {
if(this.pageIndex < pages) {
this.pageIndex++;
}
updateModel();
}
public void prev() {
if(this.pageIndex > 1) {
this.pageIndex--;
}
updateModel();
}
public int getRecords() {
return records;
}
public int getRecordsTotal() {
return recordsTotal;
}
public int getPageIndex() {
return pageIndex;
}
public int getPages() {
return pages;
}
public int getFirst() {
return (pageIndex * records) - records;
}
public List<?> getModel() {
return model;
}
public void setPageIndex(int pageIndex) {
this.pageIndex = pageIndex;
}
}
Bean:
public class TestBean {
private List<String> list;
private RepeatPaginator paginator;
@PostConstruct
public void init() {
this.list = new ArrayList<String>();
this.list.add("Item 1");
this.list.add("Item 2");
this.list.add("Item 3");
this.list.add("Item 4");
this.list.add("Item 5");
this.list.add("Item 6");
this.list.add("Item 7");
this.list.add("Item 8");
this.list.add("Item 9");
this.list.add("Item 10");
this.list.add("Item 11");
paginator = new RepeatPaginator(this.list);
}
public RepeatPaginator getPaginator() {
return paginator;
}
}
XHTML:
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
template="/WEB-INF/template/default.xhtml">
<ui:define name="content">
<h:form>
<ui:repeat value="#{testBean.paginator.model}" var="listItem">
<div>
<h:outputText value="#{listItem}"/>
</div>
</ui:repeat>
<h:commandButton value="< prev" action="#{testBean.paginator.prev}"/>
<h:outputText value="#{testBean.paginator.pageIndex} / #{testBean.paginator.pages}"/>
<h:commandButton value="next >" action="#{testBean.paginator.next}"/>
<h:inputHidden value="#{testBean.paginator.pageIndex}"/>
</h:form>
</ui:define>
</ui:composition>
Пагинация на страницы на самом деле проста. Вам просто нужно постоянно передавать один или два параметра: firstrow
и, возможно, rowcount
(который также может храниться на стороне сервера).Когда конечный пользователь щелкает Далее , вы просто увеличиваете значение firstrow
на значение rowcount
. Когда конечный пользователь нажимает Назад , вы просто уменьшаете значение firstrow
на значение rowcount
. Вам нужно только проверить, не выходит ли он за границы 0
и totalrows
, и внести соответствующие изменения.
Затем, основываясь на желаемом firstrow
и rowcount
, вы точно знаете, какие данные отображать. Если все данные уже находятся в некотором List
в памяти Java, тогда вы просто используете List # subList ()
, чтобы получить из него подсписок для отображения. Однако неэффективно дублировать всю таблицу базы данных в памяти Java. Это может не повредить, когда это всего 100 строк, но когда это намного больше, и / или вы дублируете его для каждого отдельного пользователя, тогда приложению очень скоро не хватит памяти.
В этом случае вы предпочтете разбивать страницы на уровне базы данных. Например, в MySQL вы можете использовать предложение LIMIT
для получения подмножества результатов из БД. JPA / Hibernate даже предоставляет способы использования setFirstResult ()
и setMaxResults ()
методов Query
и Criteria
соответственно. Вы можете найти примеры в этом и этом ответах.
Вы можете найти базовый пример целевого запуска JSF 1.2 с разбивкой на страницы (и сортировкой) в стиле Google в этой статье . Он использует компоненты Tomahawk, но в JSF 2.0 вы можете просто оставить их, сделав bean @ViewScoped
(заменяет t: saveState
) и используя ui: repeat
(заменяет t: dataList
).
И последнее, но не менее важное: существует множество библиотек компонентов, которые выполняют всю работу в одном компоненте. Например, RichFaces
и PrimeFaces
(также можно сделать ajaxical ).