基于rich:datascroller和rich:dataTable的分页查询实现

基于Seam/JSF开发,直接使用Rich组件确实是使界面达到较为美观和专业的最简单途径。

 

一般来说,基于rich:datascroller和rich:dataTable进行配合,马上就实现了表格及分页,但这种分布是一种“伪分页”,即:只是表现层分页,在数据层并没有进行分页查询。

 

下面给出一个我在使用的支持数据层分布查询的方法:

 

基类:

 

public abstract class BaseExtendedDataModel<T, ID extends Serializable> extends ExtendedDataModel {
	@Logger
	private Log log;

	public List<T> listRow = null;
	private int firstRow_old = 0;

	private ID currentId;
	private Map<ID, T> wrappedData = new HashMap<ID, T>();
	private Long rowCount; // better to buffer row count locally

	public abstract Long getCount();

	public abstract List<T> getList(Integer firstRow, Integer maxResults);

	public abstract T findById(ID id);

	public void wrap(FacesContext context, DataVisitor visitor, Range range, Object argument, List<T> list) throws IOException {
		wrappedData = new HashMap<ID, T>();
		for (T row : list) {
			ID id = null;
			try {
				id = (ID) PropertyUtils.getProperty(row, "id");
			} catch (Exception e) {
				e.printStackTrace();
				throw new RuntimeException(e);
			}
			// wrappedKeys.add(id);
			wrappedData.put(id, row);
			visitor.process(context, id, argument);
		}
	}

	public boolean hasById(ID id) {
		return wrappedData.get(id) != null;
	}

	@Override
	public void walk(FacesContext context, DataVisitor visitor, Range range, Object argument) throws IOException {
		int firstRow = ((SequenceRange) range).getFirstRow();
		int maxResults = ((SequenceRange) range).getRows();
		if (firstRow != firstRow_old || listRow == null){
			listRow = getList(firstRow, maxResults);
			firstRow_old = firstRow;
		}
		wrap(context, visitor, range, argument, listRow);
	}

	/*
	 * This method normally called by Visitor before request Data Row.
	 */
	@Override
	public void setRowKey(Object key) {
		this.currentId = (ID) key;
	}

	@Override
	public int getRowCount() {
		if (rowCount == null)
			return (rowCount = this.getCount()).intValue();
		else
			return rowCount.intValue();
	}

	@Override
	public boolean isRowAvailable() {
		if (currentId == null) {
			return false;
		} else {
			return hasById(currentId);
		}
	}

	/**
	 * This is main way to obtain data row. It is intensively used by framework. We strongly recommend use of local cache in that method.
	 */
	@Override
	public Object getRowData() {
		if (currentId == null) {
			return null;
		} else {
			T ret = wrappedData.get(currentId);
			if (ret == null) {
				ret = this.findById(currentId);
				wrappedData.put(currentId, ret);
				return ret;
			} else {
				return ret;
			}
		}
	}

	/**
	 * Unused rudiment from old JSF staff.
	 */
	@Override
	public Object getWrappedData() {
		throw new UnsupportedOperationException();
	}
	private int rowIndex = 0;
	@Override
	public int getRowIndex() {
		//throw new UnsupportedOperationException();
		return rowIndex;
	}

	@Override
	public void setRowIndex(int rowIndex) {
		//throw new UnsupportedOperationException();
		this.rowIndex = rowIndex;
	}

	@Override
	public void setWrappedData(Object data) {
		throw new UnsupportedOperationException();
	}

	@Override
	public Object getRowKey() {
		if (true)
			throw new UnsupportedOperationException();
		return currentId;
	}

}

 

数据列表类

 

public class PeopleListExtendedDataModel extends BaseExtendedDataModel<People, Long>{
...
	@Override
	public People findById(Long id) {
		return entityManager.find(People.class, id);
	}
	@Override
	public Long getCount() {
		return (Long)createQuery(true).getSingleResult();
	}

	@Override
	public List<People> getList(Integer firstRow, Integer maxResults) {
		return createQuery(false).setFirstResult(firstRow).setMaxResults(maxResults).getResultList();
	}

...

}

 

页面代码:

            <rich:datascroller align="left"  for="peopleList" maxPages="20" rendered="#{peopleListExtendedDataModel.size>20}"/>
            <rich:dataTable width="100%" id="peopleList" rows="20" columnClasses="col"
                value="#{peopleListExtendedDataModel}" var="people">

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值