专注于LargeTables,JSF

本文介绍了一种使用自定义DataModel和PagedListDataModel的方法,实现在MyFaces中对大型数据集进行分页处理,避免内存溢出问题。通过定义DataPage类来封装数据页面及其在完整数据集中的位置信息,并在Managed Bean中实现fetchPage方法按需加载数据。

原文url: http://wiki.apache.org/myfaces/WorkingWithLargeTables?highlight=%28table%29%7C%28memory%29%7C%28scroller%29

Components t:dataModel and t:dataScroller work together nicely to allow a user to "page" through a set of a few dozen to a few hundred records. However the implementation does assume that the entire set of available records are in memory and wrapped up inside a ListDataModel or ArrayDataModel.

When the available dataset is quite large, and the application can have many users, this can lead to memory usage problems.

This page contains discussions on how to handle this scenario.

On-demand loading

A custom DataModel can be used to allow data to be loaded "on demand".

First, a class needs to be defined which your "business methods" (eg EJBs) can use to pass "pages" of data back to the UI. This class needs to be defined in your project, as the "business" level shouldn't be extending MyFaces classes:

package example;

import java.util.List;

/**
 * A simple class that represents a "page" of data out of a longer set, ie
 * a list of objects together with info to indicate the starting row and
 * the full size of the dataset. EJBs can return instances of this type
 * when returning subsets of available data.
 */
public class DataPage<T> {

  private int datasetSize;
  private int startRow;
  private List<T> data;
        
  /**
   * Create an object representing a sublist of a dataset.
   * 
   * @param datasetSize is the total number of matching rows
   * available.
   * 
   * @param startRow is the index within the complete dataset
   * of the first element in the data list.
   * 
   * @param data is a list of consecutive objects from the
   * dataset.
   */
  public DataPage(int datasetSize, int startRow, List<T> data) {
    this.datasetSize = datasetSize;
    this.startRow = startRow;
    this.data = data;
  }

  /**
   * Return the number of items in the full dataset.
   */
  public int getDatasetSize() {
    return datasetSize;
  }

  /**
   * Return the offset within the full dataset of the first
   * element in the list held by this object.
   */
  public int getStartRow() {
    return startRow;
  }

  /**
   * Return the list of objects held by this object, which
   * is a continuous subset of the full dataset.
   */
  public List<T> getData() {
    return data;
  }
}

Now a custom DataModel can use this DataPage stuff. Again, it is recommended that you copy this code into your project and change the package name appropriately. This class can't go in the MyFaces libraries as it depends on DataPage, and as noted above, DataPage is accessed by your business level code so it really can't be in the MyFaces libs:

package example;

import javax.faces.model.DataModel;

import example.DataPage;

/**
 * A special type of JSF DataModel to allow a datatable and datascroller
 * to page through a large set of data without having to hold the entire
 * set of data in memory at once.
 * <p>
 * Any time a managed bean wants to avoid holding an entire dataset,
 * the managed bean should declare an inner class which extends this
 * class and implements the fetchData method. This method is called
 * as needed when the table requires data that isn't available in the
 * current data page held by this object.
 * <p>
 * This does require the managed bean (and in general the business
 * method that the managed bean uses) to provide the data wrapped in
 * a DataPage object that provides info on the full size of the dataset.
 */
public abstract class PagedListDataModel<T> extends DataModel {

    int pageSize;
    int rowIndex;
    DataPage<T> page;
    
    /*
     * Create a datamodel that pages through the data showing the specified
     * number of rows on each page.
     */
    public PagedListDataModel(int pageSize) {
        super();
        this.pageSize = pageSize;
        this.rowIndex = -1;
        this.page = null;
    }

    /**
     * Not used in this class; data is fetched via a callback to the
     * fetchData method rather than by explicitly assigning a list.
     */
    @Override
    public void setWrappedData(Object o) {
        throw new UnsupportedOperationException("setWrappedData");
    }

    @Override
    public int getRowIndex() {
        return rowIndex;
    }

    /**
     * Specify what the "current row" within the dataset is. Note that
     * the UIData component will repeatedly call this method followed
     * by getRowData to obtain the objects to render in the table.
     */
    @Override
    public void setRowIndex(int index) {
        rowIndex = index;
    }

