Re: DAO interface 是否該包含 Hibernate 的 Criterion ...

来源:互联网 发布:unity3d路径动画插件 编辑:程序博客网 时间:2024/05/02 11:49

Problem:

假設一個 domain object: Product
我們在設計 dao 時可能設計一個 ProductDao interface , 包含
create(Product p) , getById(long) , Update(Product p) , Delete(Product p) 這四個 methods
接著再以 ProductDaoImpl 實作以上四個 methods , 此 ProductDaoImpl 則包含了 Hibernate 的 API

接著,在 Service Layer , 我們可能寫一個 ProductService interface , 除了基本的 CRUD 動作外,可能還包含了 getLatestProducts(int days) , 或是 getHotProducts(int count) 之類的 method.

問題來了,這些不屬於 CRUD 基本動作的 methods , 其實作部分,是否該交由底層的 ProductDao 及其 ProductDaoImpl 提供 , 還是在 ProductServiceImpl 中利用 Criterion 就解掉(如此一來 , ProductDao 就會變得跟 Hibernate dependent , 怎辦 ?)

我詳述一下好了,第一個方法,就是在 ProductDao 也提供 getLatestProducts(int days) 及 getHotProducts(int count) 兩個空 method , 並由 ProductDaoImpl 去實作出來
這缺點在於,如果這類『不屬於 CRUD 基本動做的 methods』越多,則 ProductDao 及 ProductDaoImpl 就會越長越長... 比較難看
但是好處則在於 ProductDao 不會與 Hibernate 相依

第二個方法:
就是在 ProductDao 這個 interface 中,加上這個 method :
public List<Product> findByCriterion(Criterion... criterion);
而其實作的 ProductDaoImpl 只要執行即可
至於在 ProductServiceImpl 中,則針對 getLatestProducts(int days) , 或是 getHotProducts(int count) 撰寫不同的 Criterions ,再傳進 ProductDao 中即可
這樣會造成一個缺點: ProductDao 就會和 Hibernate 相關...

我個人認為第二個方法比較漂亮(優雅)
但是這個 hibernate-dependent 的 interface ,在某些人眼中(包括我),實在是有點礙眼

My Answer:

提供一個HibernateSupport來封裝hibernate底層。
在DAO Interface定義findByCondition(String condition1,String condition2...)
在DAOImpl里實作之:
List findByCondition(String condition1,String condition2...)
{
Map conditionMap = new HashMap();
if(StringUtils.isNotEmpty(condition1) && condition1.equals("...")){
conditionMap.put("condition1",condition1)
}
if(StringUtils.isNotEmpty(condition2) && condition2.equals("...")){
conditionMap.put("condition2",condition2)
}
return HibernateSupport.queryByCondition(session,conditionMap);
}

這樣做的好處是:使查詢操作透明化了,並使商業邏輯與Hibernate底層解耦了。

原创粉丝点击