30分鐘用Restful ABAP Programming模型開發一個支援增刪改查的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功能,敬請期待。
相關推薦
30分鐘用Restful ABAP Programming模型開發一個支援增刪改查的Fiori應用
這個系列的部落格集可以在Jerry這篇公眾號文章裡獲得:Jerry的通過CDS view + Smart Template 開發Fiori應用的blog合集。 三年的時間過去了,ABAP在不斷向前進化,如今我們有了新的程式設計模型:Restful ABAP Programming模型,簡稱為RAP模型。該模
【Mac系統 + Python + Django】之開發一個釋出會系統【Django模型(二)】 【Mac系統 + Mysql】之安裝Mysql資料庫 【Python + Mysql】之用pymysql庫連線Mysql資料庫並進行增刪改查操作
上一部分給大家介紹Django的檢視。 接下來繼續來了解Django框架,來看第二部分,此部分是對資料庫的操作。 目錄: 一、設計系統表 二、admin後臺管理 三、基本資料訪問(SQLite資料庫) 四、Django配置MySQL &
Mock.js簡易教程,脫離後端獨立開發,實現增刪改查功能
定義 數據 false 則表達式 type break 整數 增 刪 改 查 大於 在我們的生產實際中,後端的接口往往是較晚才會出來,並且還要寫接口文檔,於是我們的前端的許多開發都要等到接口給我們才能進行,這樣對於我們前端來說顯得十分的被動,於是有沒有可以制造假數據來模擬後
用nodejs建立伺服器實現使用者資訊的增刪改查
1.目錄的結構 node_modules 儲存的是下載好的所需要的包檔案目錄(使用npm下載) public 儲存的是靜態資源(即寫好的HTML頁面) &nb
用java製作一個具有增刪改查的簡單的學生管理系統
1、學生成員類 package mystudentManage; public class Student { private String name; private String stdId; private String age;
微信小程式之雲開發——模擬後臺增刪改查
小程式雲開發出來之後,小程式開發人員也要慢慢的接觸後端對資料的增刪改查了。下面就給大家提供一個案例吧。 這裡我把新增和修改放在了一個頁面 顯示頁面index.wxml <view wx:if="{{books}}" class='container
用單鏈表實現學生管理系統的增刪改查
連結串列的刪除和查詢 在帶頭節點的單鏈表中刪除p所指的節點,返回刪除成功的標誌。由於在單鏈表中只有指向後集結點的指標,所以先要呼叫查詢的函式,所輸入的學號與連結串列中的按順序查詢,找到了則將它刪除。 int deleteV_link(LinkList llist, int x)//刪除第一個值為x的結
iOS開發-plist檔案增刪改查
說到plist檔案,很直接的想法就是把資料已經編譯到手機上,非常的簡單省時間。。。但是有個問題 我也是待驗證 是不是程式碼操作可以刪除目錄下的plist檔案 這個待驗證哦! plist第一次看到這個字尾名檔案的時候感覺怪怪的,不過接觸久了也就習以為常了,plist
SSM 整合開發+通用的增刪改查實現
前一段時間開發java web專案都是採用的SSH框架,開發中發現在使用Hibernate做持久層開發的時候用法不夠靈活,過於笨重,因此,改用MyBaties,結合Spring、SpringMvc框架,現將配置過程梳理如下: 一、專案結構
通過用戶模型,對數據庫進行增刪改查操作
tab 接受 ssi fig app lte str 程序 ask 增加:db.session.add(user)db.session.commit() 查詢:User.query.filter(User.username == ‘mis1114‘).first() 修改:
通過用戶模型,對數據庫進行增刪改查操作。
lte integer fig 用戶 run __name__ bsp model table from flask import Flask from flask_sqlalchemy import SQLAlchemy import config app = Fla
Vue 30分鐘搞定前端增刪改查
閱讀目錄 一、MVVM大比拼 二、Vue常用網址 三、Vue基礎入門 1、MVVM圖例 2、第一個Vue例項 3、雙向繫結 四、常用指令 1、v-text、v-html指令 2、v-model指令
[譯] 用 Flask 和 Vue.js 開發一個單頁面應用
原文地址:Developing a Single Page App with Flask and Vue.js 原文作者:Michael Herman 譯文出自:掘金翻譯計劃 本文永久連結:github.com/xitu/gold-m… 譯者:Mcskiller
用20分鐘掌握MySQL增刪改查常用語句
安裝mysql資料庫後第一步就是開啟資料庫建立表格;進行增刪改查操作,掌握常用的SQL語句操作是非常有必要的,mysql資料庫有許多方便操作的可檢視形化軟體,而小編用的正是sqlyog這款圖形化介面操作軟體 mysql修改類操作語句 SQL語句不區分大小寫,
基於SpringBoot開發一個Restful服務,實現增刪改查功能
ner github上 epo column dex typealias odin 開發人員 java 在去年的時候,在各種渠道中略微的了解了SpringBoot,在開發web項目的時候是如何的方便、快捷。但是當時並沒有認真的去學習下,畢竟感覺自己在Struts和Spr
JS元件系列——又一款MVVM元件:Vue(一:30分鐘搞定前端增刪改查)
正文 前言:關於Vue框架,好幾個月之前就聽說過,瞭解一項新技術之後,總是處於觀望狀態,一直在猶豫要不要系統學習下。正好最近有點空,就去官網瞭解了下,看上去還不錯的一個元件,就抽空研究了下。最近園子裡vue也確實挺火,各種入門博文眼花繚亂,博主也不敢說寫
jeesite應用實戰(資料增刪改查),認真讀完後10分鐘就能開發一個模組
jeesite配置指南(官方文件有坑,我把坑填了!)這篇文章裡,我主要把jeesite官方給出的幫助文件的坑填了,按照裡面的方法可以搭建起來jeesite的站點。系統可以執行以後,就可以進入開發模組了,我們先從資料的增刪改查做起。 一、頁面效果 很
Yii框架實現restful 接口調用,增刪改查
png src params func delete soft -s 技術 val 創建模塊modules; 在main.php中配置文件:(1) (2)控制器層: namespace frontend\mod
[python] 用pickle模塊實現“增刪改查”的簡易功能
python pyckle模塊 #!/usr/bin/env python2 #coding:utf-8 """ pickle的作用: 1:pickle.dump(dict,file)把字典轉為二進制存入文件. 2:pickle.load(file)把文件二進制內容轉為字典. """ im
abap 的數據庫增刪改查
main 一個 所有 工作區 blog span 數據 視圖 目的 數據庫中插入新條目。 1.插入單行數據: INSERT INTO dbtab VALUES wa. INSERT INTO dbtab FROM wa. wa為工作區,是與數據庫具有相同結構的數據對象,一般