|
Hybris Enterprise Commerce Platform這個(gè)系列之前已經(jīng)由我的同事,SAP成都研究院Hybris開(kāi)發(fā)團(tuán)隊(duì)的同事張健(Zhang Jonathan)發(fā)布過(guò)兩篇文章了。這里Jerry要特別感謝張健,盡管最近他的第二個(gè)孩子誕生了,工作之余的生活變得更加忙碌,然而張健仍然抽出少的可憐的業(yè)余時(shí)間完成了這個(gè)系列的第三篇文章。 前兩篇文章分別介紹了SAP Hybris的前端和DTO層: 本文由張健繼續(xù)向我們介紹SAP Hybris的持久層即Service層。下面是他的正文。 前兩篇文章分別介紹了SAP Hybris的前端和DTO層:
當(dāng)我們打開(kāi)Hybris某個(gè)Product的明細(xì)頁(yè)面時(shí),Hybris后臺(tái)執(zhí)行了下面三步邏輯: 1. Service層從數(shù)據(jù)庫(kù)里把數(shù)據(jù)取出,以Model(又稱(chēng)為DAO對(duì)象)的形式返回給Facade層。 2. Facade層調(diào)用Converter, 在Populator的幫助下,基于Model生成了DTO。 3. Product明細(xì)頁(yè)面的Controller將其對(duì)應(yīng)的JSP視圖路徑返回給Hybris框架,通過(guò)JSP技術(shù)繪制出最后的UI。 其中步驟2和3已經(jīng)在這個(gè)系列前兩篇文章介紹過(guò),本文將詳細(xì)介紹上述步驟1。 Service層用XML定義的形式來(lái)管理Hybris的類(lèi)型系統(tǒng),既建立起與數(shù)據(jù)庫(kù)表的關(guān)聯(lián),又將類(lèi)型系統(tǒng)與具體的數(shù)據(jù)庫(kù)實(shí)現(xiàn)進(jìn)行了隔離。Service層的ModelService和Flexible Search提供了便捷的增刪改查功能。讓我們來(lái)一一了解。 Hybris類(lèi)型系統(tǒng)在DTO層的ProductFacade里,調(diào)用了Service層中獲取ProductModel的方法如下。 很簡(jiǎn)單的幾句代碼,和其他常見(jiàn)的Java Web項(xiàng)目的Service很相似。那么ProductModel是需要開(kāi)發(fā)人員自行創(chuàng)建嗎? 應(yīng)當(dāng)注意ProductModel這樣的POJO類(lèi)(Plain Old Java Object)不需開(kāi)發(fā)人員自行創(chuàng)建,而是通過(guò)Hybris自有的類(lèi)型系統(tǒng)生成的。 Hybris里的類(lèi)型分為兩類(lèi),第一類(lèi)是包含所有Hybris業(yè)務(wù)相關(guān)類(lèi)型的ItemType(又稱(chēng)ComposedType),Product即是這種類(lèi)型。第二類(lèi)是為ItemType的集合屬性和關(guān)系屬性提供支持的DataType, 包括了 CollectionTypes, MapTypes, EnumerationTypes, RelationTypes 和 AtomicTypes。例如產(chǎn)品對(duì)應(yīng)的多個(gè)媒體文件,就可以用CollectionTypes來(lái)定義,然后再用RelationTypes和Product類(lèi)型做關(guān)聯(lián)。 ABAP顧問(wèn)們可以把前者(ItemType)類(lèi)比成ABAP Data Dictionary里定義的包含了業(yè)務(wù)邏輯的全局?jǐn)?shù)據(jù)類(lèi)型,而后者就是ABAP里用STANDARD, SORTED和HASHED TABLE等等將這些業(yè)務(wù)數(shù)據(jù)類(lèi)型的一個(gè)聚合。而對(duì)于Java開(kāi)發(fā)者來(lái)說(shuō), CollectionTypes, MapTypes這些類(lèi)型其實(shí)就是Hybris對(duì)JDK中的List, Map等類(lèi)型一個(gè)更高層次的抽象。 items.xml和Hibernate框架使用XML定義類(lèi)型和數(shù)據(jù)庫(kù)配置相似,Hybris類(lèi)型系統(tǒng)的具體定義存在各個(gè)extension的items.xml文件里。比如Product類(lèi)型是存在于"../hybris/bin/platform/ext/core/resources"文件夾下的core-items.xml文件內(nèi)。這個(gè)文件也定義了很多Hybris核心的業(yè)務(wù)類(lèi)型。 我們看一個(gè)實(shí)際的例子,即Product類(lèi)型在items.xml中的定義。SAP Hybris的幫助文檔里有items.xml里每個(gè)字段的詳細(xì)含義,這里只介紹下圖中紅色高亮的字段。 extends: GenericItem。表明Product這個(gè)類(lèi)型是在另一個(gè)類(lèi)型GenericItem基礎(chǔ)上做擴(kuò)展。 GenericItem是根類(lèi)型,相當(dāng)于Java類(lèi)型系統(tǒng)的java.lang.Object。Hybris類(lèi)型系統(tǒng)通過(guò)繼承的方式避免了字段的重復(fù)建模。 假設(shè)我們已經(jīng)用上面展示的items.xml進(jìn)行了Product的建模,現(xiàn)在有一個(gè)新的需求,定義CustomerProduct類(lèi)型。從業(yè)務(wù)上說(shuō),CustomerProduct僅僅是在Product類(lèi)型的基礎(chǔ)上增加一個(gè)字段用于維護(hù)Customer ID。ABAP顧問(wèn)們會(huì)新建一個(gè)CustomerProduct的結(jié)構(gòu),把Product類(lèi)型通過(guò)Include的方式添加到CustomerProduct中去,通過(guò)include的方式繼承前者上維護(hù)的所有字段,然后只需在CustomerProduct上定義一個(gè)新字段CUSTOMER_ID即可。 對(duì)于Hybris類(lèi)型系統(tǒng),思路類(lèi)似,用CustomerProduct類(lèi)型去extends Product類(lèi)型,然后只需定義一個(gè)CustomerID字段即可。 autocreate = true: 在執(zhí)行Hybris命令行ant initialize進(jìn)行Hybris系統(tǒng)初始化時(shí),根據(jù)items.xml的定義在數(shù)據(jù)庫(kù)表中創(chuàng)建對(duì)應(yīng)的類(lèi)型。 generate = true: 在ant編譯時(shí)生成該類(lèi)型對(duì)應(yīng)的POJO類(lèi)。 以上圖的Product類(lèi)型為例,因?yàn)間enerate屬性設(shè)置為true, 因此編譯之后,我們能在下面的文件夾發(fā)現(xiàn)一個(gè)自動(dòng)生成的POJO類(lèi),命名規(guī)范為<類(lèi)型名稱(chēng)>Model.java: hybrisinplatformootstrapgensrcdehybrisplatformcoremodelproduct 和ABAP很多自動(dòng)生成的資源通常都放在名為$GEN之類(lèi)的包的套路一樣,POJO類(lèi)所在的文件目錄中的gensrc,也提示了該文件是自動(dòng)生成的。 打開(kāi)ProductModel.java查看其內(nèi)容,能進(jìn)一步了解items.xml里定義的屬性是如何映射到這個(gè)自動(dòng)生成的POJO類(lèi)的:items.xml里定義的每一個(gè)類(lèi)型屬性,都會(huì)在POJO類(lèi)里自動(dòng)生成一套set和get方法。 以name屬性為例,在ProductModel.java里自動(dòng)生成的setName和getName: table = Products: 數(shù)據(jù)庫(kù)對(duì)應(yīng)的表名,在整個(gè)Hybris類(lèi)型系統(tǒng)唯一存在。 attribute autocreate="true" qualifier="code" type="java.lang.String" generate="true":POLO類(lèi)中會(huì)出現(xiàn)一個(gè)新的成員,名稱(chēng)為code,類(lèi)型為String,并帶有set和get方法,ant initialize時(shí)在數(shù)據(jù)庫(kù)表中創(chuàng)建該屬性。 ModelService定義好類(lèi)型后,就需要開(kāi)發(fā)相應(yīng)的增刪改查功能了。Hybris提供了de.hybris.platform.servicelayer.model.ModelService類(lèi)作為幫助類(lèi),只需傳入POJO類(lèi)給對(duì)應(yīng)方法,即可實(shí)現(xiàn)增刪改查功能。這和Hibernate里的幫助類(lèi)的用法是類(lèi)似的。查詢(xún)操作對(duì)應(yīng)get方法,創(chuàng)建和更新對(duì)應(yīng)save方法,刪除操作則為remove方法。還有saveAll和removeAll方法,只需傳入業(yè)務(wù)類(lèi)型的集合即可實(shí)現(xiàn)批量增改或刪除。 下圖是一個(gè)例子,通過(guò)getModelService拿到ModelService實(shí)例,執(zhí)行save操作。
Flexible Search對(duì)于復(fù)雜查詢(xún),Hybris也提供了自己的查詢(xún)語(yǔ)句Flexsible Search。如ProductDao中使用的關(guān)聯(lián)Category類(lèi)型的查詢(xún):
用過(guò)ADBC和JDBC的ABAP顧問(wèn)和Java開(kāi)發(fā)者,對(duì)上面的代碼一定不會(huì)陌生。 下面是從Jerry的博客里摘出來(lái)的一張圖,ADBC和JDBC的對(duì)比:
https://blogs./2017/05/08/adbc-and-jdbc/ Hybris支持主流數(shù)據(jù)庫(kù),包括MySQL,Oracle,SQL Server及SAP HANA數(shù)據(jù)庫(kù)等等。而Flexible Search概念的引入,思路類(lèi)似ABAP Open SQL,通過(guò)編寫(xiě)不依賴(lài)于任何具體數(shù)據(jù)庫(kù)提供商的Flexible Search代碼,將Hybris應(yīng)用層同底層數(shù)據(jù)庫(kù)的具體實(shí)現(xiàn)做了解耦。而上面的語(yǔ)句中,POJO類(lèi)里如ProductModel._TYPECODE 的值就是“Product”,是編譯時(shí)自動(dòng)生成的。因此查詢(xún)語(yǔ)句可轉(zhuǎn)譯成如下文本:
問(wèn)號(hào)后面的”Category“是要傳入查詢(xún)語(yǔ)句的參數(shù)名,這里即為傳入了方法的參數(shù)“CategoryModel”。 到這里Hybris的Service層就基本介紹完了,而Hybris概要的系列文章也告一段落。希望大家通過(guò)這些文章對(duì)Hybris Enterprise Commerce Platform有一定的認(rèn)識(shí)。感謝閱讀。
要獲取更多Jerry的原創(chuàng)技術(shù)文章,請(qǐng)關(guān)注公眾號(hào)"汪子熙" |
|
|