由JDBC淺談JNDI及其在WebSphere中的配置和企業級應用中DB Session在Spring下的管理
在J2EE規範中對JDBC和JNDI進行了充分說明。本文展現了兩者間的一點聯絡,概要陳述下在WebSphere中如何配置JNDI資料來源以及在應用中使用JNDI資料來源,同時結合Spring簡述應用中DB Session的管理。
JDBC說明及舉例
JDBC API為訪問不同的資料庫提供了一種統一的途徑,象ODBC一樣,JDBC對開發者遮蔽了一些細節問題,另外,JDBC對資料庫的訪問也具有平臺無關性。
訪問DB最主要的是獲取與DB溝通的橋樑:java.sql.Connection。有了它我們可以開啟事務、提交事務、回滾事務,結合java.sql.PreparedStatement可以進行對DB資料進行增刪改查(
import java.sql.Connection;
import java.sql.DriverManager;
public static Connection getConn() {
Connection conn = null;
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
String url = "jdbc\:oracle\:thin\:@10.13.193.103\:1521\:test";
String username = "filenet";
String password = "filenet";
conn = DriverManager.getConnection(url, username, password);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
return conn;
}
JNDI說明
JNDI(Java Naming and Directory Interface)是命名和目錄介面,藉助JNDI我們能夠通過名稱來訪問物件(各類資源:元件、服務等)。下圖展現了JNDI及應用的架構概況。
通過上圖可以發現JNDI可以訪問的目錄和服務有很多,包括: LDAP、DNS、NIS、NDS、RMI、CORBA物件服務、XNam 、Novell、檔案系統、Windows XP/2000/NT/Me/9x的登錄檔、DSML v1&v2等等。同時上圖為我們展現了兩組API:JNDI API和JNDI SPI,下文對 JNDI庫的簡析可以幫助我們瞭解他們的作用。
1)Javax.naming:包含了訪問命名服務的類和介面。例如,它定義了Context介面,這是命名服務執行查詢的入口。
2)Javax.naming.directory:對命名包的擴充,提供了訪問目錄服務的類和介面。例如,它為屬性增加了新的類,提供了表示目錄上下文的DirContext介面,定義了檢查和更新目錄物件的屬性的方法。
3)Javax.naming.event:提供了對訪問命名和目錄服務時的事件通知的支援。例如,定義了NamingEvent類,這個類用來表示命名/目錄服務產生的事件,定義了偵聽NamingEvents的NamingListener介面。
4)Javax.naming.ldap:這個包提供了對LDAP 版本3擴充的操作和控制的支援,通用包javax.naming.directory沒有包含這些操作和控制。
5)Javax.naming.spi:這個包提供了一個方法,通過javax.naming和有關包動態增加對訪問命名和目錄服務的支援。這個包是為有興趣建立服務提供者的開發者提供的。
通過上面的講解,通常在應用中使用JNDI訪問網路服務時不會使用到Javax.naming.spi。如果我們想開發JNDI,則會用到此庫。
為何使用JNDI
上文中使用JDBC獲取Connection的過程包含在應用程式中,而其中包含DB的相關配置(url、使用者名稱、密碼、連線池引數等),即便這些配置在應用中能以配置檔案的形式存在,然而其仍舊需要跟隨應用來進行管理,使用JNDI則可以規避這些問題。
要注意區分JNDI與JDBC,不要將JNDI和JDBC混為一談。由於通過JNDI能夠訪問到網路中的服務和元件,而JDBC也可作為元件或服務放到網路上而不必與應用保持物理上的關聯性。從而對資料庫連線的管理便可轉移到J2EE規範下的WEB容器中了。這一點較上文中的原因更為重要,上段中所提及的往往在JPA(如Hibernate)等規範下是可以有效避免的,此點更為凸顯了使用JNDI來獲取訪問DB資料來源優點。
應用JNDI資料來源獲取Connection舉例以及在WebSphere中的配置
上文中已提到Connection在java操作DB的作用,可以說這是入口,JNDI中提供了相應標準來獲取Connection,其過程如下所示:
import java.sql.Connection;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource;
public static Connection getConn() {
Connection conn = null;
try {
Context ctx = new InitialContext();
//通過JNDI查詢DataSource,獲取Connection
DataSource ds = (DataSource)ctx.lookup("java:comp/env/jdbc/test");
conn = ds.getConnection();
}catch(Exception e) {
e.printStackTrace();
}
return conn;
}
在應用中上述程式碼前,WEB容器中必須要存在Context要查詢的資料來源名稱。在WebSphere中配置JNDI資料來源,大致可分為以下幾步:
2)設定JDBC提供程式(資源->JDBC-> JDBC提供程式->新建)
3)建立JNDI資料來源(資源->JDBC->Data Source->新建)
上面介紹了JNDI和JDBC的簡單使用,同時獲取了操作DB最關鍵的類,而在企業級應用中,DB session是需要統一管理的,開發人員只需要關係業務而不需要額外的事情,本文著重講JNDB和JDBC的簡單使用,其涉及到對DB的操作,故而此處結合Spring簡述DB Session的統一管理。
Spring配置DB Session簡要說明
在講配置前,我們心裡應該很清楚,無論是用什麼DB框架,都有如下規律,即:
1)對資料庫操作之前都要獲取連線資料庫的相關配置,繼而能夠獲取訪問DB的Session,進行增刪改查,
2)進行上述DB操作時,要加以事務的控制,保證操作的粒子性。
有了上述思路後,剩下的就是如何利用框架了。此處僅就獲取DB Session過程簡要陳述以對比使用JDBC和JNDI的配置。Spring具有工廠的作用能夠建立和注入其核心檔案applicationContext.xml中配置的Bean。利用這一特性,Spring可以經過以下幾步獲取DB Session:
1)獲取DB相關配置引數(DB url、userName、Password等)
2)獲取資料來源
3)建立sessionFactory(應用藉此獲取DB Session)注入資料來源,配置資料庫的相關引數
4)建立事務管理器transactionManager,注入sessionFactory
5)配置事務傳播特性等
前三點在本文會有所體現,而4)和5)則不會影響JDBC和JNDI的選取。如果Spring整合的是Hibernate,則上述各Bean的建立會涉及到Spring實現的Hibernate類,此外我們還會利用Spring建立一些應用上的業務Bean等,例如建立dao層內容時,則會將上文中的SessionFactory注入dao中,以獲取操作DB 的核心類(Session,注意區分上文中談及的獲取Connection類,上文是純採用JDBC,此處則是藉助了Hibernate)。
單就前三點的建立過程,Spring可使用註解形式和非註解形式來完成相同的工作。但這並不影響本文所講內容。實際上使用JDBC和使用JNDI的區別(僅就應用於DB產品上而言),其關鍵點在上文的第二點獲取資料來源上。兩者在Spring核心配置檔案applicationContext.xml中的配置如下程式碼所示:
<!-- 資料來源配置 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<!-- 設定JDBC驅動名稱 -->
<property name="driverClassName" value="${jdbc.driver}" />
<!-- 設定JDBC連線URL -->
<property name="url" value="${jdbc.url}" />
<!-- 設定資料庫使用者名稱 -->
<property name="username" value="${jdbc.username}" />
<!-- 設定資料庫密碼 -->
<property name="password" value="${jdbc.password}" />
<!-- 設定連線池初始值 -->
<property name="initialSize" value="1" />
<!-- 設定連線池最大值 -->
<property name="maxActive" value="100" />
<!-- 設定連線池最小空閒值 -->
<property name="minIdle" value="20" />
<!-- 設定連線池最大空閒值 -->
<property name="maxIdle" value="50" />
</bean>
<!-- JNDI資料來源 -->
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName">
<value>java:comp/env/jdbc/testDS</value>
</property>
</bean>
在使用中上述配置擇一而用即可,而JNDI資料來源的配置在上文中已簡做陳述。
本文淺顯講解了下J2EE中JDBC和JNDI的簡單使用及相關配置。兼顧了最基礎和更為企業級的DB操作方法,結合Spring等框架明確了DB操作統一性管理的幾個要點以及使用J2EE web容器實現下的JNDI資料來源的相關配置。文章牽涉內容較為基礎,每一方面仍舊有很多可深究的內容,後續實踐逐漸領悟陳述。