SAP ABAP OData 服务的分页加载数据集的实现(Pag

2022-08-06  本文已影响0人  _扫地僧_

SAP UI5 应用的分页加载数据集,是一个极为重要的特性,需要 SAP UI5 前端和 OData 服务后端同时进行相应的开发工作,才能实现这个场景。

所谓分页加载数据集,就是默认情况下,SAP UI5 应用在启动后的默认页面里,只显示指定数据的数据集,这个个数默认为 20,也可以在系统或者代码里进行配置。因此我们可以理解成,SAP UI5 应用初始化时,默认从数据库加载第 1 到第 20 条数据。

当我们的滚动条向下滑动至屏幕底部时,会触发新一批数据的加载,读取第 21 条到第 40条也就是第二个 20 条数据。

SAP UI5 调用后台 OData 服务时,通过参数 $skip=X&$top=Y 来进行分页场景的指定。

假设后台的 SAP ABAP OData 服务针对消费者通过 url 传入的 $skip=X&$top=Y,已经正确实现,则 SAP UI5 应用,以分页的方式消费该 OData 服务,具体实现步骤,可以参考笔者这些文章:

下面介绍为了支持分页加载数据集的 SAP ABAP OData 服务的后台实现。

首先我们构造带有分类加载数据集请求参数的 url:

https://{{host}}:{{port}}/sap/opu/odata/sap/ZBOOK_MANAGE_SRV/BookCollection?$skip=1&$top=2

意思是从数据库里第 2 条记录(因为 $skip 索引从1开始)开始读取,总共读取 2 条记录。

我们在图书管理 OData 服务的 Data Provider Class 的 GET_ENTITYSET 里设置断点,然后用 Postman 发送上述请求,观察这个方法的输入参数里包含的 skip 和 top 参数:

发现分别包含在 is_paging 结构体的 skip 和 top 参数里。

为了分页实现所作的增强,源代码如下所示,增加了一个 IF 分支。

如果 is_paging 输入参数不为空,说明 OData 服务消费者,指定了 skip 和top 等分页参数。

此时我们需要根据这两个整数值,从存储了数据库全部记录的内表 lt_book 里,摘取出部分子集数据。变量 lv_index 的初始值,维护了从数据库的第几条记录开始摘取。这个初始值等于用户输入参数 $skip 的值再加上 1,因为后者是从 0 开始索引计数的。

而 lv_read_count 是一个计数器,每当从 lt_book 内表里摘取一条记录出来之后,计数器就加一。显然,这个计数器的值,不能超过另一个分页参数 $top 的值。

下图是数据库表全部 4 条数据。

最后我们来做一个测试:

https://{{host}}:{{port}}/sap/opu/odata/sap/ZBOOK_MANAGE_SRV/BookCollection?$skip=1&$top=2

如上 url,语义是,从数据库第 2( skip 的值加一) 条记录开始读取,总共读取 2(top 值为 2) 条数据。

测试结果,确实数据库第 2 和第 3 条记录被 OData 请求返回了:

GET_ENTITYSET 的完全代码如下:

  METHOD /iwbep/if_mgw_appl_srv_runtime~get_entityset.
    DATA: lt_book_db TYPE TABLE OF zbooks,
          ls_book_db LIKE LINE OF lt_book_db,
          lt_book    TYPE zcl_zbook_manage_mpc=>tt_book,
          ls_book    LIKE LINE OF lt_book,
          ls_order   LIKE LINE OF it_order,
          ls_filter  LIKE LINE OF it_filter_select_options,
          ls_option  LIKE LINE OF ls_filter-select_options.

    FIELD-SYMBOLS: <book> LIKE lt_book.

    IF it_filter_select_options IS INITIAL.
      SELECT * INTO CORRESPONDING FIELDS OF TABLE lt_book_db FROM zbooks.

      LOOP AT lt_book_db INTO ls_book_db.
        MOVE-CORRESPONDING ls_book_db TO ls_book.
        APPEND ls_book TO lt_book.
      ENDLOOP.

    ELSE.
      READ TABLE it_filter_select_options INTO ls_filter INDEX 1.
      READ TABLE ls_filter-select_options INTO ls_option INDEX 1.
      IF ls_filter-property = 'book_id' AND ls_option-option = 'EQ'.
        SELECT SINGLE * INTO ls_book_db FROM zbooks WHERE book_id = ls_option-low.
        MOVE-CORRESPONDING ls_book_db TO ls_book.
        APPEND ls_book TO lt_book.
      ENDIF.
    ENDIF.

    IF is_paging IS NOT INITIAL.
      DATA: lv_index TYPE int4,
            lv_read_count  TYPE int4 VALUE 0,
            lt_paged_table LIKE lt_book,
            ls_line        LIKE LINE OF lt_book.

      lv_index = is_paging-skip + 1.
      WHILE lv_read_count < is_paging-top.
        READ TABLE lt_book INTO ls_line INDEX lv_index.
        IF sy-subrc <> 0.
           EXIT.
        ENDIF.
        APPEND ls_line TO lt_paged_table.
        lv_read_count = lv_read_count + 1.
        lv_index = lv_index + 1.
      ENDWHILE.

      lt_book = lt_paged_table.
    ENDIF.
    CREATE DATA er_entityset TYPE zcl_zbook_manage_mpc=>tt_book.
    ASSIGN er_entityset->* TO <book>.
    <book> = lt_book.

    CHECK it_order IS NOT INITIAL.

    READ TABLE it_order INTO ls_order INDEX 1.

    IF ls_order-property <> 'author_name' AND ls_order-property <> 'book_name'.
      RETURN.
    ENDIF.

    IF ls_order-order IS INITIAL OR ls_order-order = 'asc'.
      SORT <book> BY (ls_order-property).
    ELSEIF ls_order-order = 'desc'.
      SORT <book> BY (ls_order-property) DESCENDING.
    ENDIF.

  ENDMETHOD.
上一篇下一篇

猜你喜欢

热点阅读