2012-06-23 43 views
0

我不想讓我的代碼與一些JDBC驅動程序緊密耦合(例如MySql)。我想製作通用代碼,可以與許多數據庫實現一起工作。在使用JDBC時,我不太明白如何實現此目標。如何實現JDBC驅動程序和源代碼之間的鬆散耦合?

我認爲實現這一目標,我只需要驅動程序類名(和連接字符串)導出到.properties文件(例如"com.mysql.jdbc.Driver"),然後在代碼中使用這樣的Class.forName(PROPERTIES.getDriverName()).newInstance();所以,當我決定改變我的數據庫,所有的我需要更改的是.properties文件中的jdbc驅動程序名稱(例如"COM.ibm.db2.jdbc.app.DB2Driver"),連接字符串以及在classpath中更改驅動程序的.jar文件。

是不是?

+1

從理論上講,這很好,但根據我的經驗(1)除極少數情況外,您確實不會更換數據庫; (2)SQL語法會使其變得困難,而不是驅動程序。 – JohnFx

+0

@JohnFx好的,謝謝,但是如果不注意sql語法的區別,那麼這個想法好?或者可能存在一些更優雅的方式來實現這一目標? – MyTitle

+0

可能會將其移至數據源? – kosa

回答

3

鬆耦合可以通過多種方式來實現 -

A.使用Hibernate的,但是這可能是你的需要矯枉過正,損害性能(如果您的應用程序主要執行寫操作)

B.使用春季 - JDBC或任何其他框架作爲JDBC包裝 - 通常它們提供某種抽象


C.如果您的代碼是Java EE代碼,您可以使用DataSources並在Java應用程序服務器上配置它們 - 您將查找數據源的名稱,並且您不知道背後的實施細節

D.您c確保您在層中構建應用程序 - 一個業務邏輯層,它使用數據訪問層,它使用一些數據引擎(確保您的數據引擎類實現一個接口,以便您可以輕鬆更改實現)。

您的數據引擎類可以從配置(XML文件的屬性)讀取有關jdbc驅動程序的信息 - 例如,這基本上是Hibernate所做的。

+1

在方法'D'中,考慮使接口符合[_strategy pattern_](http://en.wikipedia.org/wiki/Strategy_pattern)。 – trashgod

+0

@trashgod - 感謝您的評論。我完全同意你的看法 –

1

這可能對您有用,當然。我會爲未來的讀者提供更完整的問題,儘管如此:

但您寫的很多查詢可能是數據庫特定的,或者依賴某些關鍵字才能生效。以一個常見的查詢爲例。要列出所有的產品在數據庫中,但顯示用戶10在一個時間:

的MySQL:

select * from products LIMIT 0,10 

然後在接下來的10行:

select * from products LIMIT 10,10 

非常棒,所以用戶可以使用MySQL作爲數據庫。那麼如果他們使用另一個免費且非常流行的數據庫postgres呢?該查詢不起作用:

SELECT * FROM product LIMIT 10 OFFSET 10 

因此,您的代碼不像您想象的那樣便攜。

解決此問題的一種方法是爲您計劃進行的所有查詢/訪問創建您自己的接口(接口Query,接口Access),然後擁有一個查詢工廠,該工廠可基於DB方言進行實例化(MySQL,postgres等),並創建MySQLQueryImpl和PostGresQueryImpl(都實現了Query接口)。

不幸的是,您必須編寫一些數據庫調用的兩次,或者將它們自己移出到屬性文件中。您還可以設計查詢因子以從屬性文件實例化(就像您最初想要的那樣),並允許其他用戶在將來實現他們自己的查詢,以便擴展性在那裏,而且您不必親自去做。

或者...

另一種選擇,這可能是更優雅和錯誤證明(嗯......也許)是讓你別人這樣做。 Hibernate是一個非常常用的工具,可以爲您抽取數據庫讀/寫,並且可以將其配置爲使用其他數據庫,只要它具有多年的經驗和錯誤修復。它不是最容易學的東西(對於複雜的查詢和連接等),但對於基本模型和映射到數據庫,它會給你提供你想要的和更多的東西,包括能夠非常輕鬆地開啓/關閉緩存和懶惰加載數據,因此您不會帶入數千條您不會使用的記錄。您需要很長時間才能創建和加固這樣的系統。

2

你說得對。將驅動程序類名稱,數據庫URL,用戶和密碼外化,然後在此處進行。無論如何,大多數「框架」都是這樣做的:Java EE服務器允許在服務器中配置數據源,並使用JNDI訪問它。 Hibernate在其配置文件中有這樣的條目,連接池通常使用XML或屬性文件來保存它們的配置。

當然,如果您使用專有SQL代碼,您將無法輕鬆地從一個數據庫切換到另一個數據庫,但這是另一個問題。

1

外部連接字符串不能使您的應用程序處理不同的數據庫。 但是,這是你可以做的。

使用的數據源,而不是連接這爲您創建一個使用JNDI連接多種不同的方式的能力,從連接池等

更多的數據源,直出的javax.sql.DataSource的Javadoc

用於連接到此DataSource對象表示的物理數據源的工廠。對於DriverManager 工具的替代方案,DataSource對象是獲取 連接的首選方法。

定義用於訪問數據的DAO接口。使您的應用程序代碼依賴於Interface。您可以爲DAO接口提供數據庫特定的實現。數據庫更改時,爲數據庫創建新的實現。讓DAO工廠根據數據庫選擇合適的DAO實例。

類似Mybatis,Hibernate這樣的支持ORM範式的庫爲您自動執行這些步驟。