    /**
     * Return the total number of rows of data available (not just the
     * number of rows in the current page!).
     */
    @Override
    public int getRowCount() {
        return getPage().getDatasetSize();
    }
    
    /**
     * Return a DataPage object; if one is not currently available then
     * fetch one. Note that this doesn't ensure that the datapage
     * returned includes the current rowIndex row; see getRowData.
     */
    private DataPage<T> getPage() {
        if (page != null)
            return page;
        
        int rowIndex = getRowIndex();
        int startRow = rowIndex;
        if (rowIndex == -1) {
            // even when no row is selected, we still need a page
            // object so that we know the amount of data available.
           startRow = 0;
        }

        // invoke method on enclosing class
        page = fetchPage(startRow, pageSize);
        return page;
    }

    /**
     * Return the object corresponding to the current rowIndex.
     * If the DataPage object currently cached doesn't include that
     * index then fetchPage is called to retrieve the appropriate page.
     */
    @Override
    public Object getRowData(){
        if (rowIndex < 0) {
            throw new IllegalArgumentException(
                "Invalid rowIndex for PagedListDataModel; not within page");
        }

        // ensure page exists; if rowIndex is beyond dataset size, then 
        // we should still get back a DataPage object with the dataset size
        // in it...
        if (page == null) {
            page = fetchPage(rowIndex, pageSize);
        }

        // Check if rowIndex is equal to startRow,
        // useful for dynamic sorting on pages
                
        if (rowIndex == page.getStartRow()){
                page = fetchPage(rowIndex, pageSize);
        }

        int datasetSize = page.getDatasetSize();
        int startRow = page.getStartRow();
        int nRows = page.getData().size();
        int endRow = startRow + nRows;
        
        if (rowIndex >= datasetSize) {
            throw new IllegalArgumentException("Invalid rowIndex");
        }
        
        if (rowIndex < startRow) {
            page = fetchPage(rowIndex, pageSize);
            startRow = page.getStartRow();
        } else if (rowIndex >= endRow) {
            page = fetchPage(rowIndex, pageSize);
            startRow = page.getStartRow();
        }
        
        return page.getData().get(rowIndex - startRow);
    }

    @Override
    public Object getWrappedData() {
        return page.getData();
    }

    /**
     * Return true if the rowIndex value is currently set to a
     * value that matches some element in the dataset. Note that
     * it may match a row that is not in the currently cached 
     * DataPage; if so then when getRowData is called the
     * required DataPage will be fetched by calling fetchData.
     */
    @Override
    public boolean isRowAvailable() {
        DataPage<T> page = getPage();
        if (page == null)
            return false;
        
        int rowIndex = getRowIndex();
        if (rowIndex < 0) {
            return false;
        } else if (rowIndex >= page.getDatasetSize()) {
            return false;
        } else {
            return true;
        }
    }

    /**
     * Method which must be implemented in cooperation with the
     * managed bean class to fetch data on demand.
     */
    public abstract DataPage<T> fetchPage(int startRow, int pageSize);
}

