我根据Grid的实现方式,写了一个pagedloop组件,设计了一个LoopDataSource接口作为pagedloop的source,主要是希望从数据库中抓取每页所需的记录,而不是所有记录。
LoopDataSource.java:
public interface LoopDataSource extends Iterable<Object>{
int getTotalRowCount();
void prepare(int startIndex, int endIndex, String propertyName);
}
public class HibernateLoopDataSource implements LoopDataSource {
private final Session session;
private final Class<?> entityType;
private int startIndex;
private List<Object> preparedResults;
public HibernateLoopDataSource(Session session, Class<?> entityType){
assert session != null;
assert entityType != null;
this.session = session;
this.entityType = entityType;
}
public int getTotalRowCount(){
Criteria criteria = session.createCriteria(entityType);
criteria.setProjection(Projections.rowCount());
Number result = (Number) criteria.uniqueResult();
return result.intValue();
}
@SuppressWarnings("unchecked")
public void prepare(int startIndex, int endIndex, String propertyName){
Criteria crit = session.createCriteria(entityType);
crit.setFirstResult(startIndex).setMaxResults(endIndex - startIndex + 1);
if(propertyName!=null){
crit.addOrder(Order.desc(propertyName));
}
this.startIndex = startIndex;
preparedResults = crit.list();
}
@Override
public Iterator<Object> iterator() {
// TODO Auto-generated method stub
return preparedResults.iterator();
}
}
public class PagedLoop implements ClientElement {
//@Parameter(value = "prop:componentResources.id", defaultPrefix = "literal")
//private String clientId;
/**
* The element to render. If not null, then the loop will render the
* indicated element around its body (on each pass through the loop). The
* default is derived from the component template.
*/
@Parameter(value = "prop:componentResources.elementName", defaultPrefix = "literal")
private String elementName;
/**
* The element to render. If not null, then the loop will render the
* indicated element around its body (on each pass through the loop). The
* default is derived from the component template.
*/
@Parameter(required = true, principal = true, autoconnect = true)
private LoopDataSource source;
/**
* A wrapper around the provided Data Source that caches access to the
* availableRows property. This is the source provided to sub-components.
*/
private LoopDataSource cachingSource;
/**
* Defines where the pager (used to navigate within the "pages" of results)
* should be displayed: "top", "bottom", "both" or "none".
*/
@Parameter(value = "bottom", defaultPrefix = "literal" )
private String pagerPosition;
private GridPagerPosition internalPagerPosition;
/**
* The number of rows of data displayed on each page. If there are more rows
* than will fit, the Grid will divide up the rows into "pages" and
* (normally) provide a pager to allow the user to navigate within the
* overall result set.
*/
@Parameter("25")
private int rowsPerPage;
@Persist
private int currentPage;
/**
* The current value, set before the component renders its body.
*/
@SuppressWarnings("unused")
@Parameter
private Object value;
/**
*If true and the Loop is enclosed by a Form, then the normal state saving logic is turned off.
* Defaults to false, enabling state saving logic within Forms.
*/
@SuppressWarnings("unused")
@Parameter(name = "volatile")
private boolean volatileState;
/**
* The index into the source items.
*/
@SuppressWarnings("unused")
@Parameter
private int index;
/**
* Optional primary key converter; if provided and inside a form and not
* volatile, then each iterated value is converted and stored into the form.
*/
@SuppressWarnings("unused")
@Parameter
private ValueEncoder<?> encoder;
@SuppressWarnings("unused")
@Component(parameters = { "source=dataSource",
"elementName=prop:elementName", "value=inherit:value",
"volatile=inherit:volatileState", "encoder=inherit:encoder",
"index=inherit:index" })
private Loop loop;
@Component(parameters = { "source=dataSource", "rowsPerPage=rowsPerPage",
"currentPage=currentPage" })
private Pager pager;
@SuppressWarnings("unused")
@Component(parameters = "to=pagerTop")
private Delegate pagerTop;
@SuppressWarnings("unused")
@Component(parameters = "to=pagerBottom")
private Delegate pagerBottom;
/**
* A Block to render instead of the table (and pager, etc.) when the source
* is empty. The default is simply the text "There is no data to display".
* This parameter is used to customize that message, possibly including
* components to allow the user to create new objects.
*/
@Parameter(value = "block:empty")
private Block empty;
private String assignedClientId;
@Parameter(name="OrderBy", defaultPrefix="literal")
private String propertyName;
/**
* A version of LoopDataSource that caches the availableRows property.
*/
static class CachingDataSource implements LoopDataSource
{
private final LoopDataSource delegate;
private boolean availableRowsCached;
private int availableRows;
CachingDataSource(LoopDataSource delegate)
{
this.delegate = delegate;
}
public int getTotalRowCount()
{
if (!availableRowsCached)
{
availableRows = delegate.getTotalRowCount();
availableRowsCached = true;
}
return availableRows;
}
public void prepare(int startIndex, int endIndex, String propertyName)
{
delegate.prepare(startIndex, endIndex, propertyName);
}
@Override
public Iterator<Object> iterator() {
return delegate.iterator();
}
}
public String getElementName() {
return elementName;
}
public Object getPagerTop() {
return internalPagerPosition.isMatchTop() ? pager : null;
}
public Object getPagerBottom() {
return internalPagerPosition.isMatchBottom() ? pager : null;
}
public int getRowsPerPage() {
return rowsPerPage;
}
public void setRowsPerPage(int rowsPerPage) {
this.rowsPerPage = rowsPerPage;
}
public int getCurrentPage() {
return currentPage;
}
public void setCurrentPage(int currentPage) {
this.currentPage = currentPage;
}
void setupDataSource()
{
cachingSource = new CachingDataSource(source);
int availableRows = cachingSource.getTotalRowCount();
if (availableRows == 0)
return;
int maxPage = ((availableRows - 1) / rowsPerPage) + 1;
// This captures when the number of rows has decreased, typically due to deletions.
int effectiveCurrentPage = getCurrentPage();
if (effectiveCurrentPage > maxPage)
effectiveCurrentPage = maxPage;
int startIndex = (effectiveCurrentPage - 1) * rowsPerPage;
int endIndex = Math.min(startIndex + rowsPerPage - 1, availableRows - 1);
cachingSource.prepare(startIndex, endIndex, propertyName);
}
Object setupRender() {
if (currentPage == 0)
currentPage = 1;
internalPagerPosition = new StringToEnumCoercion<GridPagerPosition>(
GridPagerPosition.class).coerce(pagerPosition);
setupDataSource();
// If there's no rows, display the empty block placeholder.
return cachingSource.getTotalRowCount() == 0 ? empty : null;
}
Object beginRender() {
// Skip rendering of component (template, body, etc.) when there's
// nothing to display.
// The empty placeholder will already have rendered.
return (cachingSource.getTotalRowCount() != 0);
}
void onAction(int newPage){
currentPage = newPage;
}
/**
* Returns a unique id for the element. This value will be unique for any given rendering of a
* page. This value is intended for use as the id attribute of the client-side element, and will
* be used with any DHTML/Ajax related JavaScript.
*/
@Override
public String getClientId()
{
return assignedClientId;
}
public LoopDataSource getDataSource(){
return cachingSource;
}
public String getPropertyName(){
return propertyName;
}
}
@Property
private Blog blog;
@Inject
private Session session;
public LoopDataSource getList(){
return new HibernateLoopDataSource(session, Blog.class);
}
分享到:
相关推荐
在这个项目中,我们有`qt自定义分页组件源代码`,它包含了实现这一功能的核心源码和测试代码。下面我们将详细探讨这些源文件及其在QT开发中的作用。 首先,`zpagewidget.cpp`和`zpagewidget.h`是自定义分页组件的...
"小程序自定义分页选择组件"是一个专门为解决页面分页问题而设计的组件,它提供了灵活的配置选项,允许开发者根据实际需求定制分页显示效果。下面我们将深入探讨这个组件的核心功能、参数设置以及如何在小程序中应用...
使用`BindingSource`组件可以方便地实现数据绑定和分页操作。 4. **分页逻辑**:在事件处理程序中,你需要实现分页逻辑。这通常涉及计算当前页码、确定数据范围,然后更新数据显示。例如,如果每页显示10条数据,第...
自定义分页标签自定义分页标签自定义分页标签自定义分页标签自定义分页标签自定义分页标签自定义分页标签自定义分页标签自定义分页标签自定义分页标签自定义分页标签自定义分页标签自定义分页标签自定义分页标签...
为了提高代码的可维护性和可移植性,我们可以通过编写自定义分页插件来实现更灵活的分页逻辑。本文将详细介绍如何在 MyBatis 中实现自定义分页插件。 自定义分页插件提供了一种灵活且高效的方式来实现 MyBatis 的...
本文将深入探讨如何在GridView中实现自定义分页,以及这一过程中的关键知识点。 首先,理解自定义分页的核心概念。自定义分页意味着我们不再依赖GridView内置的分页功能,而是自己处理数据的加载和分页逻辑。这样...
实现自定义分页控件通常涉及以下几个关键组件: 1. **基类选择**:你可以选择继承`QWidget`或`QAbstractButton`作为自定义控件的基础。如果需要一个完整的组件,可以选择`QWidget`,因为它提供了一个空白画布,可以...
本文将深入探讨如何在ASP.NET中实现自定义分页,以及与SQL数据库的集成。 首先,我们要理解ASP.NET中的分页原理。分页的基本思想是通过在服务器端对数据进行切割,每次只取一部分数据返回给客户端,然后在客户端...
2.1.目前网络上很多分页主键,不能进行按钮选择, 2.2.甚至对样式修改的难度也较大, 2.3.使用在开发过程中由于使用到了分页功能,在这里写了一个分页功能。 3.按钮选择 之前的很多按钮是通过参数进行选择,这样不...
本文将深入探讨.NET自定义分页控件的设计与实现,以及它的优势和应用。 首先,分页控件是数据展示的核心组件,尤其是在大数据集的场景下。通过分页,用户可以逐页浏览数据,而不是一次性加载所有记录,这大大减轻了...
本教程将详细讲解如何创建和使用自定义分页标签,以及如何实现淘宝购物分页标签的样式。 首先,理解分页的核心原理:分页是将大量数据分割成小块,每次只加载一部分数据到页面上,用户通过翻页来查看其他部分。在...
本教程将深入探讨如何在Android中创建一个自定义分页控件,以便实现高效、用户友好的界面。 首先,我们需要理解分页的基本原理。分页通常是通过在后台服务器上对数据进行切片,每次请求只加载一部分数据,而不是一...
总结起来,QT5分页组件是通过自定义控件、信号与槽机制以及与数据模型的交互来实现的。它简化了大量数据的显示,并提供了良好的用户体验。通过学习和实践,开发者可以熟练掌握这一功能,提升应用程序的易用性。
这个资源是一个基于vue2和element-ui实现的自定义分页表格组件,是将element-ui的表格组件和分页组件封装成了一个组件,可以指定接口地址,快速实现分页表格的渲染,减少前端代码的编写。使用的技术:vue2.6.14、...
LibHelper是一个支持自定义分页的工具类,详细介绍看这里 “MVC实现自定义分页”http://blog.csdn.net/xyj2014/article/details/49761963
本文将详细介绍如何创建一个自定义的分页控件,并通过Web版实例进行演示。 一、分页控件的基本概念 分页控件是网页设计中用于分割大量数据的一种交互组件,它允许用户通过点击不同页码来查看数据的不同部分。分页...
uniapp分页组件:H5、小程序、app分页组件
本文实例为大家分享了swiper自定义分页器的样式代码,供大家参考,具体内容如下 js主要代码 pagination: { // 自定义分页器的类名----必填项 el: '.custom-pagination', // 是否可点击----必填项 clickable: ...