Hybris Enterprise Commerce Platform 服務層的設計與實現

i042416發表於2018-08-02

Hybris Enterprise Commerce Platform這個系列之前已經由我的同事,SAP成都研究院Hybris開發團隊的同事 張健(Zhang Jonathan) 釋出過兩篇文章了。這裡Jerry要特別感謝張健,儘管最近他的第二個孩子誕生了,工作之餘的生活變得更加忙碌,然而張健仍然抽出少的可憐的業餘時間完成了這個系列的第三篇文章。

前兩篇文章分別介紹了SAP Hybris的前端和DTO層:

本文由張健繼續向我們介紹SAP Hybris的持久層即Service層。下面是他的正文。

Hybris Enterprise Commerce Platform 服務層的設計與實現

前兩篇文章分別介紹了SAP Hybris的前端和DTO層:

  • 從產品展示頁面談談Hybris的特有概念和設計結構

  • 從產品展示頁面談談Hybris系列之二: DTO, Converter和Populator

Hybris Enterprise Commerce Platform 服務層的設計與實現

當我們開啟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的方法如下。

Hybris Enterprise Commerce Platform 服務層的設計與實現

很簡單的幾句程式碼,和其他常見的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等型別一個更高層次的抽象。

Hybris Enterprise Commerce Platform 服務層的設計與實現

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裡每個欄位的詳細含義,這裡只介紹下圖中紅色高亮的欄位。

Hybris Enterprise Commerce Platform 服務層的設計與實現

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 Enterprise Commerce Platform 服務層的設計與實現

對於Hybris型別系統,思路類似,用CustomerProduct型別去extends Product型別,然後只需定義一個CustomerID欄位即可。

autocreate = true: 在執行Hybris命令列ant initialize進行Hybris系統初始化時,根據items.xml的定義在資料庫表中建立對應的型別。

generate = true: 在ant編譯時生成該型別對應的POJO類。

以上圖的Product型別為例,因為generate屬性設定為true, 因此編譯之後,我們能在下面的資料夾發現一個自動生成的POJO類,命名規範為<型別名稱>Model.java:

Hybris Enterprise Commerce Platform 服務層的設計與實現

hybrisinplatformootstrapgensrcdehybrisplatformcoremodelproduct

和ABAP很多自動生成的資源通常都放在名為$GEN之類的包的套路一樣,POJO類所在的檔案目錄中的gensrc,也提示了該檔案是自動生成的。

開啟ProductModel.java檢視其內容,能進一步瞭解items.xml裡定義的屬性是如何對映到這個自動生成的POJO類的:items.xml裡定義的每一個型別屬性,都會在POJO類裡自動生成一套set和get方法。

Hybris Enterprise Commerce Platform 服務層的設計與實現

以name屬性為例,在ProductModel.java裡自動生成的setName和getName:

Hybris Enterprise Commerce Platform 服務層的設計與實現

Hybris Enterprise Commerce Platform 服務層的設計與實現

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操作。

Hybris Enterprise Commerce Platform 服務層的設計與實現

Flexible Search

對於複雜查詢,Hybris也提供了自己的查詢語句Flexsible Search。如ProductDao中使用的關聯Category型別的查詢:

Hybris Enterprise Commerce Platform 服務層的設計與實現

用過ADBC和JDBC的ABAP顧問和Java開發者,對上面的程式碼一定不會陌生。

下面是從Jerry的部落格裡摘出來的一張圖,ADBC和JDBC的對比:

Hybris Enterprise Commerce Platform 服務層的設計與實現

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”,是編譯時自動生成的。因此查詢語句可轉譯成如下文字:

Hybris Enterprise Commerce Platform 服務層的設計與實現

問號後面的”Category“是要傳入查詢語句的引數名,這裡即為傳入了方法的引數“CategoryModel”。

到這裡Hybris的Service層就基本介紹完了,而Hybris概要的系列文章也告一段落。希望大家透過這些文章對Hybris Enterprise Commerce Platform有一定的認識。感謝閱讀。

Hybris Enterprise Commerce Platform 服務層的設計與實現

要獲取更多Jerry的原創技術文章,請關注公眾號"汪子熙"或者掃描下面二維碼:

Hybris Enterprise Commerce Platform 服務層的設計與實現

Hybris Enterprise Commerce Platform 服務層的設計與實現


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/24475491/viewspace-2169023/,如需轉載,請註明出處,否則將追究法律責任。

相關文章