和一般的Hibernate Entity domain一樣,在Informa的impl.hibernate包下,包含了兩種類型的文件:java文件和Hibernate的XML映射文件。
逐個逐個地打開這些java文件和xml文件來看,我發現了幾個特點:
A.多數的Hibernate實現和Basic實現的代碼都是一摸一樣的,這一點并不奇怪。因為本來就是實體bean
B.所有的Hibernate實現都沒有在構造函數中調用IdGenerator生成ID,使用了數據庫生成的Id
在前面一節《RSS工具開發手記(08)---Informa的build.xml》中,我們提到了Informa的自定義task:schemaexport。這個task依靠于Hibernate的內在類“org.hibernate.tool.hbm2ddl.SchemaExportTask”在CLASSPATH下搜尋hbm文件,然后把這些映射文件導出為ddl文件。
在這個包里面比較值得研究的有下面幾個:
A.Channel
B.ChannelBuilder
C.ChannelUpdatePeriodUserType
D.SessionHandler
★Channel
經過和impl.basic包中Channel的比較,發現兩者的實現有如下的不同:
A.構造方法中多了3個方法,兩個是使用title和location來構造的,一個是使用Element,title,location來構造的
B.從Hibernate中檢索出來的是不用設置ID的,而從內存中生成的必須使用IdGenerator產生唯一ID
C.basic實現中沒有getLocationString方法和setLocationString方法
D.basic實現中沒有getSiteString方法和setSiteString方法
E.basic實現中沒有getGroup方法和setGroup方法
F.basic實現中沒有getFormatString和setFormatString方法
G.basic中沒有setItems方法,而且getItems方法中的實現不同(basic采用了同步的hashset,而hibernate沒有)
H.basic中的addItem方法是添加到hashmap,而hibernate中的addItem方法是添加到hashset
I.basic中的getItem方法是直接從map中根據ID獲取,而hibernate中的getItem是采用Iterator方法輪詢,而且不是從數據庫中獲取
我們來比較這兩個包中構造方法的代碼:
impl.basic包










impl.hibernate包











首先最明顯的一個區別就是Id的生成不同了,其次在impl.basic中使用同步的HashMap來存儲items,而在impl.hibernate中使用了HashSet。但是在下面impl.hibernate的getItem的方法中,兩者的效率明顯有了區別:
impl.basic



impl.hibernate
















在Hibernate實現包中,由于使用了HashSet,只能使用逐個迭代的方式來輪詢檢查,當item的數目比較多時,無疑效率被第一種低了很多。在作者的注釋中也提到了可以使用map。特別的這個getItem并非從數據庫的ITEMS表取出的。為什么要這樣做呢?
在查看了Channel的xml映射文件后,我有了一點頭緒





注意其中的lazy="false"屬性,這意味著當我們從數據庫中檢索Channel時,對應的item都會被檢出,然后填充到entity bean中,所以此時直接從Channel中的HashSet中拿就可以了。
至于同步方面我想原因可能是:impl.basic包中的實現是在內存中實現的,所以對于items必須進行同步。因此使用了Collections.synchronizedMap對訪問或存儲的item進行同步。而hibernate實現包中由于是Hibernate管理同步,所以不需要顯式地使用Collections.synchronizedSet來同步這個Set。
至于為什么在basic和hibernate包中有些屬性和方法是不存在的,構造方法也有不同,這兩點還有待于和作者探討。
-------------------------------------------------------------
生活就像打牌,不是要抓一手好牌,而是要盡力打好一手爛牌。