Finally, the managed bean needs to provide a simple inner class that provides the fetchPage implementation:

  public SomeManagedBean {
    ....


    private DataPage<SomeRowObject> getDataPage(int startRow, int pageSize) {
      // access database here, or call EJB to do so
    }

    public DataModel getDataModel() {
        if (dataModel == null) {
            dataModel = new LocalDataModel(getRowsPerPage());
        }

        return dataModel;
    }

    private class LocalDataModel extends PagedListDataModel {
        public LocalDataModel(int pageSize) {
            super(pageSize);
        }
        
        public DataPage<SomeRowObject> fetchPage(int startRow, int pageSize) {
            // call enclosing managed bean method to fetch the data
            return getDataPage(startRow, pageSize);
        }
    }

The jsp pages are then trivial; by default the t:dataScroller will update the t:dataTable's "first" property, and that's all that is needed because when the table asks the custom DataModel for the necessary rows callbacks to fetchPage will be made which will fetch exactly the data required. No event listeners, action methods, or anything else is required as glue.

Other approaches

In an email thread on this topic, an alternative was decribed:

So was this:

And another example with the DataModel approach

And a sortable and scrollable demo with 1.1.1 jars included:

Paging large data sets with a LazyList

Paged datatable with a GenericDataTableHandler:

last edited 2007-05-31 06:48:27 by JurgenLust

下载代码方式:https://pan.quark.cn/s/28492da20c79 依据所提供的文件资料,本资源将系统地探讨FPGA(即现场可编程门阵列)的核心概念、其在视频图像技术领域的入门及进阶知识要点,以及图像处理算法的实现方法。此外,还将对VIPBoardBig这一特定FPGA开发板的详细资料和使用途径进行深入剖析。 FPGA的入门与进阶学习主要涉及以下核心内容: 1. FPGA的基础概念:FPGA是一种能够通过编程进行配置的集成电路,主要目的是达成硬件逻辑的可重构特性。该类芯片由大量的可配置逻辑模块(CLB)、输入输出模块(IOB)以及可编程互连资源共同构成。 2. FPGA开发板与相关套件:FPGA开发板是一种用于FPGA芯片学习和测试的硬件平台,通常配备有基础的外设设备,例如LED指示灯、按键开关、LCD显示屏、串口通信接口等。套件则通常包含硬件板卡、技术文档、相关资源,以及可能的软件工具和示例代码集。VIPBoardBig即为本教程选用的FPGA开发板,拥有特定的硬件配置和功能特性。 3. FPGA的开发流程:FPGA开发一般涉及硬件描述语言(HDL)的设计与仿真阶段,常用语言为Verilog或VHDL。随后,借助综合工具将设计蓝图转化为FPGA内部的逻辑网络,最终通过编程设备将配置文件传输至FPGA芯片中,从而实现设计的预期功能。 4. 外设开发与设计工作:涵盖LED显示控制、键盘驱动、LCD显示驱动、UART串口设计等基础外设的开发任务。这部分知识将引导学习者掌握如何在FPGA平台上管理和运用这些基础外设。 5. VGA驱动显示与字符显示测试:VGA(Video Graphics Array)是一种视频传输接口标准,能够支持640x480...
内容概要:本文系统阐述了企业在搭建官方知识库后如何通过“7步锚定法”实现GEO(生成式引擎优化)的落地,重点在于从知识库走向内容矩阵的战略升级。文章指出知识库仅为起点,真正的核心是让大模型“信任并推荐”企业内容。为此提出“一个主战场+多个品牌布局”的策略,强调需根据行业特性选择高商业流量的大模型(如豆包、文心一言、通义千问等),而非工具性模型(如ChatGPT、Claude)。通过业务场景画像、大模型流量测绘、采信逻辑拆解、内容架构设计、语义关键词埋点、信源建设与效果迭代七步法,构建高质量、高可信度的内容体系,并警惕“全模型覆盖、内容堆砌、一套内容通用、忽视第三方平台”四大误区。最终指出GEO本质是一场认知战,比拼的是对大模型逻辑与客户需求的理解深度及长期主义投入。; 适合人群:已完成官方知识库搭建、希望提升AI引用率与获客效率的企业市场负责人、品牌运营、数字营销从业者及SEO/GEO优化相关人员。; 使用场景及目标:①指导企业科学选择主攻大模型并制定差异化内容策略;②构建符合大模型采信逻辑的高质量内容矩阵;③避免常见GEO落地误区,提升AI搜索下的品牌曝光与转化效果;④建立可持续优化的数据反馈闭环。; 阅读建议:建议结合自身行业特征与客户决策路径,逐步实践“7步法”,优先聚焦单一主战场打透,注重内容质量与第三方权威信源建设,坚持3-6个月持续投入以观察真实效果。
内容概要:本文针对考虑需求响应的微电网优化调度问题,提出了一种基于改进多目标灰狼算法(GWO)的优化方法,并通过Matlab代码实现了完整的仿真验证。研究在传统灰狼算法基础上引入改进机制,有效提升了算法的收敛速度、全局搜索能力和Pareto前沿分布质量,用于求解包含经济运行成本、碳排放水平、可再生能源利用率等多重目标的微电网调度模型。模型充分融合用户侧需求响应机制,利用分时电价等激励手段引导负荷转移与削峰填谷,从而增强系统对光伏、风电等间歇性能源的消纳能力,降低综合运行成本与环境影响。文中系统阐述了多目标优化建模过程、算法改进策略、约束处理方法及仿真结果对比分析,验证了该方法在获取高质量非劣解集和辅助决策方面的优越性。; 适合人群:适用于电力系统、能源互联网、自动化控制、智能优化算法等相关领域的硕士/博士研究生、科研人员,以及从事微电网能量管理、综合能源系统优化、低碳调度等工作的工程技术人员。; 使用场景及目标:①应用于微电网能量管理系统(EMS)中实现多目标协同优化调度;②为基于电价激励的需求响应项目提供负荷调控策略与量化分析工具;③作为智能计算算法在能源系统优化中应用的教学案例与科研参考,支持进一步拓展至多能互补、多微网互联等复杂场景的研究。; 阅读建议:建议读者结合提供的Matlab代码深入理解算法实现细节,重点关注目标函数构造、约束条件处理、多目标适应度评估及决策者偏好选择机制;可尝试将该框架迁移至含氢能储能、电动汽车集群等新型设备的综合能源系统中进行性能测试与算法改进。
内容概要:本文深入分析了洞察时空在2026年世界人工智能大会上提出的“数算一体AI星座”项目,该星座由576颗低轨及超低轨卫星构成,旨在实现“一天一次全球扫描”的高频对地观测能力,为AI Agent提供标准化的“地球真值”数据,弥补大模型在物理世界认知中的预测偏差。项目创新性地提出“数算一体”范式,通过天地一体算力协同、星上边缘计算与多模态数据融合,构建以“地球状态变量”为核心的智能认知系统,推动天基基础设施从数据采集向智能服务跃迁。报告系统梳理了当前研究现状,指出现有遥感系统在时效性、一致性与AI适配性上的不足,提出涵盖星座组网、星上AI推理、数据标准化等关键技术路径,并剖析了星上算力限制、数据一致性保障、物理可解释性等核心挑战,给出了芯片研发、开放标准、跨学科协作等未来发展方向。洞察时空作为主导企业,具备航天与AI复合背景,已获政策与资本支持,计划2030年完成全星座部署。; 适合人群:从事商业航天、人工智能、遥感技术、地球系统科学及相关交叉领域的科研人员、技术研发人员、政策制定者与产业投资者。; 使用场景及目标:①理解AI与天基系统融合的前沿趋势与技术架构;②探索“数算一体”在星地协同计算、多模态数据产品标准化中的实现路径;③评估高频地球观测数据对AI Agent、气候建模、灾害预警等应用的支撑潜力; 阅读建议:本报告兼具战略高度与技术深度,建议结合商业航天发展动态与AI在科学发现中的应用案例进行延伸阅读,重点关注天地算力调度机制与“地球状态变量”的定义演化,以把握下一代天基智能基础设施的发展方向。
内容概要:本文围绕综合能源系统与模型预测控制(MPC)滚动优化展开深入研究,重点利用Matlab代码实现对包含光伏、储能、风电等多种能源形式的综合能源系统进行建模与多时间尺度优化调度。通过MPC滚动优化方法,结合系统的动态数学模型与对未来负荷、可再生能源出力的预测信息,实现对能源生产、存储、转换与消费的协同优化控制,旨在提升系统运行的经济性、能源利用效率、低碳水平及供电可靠性。研究详细阐述了MPC的核心原理、预测模型构建、目标函数设计(如运行成本最小化)、系统约束(如功率平衡、设备容量、储能荷电状态)处理以及优化求解过程,并提供了完整的Matlab仿真代码框架,便于读者复现和二次开发。; 适合人群:具备一定电力系统、自动化、能源系统工程或控制理论基础,熟悉Matlab编程环境,从事相关领域科研、工程应用的研发人员、高校研究生及高年级本科生。; 使用场景及目标:①掌握模型预测控制(MPC)在综合能源系统、微电网、智慧园区等场景中的优化调度应用方法;②学习如何构建多能互补系统的精细化数学模型并实现滚动优化求解;③为能源互联网、新型电力系统背景下的能量管理与决策提供技术参考、算法支持与代码实例。; 阅读建议:建议读者结合文中提供的Matlab代码进行动手实践,重点关注MPC控制器的设计逻辑、预测模型与优化器的耦合机制,以及约束条件的代码实现方式。同时,鼓励在现有模型基础上,拓展至不同的能源设备配置、负荷场景或优化目标(如碳排放最小化),以深化对MPC在能源领域应用的理解。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值