【问题标题】:TYPO3 Extbase - Paginate through a large table (100000 records)TYPO3 Extbase - 通过大表分页(100000 条记录)
【发布时间】:2017-07-23 21:35:00
【问题描述】:

我有一个相当大的表,大约有 100000 条记录。如果我不在存储库中设置限制

存储库:

public function paginateRequest() {

$query = $this->createQuery();
$result = $query->setLimit(1000)->execute();
//$result = $query->execute();
return $result;

}

/**
 * action list
 *
 * @return void
 */
public function listAction() {

$this->view->assign('records', $this->leiRepository->paginateRequest());

//$this->view->assign('records', $this->leiRepository->findAll());

}

...尽管我使用的是 f:widget.paginate ,但查询和分页符。根据文档https://fluidtypo3.org/viewhelpers/fluid/master/Widget/PaginateViewHelper.html,我希望我只能通过记录呈现 itemsPerPage 和 'parginate' ...

列表.hmtl

<f:if condition="{records}">
<f:widget.paginate objects="{records}" as="paginatedRecords" configuration="{itemsPerPage: 100, insertAbove: 0, insertBelow: 1, maximumNumberOfLinks: 10}">                     
    <f:for each="{paginatedRecords}" as="record">
        <tr>
            <td><f:link.action action="show" pageUid="43" arguments="{record:record}"> {record.name}</f:link.action></td>
            <td><f:link.action action="show" pageUid="43" arguments="{record:record}"> {record.lei}</f:link.action></td>
        </tr>
    </f:for>
</f:widget.paginate>

型号:

类雷扩展\TYPO3\CMS\Extbase\DomainObject\AbstractEntity {

...
/**
 * abc
 *
 * @lazy
 * @var string
 */
protected $abc = '';
...

【问题讨论】:

    标签: typo3 extbase typo3-7.6.x


    【解决方案1】:

    您要分页的对象有多大/复杂?如果它们在列表视图中有您不需要的子对象,请在模型内的这些关系中添加 @lazy 注释。

    由于记录量很大,您应该在列表视图中使它们尽可能简单。您可以尝试使用$this-&gt;leiRepository-&gt;findAll()-&gt;toArray() 仅将结果作为数组提供给列表视图,或者通过将true 添加到execute(true) 仅返回存储库中的原始结果。

    您还可以在控制器的 foreach 中自己创建一个列表项数组,并只在列表中添加您真正需要的属性。

    【讨论】:

    • 谢谢保罗。我尝试了@lazy 加载,->toArray() 和 execute(true) ...但它仍然中断。当您询问“对象应该有多大/多复杂?” ...您的意思是我想在每个分页选项卡的列表视图中显示多少条记录?我希望至少有 100 个......并且通过子对象?
    【解决方案2】:

    如果您的问题是性能问题,只需使用默认的 findAll()-Method。

    \TYPO3\CMS\Extbase\Persistence\Repository 中的内置 defaultQuerySettings 会根据 Pagination 小部件设置它们的偏移量和限制,如果没有另外设置。

    如果性能问题仍然存在,您可能必须考虑为您的数据库请求编写一个自定义查询,该查询仅请求您的视图实际显示的数据。该过程在文档中进行了描述:https://docs.typo3.org/typo3cms/ExtbaseFluidBook/6-Persistence/3-implement-individual-database-queries.html

    【讨论】:

      【解决方案3】:

      我在 TYPO3 9.5 中使用。存储库中的下一个函数:

      public function paginated($page = 1, $size = 9){
          $query = $this->createQuery();
          $begin = ($page-1) * $size;
          $query->setOffset($begin);
          $query->setLimit($size);
          return $query->execute();
      }
      

      在控制器中,我使用参数作为参数来发送页面以在 Rest 操作中加载。

      public function listRestAction()
      {
      
          $arguments = $this->request->getArguments();
          $totalElements = $this->repository->total();
          $pages = ceil($totalElements/9);
          $next_page = '';
          $prev_page = '';
          #GET Page to load
          if($arguments['page'] AND $arguments['page'] != ''){
              $page_to_load = $arguments['page'];
          } else {
              $page_to_load = 1; 
          }
          #Configuration of pagination
          if($page_to_load == $pages){
              $prev = $page_to_load - 1;
              $prev_page = "http://example.com/rest/news/page/$prev";
          } elseif($page_to_load == 1){
              $next = $page_to_load + 1;
              $next_page = "http://example.com/rest/news/page/$next";
          } else {
              $prev = $page_to_load - 1;
              $prev_page = "http://example.com/rest/news/page/$prev";
              $next = $page_to_load + 1;
              $next_page = "http://example.com/rest/news/page/$next";
          }
      
          $jsonPreparedElements = array();
          $jsonPreparedElements['info']['count'] = $totalElements;        
          $jsonPreparedElements['info']['pages'] = $pages;
          $jsonPreparedElements['info']['next'] = $next_page;
          $jsonPreparedElements['info']['prev'] = $prev_page;
          $result = $this->repository->paginated($page_to_load);
          $collection_parsed_results = array();
          foreach ($result as $news) {
              array_push($collection_parsed_results, $news->parsedArray());
          }
          $jsonPreparedElements['results'] = $collection_parsed_results;
          $this->view->assign('value', $jsonPreparedElements);
      }
      

      这样的结果,就是这样的 JSON:

      {
      "info": {
          "count": 25,
          "pages": 3,
          "next": "",
          "prev": "http://example.com/rest/news/page/2"
      },
      "results": [
          { ....}
      ] }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-06-17
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多