這是一個比實現問題更多的設計,它將會很長時間以待我。這是最好用一個例子說明: 通過服務API公開Hibernate標準
比方說,我有一個商業實體,稱爲產品了一堆屬性(名,價格,廠商,等...)。
它通過一個接口(產品)和執行(ProductImpl,在Hibernate中映射)以及基本的CRUD服務接口(ProductService)和執行(ProductServiceImpl)表示。
產品和ProductService公開爲API,但它們的實現不是。
我想添加一個列表findProducts(QueryCriteria標準)方法ProductService,將返回的產品滿足給定標準的列表。 的要求是:通過直接產品性質(例如product.price gt 50.0
)
product.vendor.name = "Oracle"
)order by product.vendor.name desc, product.price asc"
)
- 查詢
- 應用附加的過濾器。與由API客戶端全部指定的上述3個項目不同,服務可以基於客戶端身份(例如,客戶端調用該方法可能僅限於查看由給定供應商製造的產品)來應用額外的過濾器。這樣的過濾器的優先級高於由客戶端指定的任何標準(例如,如果過濾器被設置爲
product.vendor.name = "Microsoft"
,查詢在上述(2)應當產生空結果集。
的問題,因此,是什麼應該QueryCriteria通過這樣的方法使用的界面看起來像我能想到的3個解決方案,我也不喜歡他們中的一個:?
- 允許客戶端指定HQL(從「where」子句)直接 這是最直接的解決方案,但也是最有問題的安全方面。即使假定過濾器(上述#4)是簡單的如果足夠通過Hibernate的會話過濾器來實現,HQL仍然需要被解析爲 - 至少 - 確保查詢參數被指定爲參數而不是內聯。
- 使用纖細包裝的Hibernate的DetachedCriteria代替QueryCriteria。 「Thinly wrapped」,因爲客戶端不能被允許直接創建DetachedCriteria將無法控制它創建的映射實體。 此外,這不會像HQL那樣靈活,因爲某些查詢不容易(或根本不能)通過Criteria API表示。與HQL方法一樣,過濾器(上述#4)將僅限於Hibernate會話過濾器。
- 寫我自己的QueryCriteria接口/實現將在後臺形成DetachedCriteria或HQL。儘管可能是最靈活的解決方案,但它必須從Criteria API中複製很多代碼,這似乎不太理想。
任何有關上述方法的有效性的評論或 - 手指交叉 - 我沒有想到的簡單優雅的解決方案將不勝感激。
P.S.在我的具體情況中,所有的API客戶端都是內部的和「半可信的」 - 那就是我沒有太在意那些試圖故意破壞某些東西的人,因爲糟糕的編程導致了5張表的笛卡爾積:-)然而,它如果能夠提供一種能夠承受API暴露於公衆的解決方案,我們感到非常高興。
看起來這個問題已經持續了兩個月;我很好奇你定居在什麼地方?我想我會採取#3,「寫我自己的...」的方法,並試圖將我需要的信息「扁平化」到ProductService/criteria API中作爲可查詢屬性,具體取決於使用情況。 – RMorrisey 2009-09-22 00:20:30
@Rorrisey - 我已經添加了一個描述我的解決方案的答案。 – ChssPly76 2009-09-22 04:04:42