jpa 分页 排序 过滤
Primefaces数据表惰性分页有效,但是在Web上使用Criteria搜索完整示例后,我感到非常沮丧。 所以我混合了来自
- http://stackoverflow.com/questions/13972193/how-to-query-data-for-primefaces-datatable-with-lazy-loading-and-pagination
- http://www.primefaces.org/showcase/ui/datatableLazy.jsf
- http://www.javacodegeeks.com/2012/04/lazy-jsf-primefaces-datatable.html
使用以下命令将所有内容放到一个完整的示例中:
- Primefaces 4.0
- TomEE 1.6.0以上
- 标准JPA
带有:
- 筛选
- 排序
- 分页
- 使用@ViewScoped托管豆
让我们开始吧:
xhtml片段
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<h:body>
<h:form id="am">
<p:dataTable
var="element"
value="#{inventoryManagerMB.model}"
lazy="true"
paginator="true"
rows="10"
paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}"
rowsPerPageTemplate="10,50,100"
id="sites">
<p:column sortBy="id" filterBy="id" filterMatchMode="contains" headerText="ID">
<h:outputText value="#{element.id}" />
</p:column>
<p:column sortBy="name" filterBy="name" filterMatchMode="contains" headerText="Name">
<h:outputText value="#{element.name}" />
</p:column>
<p:column sortBy="siteType.name" filterBy="siteType.name" filterMatchMode="contains" headerText="Type">
<h:outputText value="#{element.siteType.name}" />
</p:column>
<p:column sortBy="ip" filterBy="ip" filterMatchMode="contains" headerText="IP">
<h:outputText value="#{element.ip} " />
</p:column>
<p:column sortBy="description" filterBy="description" filterMatchMode="contains" headerText="Description">
<h:outputText value="#{element.description}" />
</p:column>
</p:dataTable>
</h:form>
</h:body>
</html>
ManagedBean
@ManagedBean
@ViewScoped
public class InventoryManagerMB implements Serializable {
private static final long serialVersionUID = -1201944101993687165L;
@EJB
private InventoryManagerEJB inventoryManagerEJB;
private LazyDataModel<Site> model;
@PostConstruct
public void init() {
try {
this.model = new LazyDataModel<Site>(){
private static final long serialVersionUID = 1L;
@Override
public List<Site> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, String> filters) {
List<Site> result = inventoryManagerEJB.getResultList(first, pageSize, sortField, sortOrder, filters);
model.setRowCount(inventoryManagerEJB.count(sortField, sortOrder, filters));
return result;
}
};
}
public LazyDataModel<Site> getModel() {
return model;
}
public void setModel(LazyDataModel<Site> model) {
this.model = model;
}
(...)
EJB
@Stateless
public class InventoryManagerEJB {
@Inject
private BaseService baseService;
public List<Site> getResultList(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, String> filters) {
List<Site> all = new ArrayList<Site>();
all.addAll(this.baseService.getSiteDAO().getAll(first,pageSize,sortField,sortOrder,filters));
return all;
}
public int count(String sortField, SortOrder sortOrder, Map<String, String> filters) {
return this.baseService.getSiteDAO().getAll(-1,-1,null,null,filters).size();
}
}
基本服务
@ApplicationScoped
public class BaseService implements Serializable{
private static Logger log = Logger.getLogger(BaseService.class);
/*
* persistence
*/
private static final long serialVersionUID = 588696475267901772L;
@PersistenceContext
private EntityManager entityManager;
private SiteDAO siteDAO;
@PostConstruct
public void init() {
siteDAO = new SiteDAO(entityManager);
}
public SiteDAO getSiteDAO() {
return siteDAO;
}
SiteDAO
public class SiteDAO extends GenericDAO<Site>{
public SiteDAO(EntityManager entityManager) {
super(entityManager);
}
public Collection<Site> getAll(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, String> filters) {
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Site> q = cb.createQuery(Site.class);
Root<Site> site = q.from(Site.class);
Join<Site,SiteType> siteType = site.join(Site_.siteType);
q.select(site);
Path<?> path = getPath(sortField, site, siteType);
if (sortOrder == null){
//just don't sort
}else if (sortOrder.equals(SortOrder.ASCENDING)){
q.orderBy(cb.asc(path));
}else if (sortOrder.equals(SortOrder.DESCENDING)){
q.orderBy(cb.asc(path));
}else if (sortOrder.equals(SortOrder.UNSORTED)){
//just don't sort
}else{
//just don't sort
}
//filter
Predicate filterCondition = cb.conjunction();
for (Map.Entry<String, String> filter : filters.entrySet()) {
if (!filter.getValue().equals("")) {
//try as string using like
Path<String> pathFilter = getStringPath(filter.getKey(), site, siteType);
if (pathFilter != null){
filterCondition = cb.and(filterCondition, cb.like(pathFilter, "%"+filter.getValue()+"%"));
}else{
//try as non-string using equal
Path<?> pathFilterNonString = getPath(filter.getKey(), site, siteType);
filterCondition = cb.and(filterCondition, cb.equal(pathFilterNonString, filter.getValue()));
}
}
}
q.where(filterCondition);
//pagination
TypedQuery<Site> tq = entityManager.createQuery(q);
if (pageSize >= 0){
tq.setMaxResults(pageSize);
}
if (first >= 0){
tq.setFirstResult(first);
}
return tq.getResultList();
}
private Path<?> getPath(String field, Root<Site> site, Join<Site, SiteType> siteType) {
//sort
Path<?> path = null;
if (field == null){
path = site.get(Site_.name);
}else{
switch(field){
case "id":
path = site.get(Site_.id);
break;
case "name":
path = site.get(Site_.name);
break;
case "siteType.name":
path = siteType.get(SiteType_.name);
break;
case "ip":
path = site.get(Site_.ip);
break;
case "description":
path = site.get(Site_.description);
break;
}
}
return path;
}
private Path<String> getStringPath(String field, Root<Site> site, Join<Site, SiteType> siteType) {
//sort
Path<String> path = null;
if (field == null){
path = site.get(Site_.name);
}else{
switch(field){
case "id":
path = null;
break;
case "name":
path = site.get(Site_.name);
break;
case "siteType.name":
path = siteType.get(SiteType_.name);
break;
case "ip":
path = site.get(Site_.ip);
break;
case "description":
path = site.get(Site_.description);
break;
}
}
return path;
}
}
实体
@Entity
@Table(uniqueConstraints=@UniqueConstraint(columnNames={"name"}))
public class Site implements Serializable {
/**
*
*/
private static final long serialVersionUID = 8008732613898597654L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Nameable
@Column(nullable=false)
private String name;
private String ip;
private String description;
@ManyToOne
@JoinColumn(name="siteTypeId")
private SiteType siteType;
(...)
}
而已。 请享用。
参考: Primefaces DataTable使用我们的JCG合作伙伴 Leonardo Shikida的@ViewScoped 通过JPA Criteria进行分页,筛选和排序的延迟加载,在Leo的Notepad博客上。
jpa 分页 排序 过滤