Hybris Enterprise Commerce Platform 服務層的設計與實現
Hybris Enterprise Commerce Platform這個系列之前已經由我的同事,SAP成都研究院Hybris開發團隊的同事 張健(Zhang Jonathan) 釋出過兩篇文章了。這裡Jerry要特別感謝張健,儘管最近他的第二個孩子誕生了,工作之餘的生活變得更加忙碌,然而張健仍然抽出少的可憐的業餘時間完成了這個系列的第三篇文章。
前兩篇文章分別介紹了SAP Hybris的前端和DTO層:
本文由張健繼續向我們介紹SAP Hybris的持久層即Service層。下面是他的正文。
前兩篇文章分別介紹了SAP Hybris的前端和DTO層:
-
從產品展示頁面談談Hybris的特有概念和設計結構
-
從產品展示頁面談談Hybris系列之二: DTO, Converter和Populator
當我們開啟Hybris某個Product的明細頁面時,Hybris後臺執行了下面三步邏輯:
1. Service層從資料庫裡把資料取出,以Model(又稱為DAO物件)的形式返回給Facade層。
2. Facade層呼叫Converter, 在Populator的幫助下,基於Model生成了DTO。
3. Product明細頁面的Controller將其對應的JSP檢視路徑返回給Hybris框架,透過JSP技術繪製出最後的UI。
其中步驟2和3已經在這個系列前兩篇文章介紹過,本文將詳細介紹上述步驟1。
Service層用XML定義的形式來管理Hybris的型別系統,既建立起與資料庫表的關聯,又將型別系統與具體的資料庫實現進行了隔離。Service層的ModelService和Flexible Search提供了便捷的增刪改查功能。讓我們來一一瞭解。
Hybris型別系統
在DTO層的ProductFacade裡,呼叫了Service層中獲取ProductModel的方法如下。
很簡單的幾句程式碼,和其他常見的Java Web專案的Service很相似。那麼ProductModel是需要開發人員自行建立嗎?
應當注意ProductModel這樣的POJO類(Plain Old Java Object)不需開發人員自行建立,而是透過Hybris自有的型別系統生成的。
Hybris裡的型別分為兩類,第一類是包含所有Hybris業務相關型別的ItemType(又稱ComposedType),Product即是這種型別。第二類是為ItemType的集合屬性和關係屬性提供支援的DataType, 包括了 CollectionTypes, MapTypes, EnumerationTypes, RelationTypes 和 AtomicTypes。例如產品對應的多個媒體檔案,就可以用CollectionTypes來定義,然後再用RelationTypes和Product型別做關聯。
ABAP顧問們可以把前者(ItemType)類比成ABAP Data Dictionary裡定義的包含了業務邏輯的全域性資料型別,而後者就是ABAP裡用STANDARD, SORTED和HASHED TABLE等等將這些業務資料型別的一個聚合。而對於Java開發者來說, CollectionTypes, MapTypes這些型別其實就是Hybris對JDK中的List, Map等型別一個更高層次的抽象。
items.xml
和Hibernate框架使用XML定義型別和資料庫配置相似,Hybris型別系統的具體定義存在各個extension的items.xml檔案裡。比如Product型別是存在於"../hybris/bin/platform/ext/core/resources"資料夾下的core-items.xml檔案內。這個檔案也定義了很多Hybris核心的業務型別。
我們看一個實際的例子,即Product型別在items.xml中的定義。SAP Hybris的幫助文件裡有items.xml裡每個欄位的詳細含義,這裡只介紹下圖中紅色高亮的欄位。
extends: GenericItem。表明Product這個型別是在另一個型別GenericItem基礎上做擴充套件。
GenericItem是根型別,相當於Java型別系統的java.lang.Object。Hybris型別系統透過繼承的方式避免了欄位的重複建模。
假設我們已經用上面展示的items.xml進行了Product的建模,現在有一個新的需求,定義CustomerProduct型別。從業務上說,CustomerProduct僅僅是在Product型別的基礎上增加一個欄位用於維護Customer ID。ABAP顧問們會新建一個CustomerProduct的結構,把Product型別透過Include的方式新增到CustomerProduct中去,透過include的方式繼承前者上維護的所有欄位,然後只需在CustomerProduct上定義一個新欄位CUSTOMER_ID即可。
對於Hybris型別系統,思路類似,用CustomerProduct型別去extends Product型別,然後只需定義一個CustomerID欄位即可。
autocreate = true: 在執行Hybris命令列ant initialize進行Hybris系統初始化時,根據items.xml的定義在資料庫表中建立對應的型別。
generate = true: 在ant編譯時生成該型別對應的POJO類。
以上圖的Product型別為例,因為generate屬性設定為true, 因此編譯之後,我們能在下面的資料夾發現一個自動生成的POJO類,命名規範為<型別名稱>Model.java:
hybrisinplatformootstrapgensrcdehybrisplatformcoremodelproduct
和ABAP很多自動生成的資源通常都放在名為$GEN之類的包的套路一樣,POJO類所在的檔案目錄中的gensrc,也提示了該檔案是自動生成的。
開啟ProductModel.java檢視其內容,能進一步瞭解items.xml裡定義的屬性是如何對映到這個自動生成的POJO類的:items.xml裡定義的每一個型別屬性,都會在POJO類裡自動生成一套set和get方法。
以name屬性為例,在ProductModel.java裡自動生成的setName和getName:
table = Products: 資料庫對應的表名,在整個Hybris型別系統唯一存在。
attribute autocreate="true" qualifier="code" type="java.lang.String" generate="true":POLO類中會出現一個新的成員,名稱為code,型別為String,並帶有set和get方法,ant initialize時在資料庫表中建立該屬性。
ModelService
定義好型別後,就需要開發相應的增刪改查功能了。Hybris提供了de.hybris.platform.servicelayer.model.ModelService類作為幫助類,只需傳入POJO類給對應方法,即可實現增刪改查功能。這和Hibernate裡的幫助類的用法是類似的。查詢操作對應get方法,建立和更新對應save方法,刪除操作則為remove方法。還有saveAll和removeAll方法,只需傳入業務型別的集合即可實現批次增改或刪除。
下圖是一個例子,透過getModelService拿到ModelService例項,執行save操作。
Flexible Search
對於複雜查詢,Hybris也提供了自己的查詢語句Flexsible Search。如ProductDao中使用的關聯Category型別的查詢:
用過ADBC和JDBC的ABAP顧問和Java開發者,對上面的程式碼一定不會陌生。
下面是從Jerry的部落格裡摘出來的一張圖,ADBC和JDBC的對比:
https://blogs.sap.com/2017/05/08/adbc-and-jdbc/
Hybris支援主流資料庫,包括MySQL,Oracle,SQL Server及SAP HANA資料庫等等。而Flexible Search概念的引入,思路類似ABAP Open SQL,透過編寫不依賴於任何具體資料庫提供商的Flexible Search程式碼,將Hybris應用層同底層資料庫的具體實現做了解耦。而上面的語句中,POJO類裡如ProductModel._TYPECODE 的值就是“Product”,是編譯時自動生成的。因此查詢語句可轉譯成如下文字:
問號後面的”Category“是要傳入查詢語句的引數名,這裡即為傳入了方法的引數“CategoryModel”。
到這裡Hybris的Service層就基本介紹完了,而Hybris概要的系列文章也告一段落。希望大家透過這些文章對Hybris Enterprise Commerce Platform有一定的認識。感謝閱讀。
要獲取更多Jerry的原創技術文章,請關注公眾號"汪子熙"或者掃描下面二維碼:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/24475491/viewspace-2169023/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Hybris ECP(Enterprise Commerce Platform)的除錯Platform除錯
- 服務API版本控制設計與實踐API
- c++ 層實現binder服務樣例C++
- 服務設計的原則:服務模式與反模式模式
- NodeJs服務註冊與服務發現實現NodeJS
- WCF 設計和實現服務協定(01)
- Redis 設計與實現 (七)--事務Redis
- 服務計算 SO 服務的設計
- SAP ABAP和Hybris Commerce的Sample資料
- SAP Hybris Commerce裡的資料庫表資料庫
- 微服務~Eureka實現的服務註冊與發現及服務之間的呼叫微服務
- [翻譯]微服務設計模式 - 5. 服務發現 - 服務端服務發現微服務設計模式服務端
- CRM, C4C和SAP Hybris的資料庫層設計資料庫
- Hybris開發環境的license計算實現開發環境
- 服務註冊與發現的原理和實現
- Eureka實現服務註冊與發現
- 馬蜂窩ABTest多層分流系統的設計與實現
- SAP ABAP Netweaver和Hybris Commerce的部署策略
- Hybris UI的Route(路由)實現UI路由
- vivo 服務端監控架構設計與實踐服務端架構
- SAP Netweaver和Hybris Commerce啟動後執行的預設操作
- 百億流量微服務閘道器的設計與實現微服務
- 實現etcd服務註冊與發現
- Titan 的設計與實現
- LFU 的設計與實現
- API的設計與實現API
- SAP Hybris Commerce product讀取的除錯截圖除錯
- SAP Hybris Commerce 新版本功能解析
- binder 一個簡單的c++服務的實現,與callback實現C++
- 關於 Hybris (SAP Commerce Cloud)產品的客戶群Cloud
- 微服務的接入層設計與動靜資源隔離微服務
- SAP Commerce(SAP Hybris)學習資料彙總
- 如何在Hybris commerce裡建立一個media物件物件
- ABAP的OPEN SQL和Hybris Commerce的Flexible Search簡介SQLFlex
- Picker元件的設計與實現元件
- RedisHttpSession 的設計與實現RedisHTTPSession
- 限流 SDK 的設計與實現
- 微服務5:服務註冊與發現(實踐篇)微服務