2009-02-05 59 views
4

通常,在定義DAO時,您需要爲DAO對象上的數據源設置一個setter。 我的問題是,我們的數據源根據對服務器的請求動態變化。即每個請求可以訪問不同的數據庫實例。如何在數據源動態變化時設計DAO

該請求包含邏輯屬性,稍後可用於檢索到請求數據庫的連接。

因此,當依賴注入到業務邏輯對象的DAO時,我需要一種方法來在運行時(不是配置時間)在DAO上設置屬性。

一個解決方案是將數據源存儲在線程本地,但我真的不喜歡弄亂線程局部變量。

另一種方法是在業務邏輯對象上使用請求屬性調用DAO初始化的初始化方法。

我想這是一個普遍的問題,你能提出一個通用的解決方案嗎?

回答

5

這聽起來像你的問題是,你正在爲你的應用程序創建一個單一的DAO實例。您需要爲每個數據源創建一個單獨的實例(可能會讓某種dao控制器爲您管理所有這些),或者可能允許您的dao中的方法是靜態的,並傳遞關於如何連接到數據源的所有信息您堅持進入每種方法的數據。

+0

明智的答案。 – 2010-03-28 12:48:47

8

你的問題有點混亂。讓一個DAO訪問多個不同的數據源似乎是一個維護的噩夢。因此,您應該定義一個包含所有您想要調用的方法的DAO接口。對於你連接的每個數據庫,我會構建一個實現你的DAO接口的新類。這允許你有多個實現。然後,我會將這些實現(每個都有自己的數據源)存儲在Map(java.util.Map)中,並使用「邏輯屬性」作爲映射關鍵字。由於所有DAO實現都實現了您的接口,因此您可以將它們轉換爲接口並交換使用。在您的業務對象上,您將注入DAO實現的Map。我希望這可以幫助你的設計。

5

我在客戶端/服務器項目上遇到過這樣的問題。客戶端和服務器項目共享Dao接口。當我用來做數據庫操作時,我不得不選擇合適的Dao實現。我的解決辦法是這樣的:從工廠

IVehicleDao vehicleDao =daoFactory.Get<IVehicleDao>(parameters); 
vehicleDao.doSomething(); 

獲取DAO通過傳遞parameters.Inside道工廠決定哪些DAO實現返回..

6

你可能想看看這個類:

http://static.springframework.org/spring/docs/2.5.x/api/org/springframework/jdbc/datasource/lookup/AbstractRoutingDataSource.html

這將使服務對象和數據訪問對象更容易忽略動態數據源的任何概念存在。

通常,您需要實施servlet過濾器並使用ThreadLocal,以便AbstractRoutingDataSource使用的DataSourceLookup實現可以輕鬆訪問指定返回哪個DataSource的請求參數。如果你真的想避免這種情況,你可以實現一個servlet過濾器,它在請求範圍的bean上設置屬性,並將該bean注入到你所寫的DataSourceLookup實現中。請求範圍的bean在其實現中仍然使用ThreadLocal,但至少這是Spring的impl,不是你的,你不需要擔心。 :)

類似的方法,詳見從Spring團隊這個博客條目:

http://blog.springsource.com/2007/01/23/dynamic-datasource-routing/

2

我已經這樣做。您需要爲每個類創建一個DAO,並且在您的DAO範圍內,您需要傳遞DATASOURCE,最後再傳遞一個類CONTROLLER,您可以在其中動態調用DAO。