30分鐘用Restful ABAP Programming模型開發一個支援增刪改查的Fiori應用
2016年時,Jerry曾經寫過一系列關於SAP Fiori Smart Template(現在更名為Fiori Elements了)的部落格,介紹了所謂的MDD開發方法論 - Metadata Driven Development,即透過開發維護了對應annotation(註解)的CDS view,結合SAP WebIDE,能夠花費最少的程式設計代價,就能夠在短時間內獲得一個支援增刪改查的Fiori應用。
這個系列的部落格集可以在Jerry這篇公眾號文章裡獲得: Jerry的透過CDS view + Smart Template 開發Fiori應用的blog合集。
三年的時間過去了,ABAP在不斷向前進化,如今我們有了新的程式設計模型:Restful ABAP Programming模型,簡稱為RAP模型。該模型定義了一套架構體系,應用開發人員能夠憑藉其來高效地進行應用的端到端開發,這種應用具有與生俱來的Restful特質,能充分利用HANA平臺的強大計算能力,支援雲環境和Fiori UX。
RAP模型的三大支柱:
- Business Service
- Core Data Service
- Behavior Definition
下面請跟著Jerry一起,透過一個實際的例子,瞭解一下這種全新的透過Restful ABAP Programming模型進行Fiori應用開發的步驟吧。
Jerry還是沿用傳統ABAP On-Premises程式設計培訓教材裡使用過的經典的SFLIGHT模型來作為底層資料庫儲存。
(1)首先建立一個資料庫表ZTRAVEL_JERRY:(如果想複製這段原始碼,請點選文末的“閱讀原文”獲得)
@EndUserText.label : 'Database table for travel data XXX'
@AbapCatalog.enhancementCategory : #NOT_EXTENSIBLE
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #LIMITED
define table ztravel_jerry {
key client : abap.clnt not null;
key travel_id : /dmo/travel_id not null;
agency_id : /dmo/agency_id;
customer_id : /dmo/customer_id;
begin_date : /dmo/begin_date;
end_date : /dmo/end_date;
@Semantics.amount.currencyCode : 'ztravel_jerry.currency_code'
booking_fee : /dmo/booking_fee;
@Semantics.amount.currencyCode : 'ztravel_jerry.currency_code'
total_price : /dmo/total_price;
currency_code : /dmo/currency_code;
description : /dmo/description;
created_by : syuname;
created_at : timestampl;
last_changed_by : syuname;
last_changed_at : timestampl;
}
因為我們在ABAP Development Tools裡無法用事務碼SE16手動往這張表裡插入資料,所以我建立一個ABAP類,用ABAP程式碼往這個表裡插入三條資料。
按F9執行這個ABAP類,然後看到三條資料成功插入了:
(2) 我們最終的目的是建立一個支援對這張表進行增刪改查的Fiori應用,而Restful ABAP Programming模型的三大支柱之一為Core Data Service,因此我們首先得有基於資料庫表ZTRAVEL_JERRY的CDS view.
所以我首先建立一個CDS view:
@AbapCatalog.sqlViewName: 'ZVI_TRAVEL'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Travel data - XXX'
define root view ZI_TRAVEL_JERRY
as select from ztravel_jerry as Travel
/* Associations */
association [0..1] to /DMO/I_Agency as _Agency on $projection.agency_id = _Agency.AgencyID
association [0..1] to /DMO/I_Customer as _Customer on $projection.customer_id = _Customer.CustomerID
association [0..1] to I_Currency as _Currency on $projection.currency_code = _Currency.Currency
{
key travel_id,
agency_id,
customer_id,
begin_date,
end_date,
@Semantics.amount.currencyCode: 'currency_code'
booking_fee,
@Semantics.amount.currencyCode: 'currency_code'
total_price,
@Semantics.currencyCode: true
currency_code,
description,
/*-- Admin data --*/
@Semantics.user.createdBy: true
created_by,
@Semantics.systemDateTime.createdAt: true
created_at,
@Semantics.user.lastChangedBy: true
last_changed_by,
@Semantics.systemDateTime.lastChangedAt: true
last_changed_at,
/* Public associations */
_Agency,
_Customer,
_Currency
}
然後建立一個projection view,將該view的欄位有選擇性地暴露出來。
@EndUserText.label: 'Travel projection view - Processor'
@AccessControl.authorizationCheck: #NOT_REQUIRED
@UI: {
headerInfo: { typeName: 'Travel', typeNamePlural: 'Travels', title: { type: #STANDARD, value: 'TravelID' } } }
@Search.searchable: true
define root view entity ZC_TRAVEL_JERRY as projection on ZI_TRAVEL_JERRY {
@UI.facet: [ { id: 'Travel',
purpose: #STANDARD,
type: #IDENTIFICATION_REFERENCE,
label: 'Travel',
position: 10 } ]
@UI: {
lineItem: [ { position: 10, importance: #HIGH } ],
identification: [ { position: 10, label: 'Travel ID [1,...,99999999]' } ] }
@Search.defaultSearchElement: true
key travel_id as TravelID,
@UI: {
lineItem: [ { position: 20, importance: #HIGH } ],
identification: [ { position: 20 } ],
selectionField: [ { position: 20 } ] }
@Consumption.valueHelpDefinition: [{ entity : {name: '/DMO/I_Agency', element: 'AgencyID' } }]
@ObjectModel.text.element: ['AgencyName'] ----meaning?
@Search.defaultSearchElement: true
agency_id as AgencyID, _Agency.Name as AgencyName,
@UI: {
lineItem: [ { position: 30, importance: #HIGH } ],
identification: [ { position: 30 } ],
selectionField: [ { position: 30 } ] }
@Consumption.valueHelpDefinition: [{ entity : {name: '/DMO/I_Customer', element: 'CustomerID' } }]
@ObjectModel.text.element: ['CustomerName']
@Search.defaultSearchElement: true
customer_id as CustomerID,
@UI.hidden: true
_Customer.LastName as CustomerName,
@UI: {
lineItem: [ { position: 40, importance: #MEDIUM } ],
identification: [ { position: 40 } ] }
begin_date as BeginDate,
@UI: {
lineItem: [ { position: 41, importance: #MEDIUM } ],
identification: [ { position: 41 } ] }
end_date as EndDate,
@UI: {
lineItem: [ { position: 50, importance: #MEDIUM } ],
identification: [ { position: 50, label: 'Total Price' } ] }
@Semantics.amount.currencyCode: 'CurrencyCode'
total_price as TotalPrice,
@Consumption.valueHelpDefinition: [{entity: {name: 'I_Currency', element: 'Currency' }}]
currency_code as CurrencyCode,
@UI.identification: [ { position: 60, label: 'Remarks' } ]
description as Description,
@UI.hidden: true
last_changed_at as LastChangedAt
}
大家可以注意到,這個projection view裡包含了很多@UI註解,作用和Fiori Elements一樣,作為後設資料,告訴對應的渲染框架,執行時這些欄位應該以什麼樣的方式渲染在Fiori UI上。
(3) 現在三大支柱之一的Core Data Service已經就位了,接下來我們基於前一步得到的projection view建立Business Service. 選中projection view,右鍵選擇New Service Definition:
這個服務定義的第一條記錄,就是透過ABAP expose關鍵字把projection view ZC_TRAVEL_JERRY暴露出來,模型名稱為TravelProcessor:
@EndUserText.label: 'Service Defintion for ZC_Travel_JERRY'
define service ZUI_C_TRAVEL_JERRY {
expose ZC_TRAVEL_JERRY as TravelProcessor;
expose /DMO/I_Customer as Passenger;
expose /DMO/I_Agency as TravelAgency;
expose /DMO/I_Airport as Airport;
expose I_Currency as Currency;
expose I_Country as Country;
}
然後基於這個Service Definition建立一個Service Binding,可以簡單把Service Binding理解成Service Definition的一個例項:
Service Binding建立完畢後,點選Activate啟用:
之前Service Definition裡用expose關鍵字暴露並指定成的模型TravelProcessor此時就可見了,雙擊:
雙擊後會自動開啟一個連結,一個Fiori應用就呈現在我們眼前了。我們沒有進行一行的JavaScript web程式設計,就得到了一個專業的支援高階搜尋的Fiori應用,能檢視底層資料庫表ZTRAVEL_JERRY的內容。
(4) 至此我們已經瞭解了Restful ABAP Programming模型的前兩大支柱,還剩下Behavior Definition. 既然RAP的口號是打造具有Restful特性的應用,但到目前為止我們還沒有感受到RAP對Restful的支援,這有待Behavior Definition來完成。
選中之前建立的CDS view,建立一個新的Behavior Definition:
實現型別指定為Managed:
我們可以看到這個Behavior Definition的定義裡,又多了一些新的ABAP關鍵字。這個Behavior Definition負責定義底層模型的Transaction Behavior,即程式碼第18到20行的create,update,delete.
當然增刪改查的功能光定義不行,還得建立其對應的實現。上圖Definition中已經指定了實現這些行為的ABAP類名稱為ZCL_BP_I_TRAVEL_M_JERRY. 為此,右鍵選擇New Behavior Implementation:
建立這個特殊的ABAP實現類:
這個實現類裡面也不需要開發人員手動編寫程式碼來完成對底層資料庫表的增刪改查操作——既然能稱之為一個程式設計模型,那麼這些通用的功能都透過框架類CL_ABAP_BEHAVIOR_HANDLER統一完成了,應用開發人員只需要定義一個對該類的宣告即可。
把這一步建立好的Behavior Definition模型和其實現全部啟用,然後回到我們之前瀏覽器裡開啟的Fiori應用,重新整理,會發現多了Create和Delete兩個按鈕,這意味著該應用對建立和刪除的支援也已經自動可用了。
同之前的搜尋功能一樣,這些功能的自動獲得,都是建立在應用開發人員一行JavaScript程式碼都不用編寫的基礎上的,由此大家感受到了Restful ABAP Programming模型的強大威力了嗎?
後續Jerry會繼續介紹如何給這個Fiori應用底層使用的模型增添Action和Validation功能,敬請期待。
要獲取更多Jerry的原創文章,請關注公眾號"汪子熙":
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/24475491/viewspace-2659278/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 如何基於Restful ABAP Programming模型開發並部署一個支援增刪改查的Fiori應用REST模型
- 如何使用 Restful ABAP Programming 程式設計模型開發一個支援增刪改查的 Fiori 應用REST程式設計模型
- 如何使用Flask開發一個增刪改查的應用Flask
- 一個典型的使用 SAP Cloud Application Programming 模型開發的 Fiori 應用CloudAPP模型
- Jerry帶您瞭解Restful ABAP Programming模型系列之三:雲端ABAP應用除錯REST模型除錯
- 30分鐘編寫一個Flask應用Flask
- 如何在 30 分鐘完成表格增刪改查的前後端框架搭建後端框架
- JavaScript中陣列的增刪改查以及應用方式JavaScript陣列
- 用thinkphp進行增刪改查的操作PHP
- 使用篇-基於Laravel開發部落格應用系列——後臺文章增刪改查功能實現(支援Markdown)Laravel
- 運用layui實現增刪改查UI
- 使用mybatis開發的增刪改查操作MyBatis
- SSM整合_年輕人的第一個增刪改查_查詢SSM
- Restful ABAP Programming模型系列二:Action和Validation的實現REST模型
- 增刪改查
- C/C++ Qt 資料庫QSql增刪改查元件應用C++QT資料庫SQL元件
- iOS CoreData (一) 增刪改查iOS
- SSM整合_年輕人的第一個增刪改查_新增SSM
- 本地開發好的 SAP Fiori Elements 應用,如何部署到 ABAP 伺服器上?伺服器
- 用 react+moox 五分鐘寫一個 todomvc 應用ReactMVC
- 安卓開發SQLite增刪改查操作例項安卓SQLite
- QBMySQL與PHP的基礎與應用專題之增刪改查uneMySqlPHP
- 關於ToDolist 的增刪改查 用jQuery來實現jQuery
- 用jsp實現資料庫的增刪改查JS資料庫
- layui的增刪改查UI
- 列表的增刪改查
- 字典的增刪改查
- redist的增刪改查Redis
- Mybatis的增刪改查MyBatis
- MongoDB的增刪改查MongoDB
- ThinkPHP的增、刪、改、查PHP
- 【URLOS應用開發基礎】10分鐘製作一個nginx靜態網站環境應用Nginx網站
- 基於gin的golang web開發:mysql增刪改查GolangWebMySql
- indexedDB 增刪改查Index
- SQL增刪改查SQL
- mysql增刪改查MySql
- Mongoose查增改刪Go
- FMDB增刪改查