Visualforce页面分页的方法2(使用SOQL的LIMIT和OFFSET来进行分页)【推荐方法】
2023年09月06日
文章浏览:243
需求:在Visualforce内进行页面分页,并且数据量非常大,至少一个页面要显示5000件以上,甚至几十万件

大数据量的分页显示,这样的需求很常见,所以在Visualforce内进行大数据量页面分页,我们在这里简单地说明一下。

希望对大家有所帮助。


实现步骤(1):创建Apex代码


关于使用SOQL的LIMIT和OFFSET来进行分页,很简单,关键的代码就是下面这一句SOQL。

另外的下一页next,上一页previous方法无非是对OffsetSize的值进行修改,并重新查询 。

leadViewQuery = leadViewQuery + whereStr + 'LIMIT :LimitSize OFFSET :OffsetSize';


/**
 * @description       : 使用SOQL的LIMIT和OFFSET来进行分页
 * @author            : SalesforceGogogo.com
 * @last modified on  : 2023/08/31
 * @last modified by  : SalesforceGogogo.com
**/


public with sharing class GoodPaging {
	
	// 検索結果件数
    public Integer searchCount { get; set; }
    public Integer viewrecCount { get; set; }
    
    // 検索リードリスト
    public List<Lead> searchLeadList { get; set; }              
    
    // 次ページ、前ページ用項目------------Start
    private integer totalRecs = 0;
    public integer OffsetSize = 0;
    private integer LimitSize= 50;
    
    private static final Integer PAGE_SIZE =50;     // 1ページあたりの表示件数
    public Integer currentPage {get; private set;}          // 現在選択中のページ
    public Integer totalPage {get; private set;}            // ページ数
    
    public Integer firstNum { 
        get{
            if(currentPage != null){
                return PAGE_SIZE * (currentPage - 1) + 1;
            }
            
            return 0;
        }
        set;
    }
    
    public GoodPaging(){
    	searchLead();
    }
    
    //-----------------------------------------
    // 検索
    //-----------------------------------------
    public void searchLead(){
    	searchWithPagnation();
    	
    	// ページの総数を計算
        // レコード数 / ページサイズで計算、小数部分は切り上げ
        totalPage = (Integer)Math.ceil((Decimal)searchCount / LimitSize);
        //System.debug('■totalPage---------------->'+ totalPage);
        
        currentPage = 1;
    }
    
    public void searchWithPagnation(){
        this.searchCount = 0;
        
        String leadViewQuery = 
           'Select                            ' + 
           '    Id                            ' + 
           '    ,Name                         ' + 
           '    ,Phone                        ' + 
           '    ,MobilePhone                  ' + 
           '    ,State                        ' + 
           '    ,City                         ' + 
           '    ,Street                       ' + 
           '    ,CreatedDate                  ' + 
           '    ,FirstName                    ' + 
           '    ,LastName                     ' + 
           '    ,Company                      ' + 
           '    ,ConvertedAccountId           ' +
           'From                              ' + 
           '    Lead                          ' + 
           'Where                             ' + 
           '    IsDeleted = false             ' ;
           
        String leadCntQuery = 
           'Select                            ' + 
           '    Count(Id) cnt                 ' + 
           'From                              ' + 
           '    Lead                          ' + 
           'Where                             ' + 
           '    IsDeleted = false             ' ;
        
    	// 関連データからの条件絞り込みを実行する必要がある場合は関連データから検索を行う
    	String whereStr = '';
    	leadViewQuery = leadViewQuery + whereStr + 'LIMIT :LimitSize OFFSET :OffsetSize';
    	System.debug('■leadViewQuery---------------->'+ leadViewQuery);
    	
    	
    	List<Lead> searchLeadListQuery = Database.query(leadViewQuery);
    	System.debug('■searchLeadListQuery---------------->'+ searchLeadListQuery);
    	
    	this.searchLeadList = Database.query(leadViewQuery);
    	System.debug('■searchLeadList.Size()---------------->'+ this.searchLeadList.Size());
    	
    	
    	leadCntQuery = leadCntQuery + whereStr;
        AggregateResult[] groupedResults = Database.query(leadCntQuery);
        
        // 検索結果件数を保持
        this.searchCount = Integer.valueOf(groupedResults.get(0).get('cnt'));
        //System.debug('■searchCount---------------->'+ searchCount);
    	
    	if(this.searchCount >= 50){
            this.viewrecCount = 50;
        }else{
            this.viewrecCount = this.searchCount;
        }
    }
    
    
    //Pageing対応-------------------Start
    public void FirstPage()
    {
        OffsetSize = 0;
        searchWithPagnation();
    }
    
    public void previous()
    {
        OffsetSize = OffsetSize - LimitSize;
        searchWithPagnation();
        currentPage--;
    }
    
    public void next()
    {
        OffsetSize = OffsetSize + LimitSize;
        searchWithPagnation();
        currentPage++;
    }
    
    public void LastPage()
    {
        OffsetSize = totalrecs - math.mod(totalRecs,LimitSize);
        searchWithPagnation();
    }
    
    //前のページがあるかどうか
    public boolean getenablePrev()
    {
        if(OffsetSize == 0 || currentPage == 1){
            return false;
        }else{
            return true;
        }
    }
    
    //次のページがあるかどうか
    public boolean getenableNext()
    {
        if((OffsetSize + LimitSize) > totalRecs){
            return false;
        }else{
            return true;    
        }
    }
    //Pageing対応-------------------End
}


实现步骤(2):创建Visualforce Page代码



<apex:page standardStylesheets="false" controller="GoodPaging" lightningStylesheets="false" sidebar="false" showHeader="false" docType="html-5.0" id="page">
  <style>
    .table .thead-dark th {
        color: #000;
        background-color: #e9dfe5;
        border-color: #dee2e6;
    }
  </style>
<apex:form >
<table id="searchTable" class="table table-bordered table-striped" style="width:100%;height:1000px;table-layout: auto;">
<thead>
  <tr>
    <th colspan="10" style="border-bottom: solid 0.1px #e9dfe5;height:45px;" class="sorter-false filter-false" >
      <div style="width:50%;float:left;">検索結果:{!searchCount}件 表示件数:{!viewrecCount}件</div>
      <div style="width:50%;float:left;text-align: right;">
        <!-- ページネーション -->
        <apex:outputPanel layout="none" rendered="{!enablePrev}">
          <apex:commandLink value="< 前" action="{!previous}" />
          <apex:outputLabel value=" | " />
        </apex:outputPanel>
        <apex:outputLabel value="{!currentPage}/{!totalPage}" />
        <apex:outputPanel layout="none" rendered="{!enableNext}">
          <apex:outputLabel value=" | " />
          <apex:commandLink value="次 >" action="{!next}" />
        </apex:outputPanel>  
      </div>
    </th>
  </tr>
  <tr class="thead-dark">
      <th  width="3%"><span>No.</span></th>  
      <th  width="10%"><span>登録日</span></th>
      <th width="22%"><span>住所</span></th>
      <th width="15%"><span>顧客名</span></th>
      <th width="10%"><span>携帯</span></th>
      <th width="10%"><span>日時</span></th>
  </tr>
</thead>


<apex:variable var="rowNum" value="{!firstNum}" />
<apex:repeat value="{!searchLeadList}" var="scLead" >
  <tr class="dataLineNomal" style="height:45px;" id="{!scLead.Id}">
    <td style="font-size:12px;">
      <apex:outputText value="{!rowNum}"/>
    </td>
    <td style="font-size:12px;"><apex:outputField value="{!scLead.CreatedDate}"/></td>
    <td style="font-size:12px;padding:10px 10px 0px 10px;">
      <div><apex:outputText value="{!scLead.State}" /></div>
      <div><apex:outputText value="{!scLead.City}" /></div>
      <div><apex:outputText value="{!scLead.Street}" /></div>
    </td>
    <td style="font-size:12px;padding:10px 10px 0px 10px;">
      <div><div class="mapTColumnHeader">姓</div><apex:outputLink value="/{!scLead.Id}">{!scLead.FirstName}</apex:outputLink></div>
      <div><div class="mapTColumnHeader">名</div><apex:outputLink value="/{!scLead.Id}">{!scLead.LastName}</apex:outputLink></div>
    </td>
    <td style="font-size:12px;padding:10px 10px 0px 10px;">
      <div><div class="mapTColumnHeader">携帯</div><apex:outputText value="{!scLead.MobilePhone}"/></div>
    </td>
    <apex:variable var="rowNum" value="{!rowNum+1}"/>
  </tr>
</apex:repeat>
</table>

</apex:form>
</apex:page>




参考页面

How to do pagination on a large dataset in Apex

 https://www.linkedin.com/pulse/how-do-pagination-large-dataset-apex-zlatko-petrov/ 


实现效果

这个截图不太好,数据量太少,最好是有至少5000件以上的数据 。

我想说的是,

这个ViewState里面的数据数量,就是一页面的内容。其余页面的内容,我们使用SOQL的LIMIT和OFFSET的特性,就可以不查询出来,不放到List里面去,不放到List里面,就不会占用ViewState的容量。




关注 收藏