JSP +Tomcat 數(shù)據(jù)庫(kù)訪問(wèn)
作者:劉志遠(yuǎn)
?
在一般的 Web 項(xiàng)目開(kāi)發(fā)中,對(duì)數(shù)據(jù)庫(kù)的訪問(wèn)是必不可少的,本文主要介紹兩種在使用 Tomcat 作為 Web 服務(wù)的 JSP 開(kāi)發(fā)中訪問(wèn)數(shù)據(jù)庫(kù)的方法,希望能對(duì)剛接觸 JSP 開(kāi)發(fā)的朋友有所幫助。 用過(guò) .NET 平臺(tái)的朋友應(yīng)該知道,項(xiàng)目中需要訪問(wèn)數(shù)據(jù)庫(kù)時(shí),直接導(dǎo)入相應(yīng)的數(shù)據(jù)庫(kù)命名空間,寫(xiě)個(gè)數(shù)據(jù)庫(kù)連接字符串(如數(shù)據(jù)庫(kù)名、用戶(hù)名、密碼等)后,則可以很容易的獲得數(shù)據(jù)庫(kù)連接對(duì)象。其實(shí) Java 中訪問(wèn)數(shù)據(jù)庫(kù)也差不多是那樣,但這對(duì)于剛接觸 Java 開(kāi)發(fā)環(huán)境的朋友來(lái)說(shuō)可能還是比較棘手的:不知道數(shù)據(jù)庫(kù)連接信息如何配置,到底要調(diào)用哪些對(duì)象,以及 JDBC 數(shù)據(jù)庫(kù)驅(qū)動(dòng)、 JDBC 數(shù)據(jù)源、連接池等 是些什么。本文盡量對(duì)這些基本問(wèn)題做個(gè)明了的介紹。
??????
微軟
Windows
平臺(tái)提供的統(tǒng)一數(shù)據(jù)庫(kù)訪問(wèn)方式是
ODBC
(
Open DataSource Connectivity
),也就是一些
ODBC API(應(yīng)用程序編程接口)
。訪問(wèn)數(shù)據(jù)庫(kù)時(shí),開(kāi)發(fā)者在程序中只需調(diào)用
ODBC API
,
ODBC
驅(qū)動(dòng)程序就會(huì)將請(qǐng)求轉(zhuǎn)換為特定的數(shù)據(jù)庫(kù)調(diào)用請(qǐng)求(這個(gè)過(guò)程比較復(fù)雜,但對(duì)開(kāi)發(fā)者來(lái)說(shuō)是隱藏的,不必了解這個(gè)轉(zhuǎn)換過(guò)程是怎樣的),就可方便的完成數(shù)據(jù)庫(kù)訪問(wèn)操作。
類(lèi)似
MS
的
ODBC
,
Sun
公司推出了
JDBC
(
Java Database Connectivity
),
JDBC
只是一些描述訪問(wèn)關(guān)系數(shù)據(jù)庫(kù)的標(biāo)準(zhǔn)
Java
類(lèi)庫(kù)的
API
而已,并沒(méi)有提供訪問(wèn)具體數(shù)據(jù)庫(kù)的功能,但它的這些接口卻為各數(shù)據(jù)庫(kù)廠商提供訪問(wèn)自己數(shù)據(jù)庫(kù)的驅(qū)動(dòng)的一個(gè)標(biāo)準(zhǔn),方便他們實(shí)現(xiàn)自己的
JDBC
驅(qū)動(dòng)程序類(lèi)。
JDBC
驅(qū)動(dòng)程序類(lèi)實(shí)現(xiàn)了
JDBC
中定義的各個(gè)接口,也就真正提供了訪問(wèn)數(shù)據(jù)庫(kù)的功能。
而一般情況下,我們的開(kāi)發(fā)環(huán)境
(
如
MyEclips)
并不像
.NET
開(kāi)發(fā)環(huán)境那樣自帶了這些數(shù)據(jù)庫(kù)驅(qū)動(dòng)程序類(lèi)庫(kù),所以在開(kāi)發(fā)過(guò)程中,我們往往得自己到所使用的關(guān)系數(shù)據(jù)庫(kù)廠商網(wǎng)站去下載對(duì)應(yīng)的
JDBC
驅(qū)動(dòng)類(lèi)庫(kù)
(
.jar
格式,
Oracle
的可直接在
oracle
安裝目錄的
jdbc
文件夾中的
lib
下找到),再添加到項(xiàng)目中,如放在
WEB-INF
下的
lib
文件夾中。
只
有在程序中包含了數(shù)據(jù)庫(kù)的
JDBC
驅(qū)動(dòng)類(lèi)庫(kù)才能實(shí)現(xiàn)數(shù)據(jù)庫(kù)的訪問(wèn),這一步是非常關(guān)鍵的。
下面筆者就對(duì)幾種常見(jiàn)的數(shù)據(jù)庫(kù)的訪問(wèn)設(shè)置及相關(guān)內(nèi)容做個(gè)介紹。
???????? 首先,由于各數(shù)據(jù)庫(kù)廠商提供的 JDBC 驅(qū)動(dòng)類(lèi)庫(kù)是不一樣的,你可能很自然就想到訪問(wèn)數(shù)據(jù)時(shí)必須寫(xiě)明數(shù)據(jù)庫(kù)程序的 JDBC 驅(qū)動(dòng)類(lèi)名。再者,你的程序要訪問(wèn)的是哪個(gè)機(jī)器上的數(shù)據(jù)庫(kù),以及具體數(shù)據(jù)庫(kù)的名稱(chēng)是什么(一般一個(gè)關(guān)系數(shù)據(jù)庫(kù)軟件中可以創(chuàng)建很多數(shù)據(jù)庫(kù)),在 Java 中,我們把這幾個(gè)信息稱(chēng)為數(shù)據(jù)庫(kù)的 JDBC URL 。此外,用哪個(gè)用戶(hù)(當(dāng)然也要提供密碼)訪問(wèn)該數(shù)據(jù)庫(kù)我們也必須描述。通常,包含了 JDBC 驅(qū)動(dòng)類(lèi)庫(kù),再提供上面的信息就可以很容易的訪問(wèn)數(shù)據(jù)庫(kù)了。
常見(jiàn)數(shù)據(jù)庫(kù)的
JDBC
驅(qū)動(dòng)類(lèi)名如下:
數(shù)據(jù)庫(kù)
|
數(shù)據(jù)庫(kù)
JDBC
驅(qū)動(dòng)類(lèi)名
|
Oracle
|
oracle.jdbc.driver.OracleDriver
|
SQL Server 2000
|
com.microsoft.jdbc.sqlserver.SQLServerDriver
|
SQL Server 2005
|
com.microsoft.sqlserver.jdbc.SQLServerDriver
|
MySQL
|
com.mysql.jdbc.Driver
|
常見(jiàn)數(shù)據(jù)庫(kù)
JDBC URL
的形式如下:
數(shù)據(jù)庫(kù)
|
JDBC URL
|
Oracle
|
jdbc:oracle:thin:@localhost:1521:oracle9i
注
:
localhost
:機(jī)器名,也可以是
IP
;
?
oracle9i
:要訪問(wèn)的數(shù)據(jù)庫(kù)名
|
SQL Server 2000/2005
|
jdbc:microsoft:sqlserver://localhost:1433;databasename=dbname
|
MySQL
|
jdbc:mysql://localhost:3306/databasename
|
????????
做好上面的準(zhǔn)備后,用幾行代碼就可以訪問(wèn)數(shù)據(jù)庫(kù)了。訪問(wèn)數(shù)據(jù)庫(kù)的方式又分兩種:直接訪問(wèn)和通過(guò)數(shù)據(jù)源連接池訪問(wèn)。下面以訪問(wèn)
Oracle
數(shù)據(jù)庫(kù)為例進(jìn)行介紹,其他數(shù)據(jù)庫(kù)都類(lèi)似。
方法一 直接訪問(wèn)
????????
訪問(wèn)代碼如下:
????????
String driverClass =
"oracle.jdbc.driver.OracleDriver"
;
??????
????????
String url =
"jdbc:oracle:thin:@localhost:1521:oracle9i"
;
????????
String username =
"cotte"
;
????????
String password =
"tiger"
;
????????
Class.
forName
(driverClass);
????????
Connection conn = DriverManager.
getConnection
(url, username, password);
????????
Statement stmt = conn.createStatement();
???????? ResultSet rs = stmt.executeQuery( "select * from jobs" );
????????
從代碼中可以看出,
JDBC
訪問(wèn)數(shù)據(jù)庫(kù)是比較簡(jiǎn)單的,且步驟統(tǒng)一:先調(diào)用
Class
類(lèi)的
forName()
方法指定數(shù)據(jù)庫(kù)驅(qū)動(dòng)類(lèi)型,再調(diào)用
DriverManager
類(lèi)的
getConnection()
方法獲得數(shù)據(jù)庫(kù)連接對(duì)象,接著調(diào)用
Connection
對(duì)象的
createStatement()
方法獲得
Statement
類(lèi),通過(guò)調(diào)用
Statement
類(lèi)的各種訪問(wèn)數(shù)據(jù)的方法就可以訪問(wèn)、操作數(shù)據(jù)庫(kù)了。這里的
ResultSet
對(duì)象包含了從數(shù)據(jù)庫(kù)中查詢(xún)到數(shù)據(jù)。

?
?
?
方法二 使用 JDBC 數(shù)據(jù)源和連接池訪問(wèn)數(shù)據(jù)庫(kù)
???????? 方法一使用的方法還是比較方便的,但用戶(hù)每次訪問(wèn)數(shù)據(jù)庫(kù)時(shí)都必須創(chuàng)建一個(gè)數(shù)據(jù)庫(kù)連接對(duì)象,這個(gè)過(guò)程是要耗費(fèi)服務(wù)器資源和消耗一定的時(shí)間的,且一個(gè)數(shù)據(jù)庫(kù)服務(wù)器同時(shí)建立的連接數(shù)目也是有限的。用戶(hù)少時(shí)不會(huì)有多大影響,但如果訪問(wèn)數(shù)據(jù)庫(kù)的用戶(hù)數(shù)量較大時(shí)這就會(huì)成為影響系統(tǒng)性能的一個(gè)瓶頸,為解決這個(gè)問(wèn)題,聰明的程序員們想出了 “JDBC 數(shù)據(jù)源和連接池 ” 方法,從而較好的處理了這個(gè)問(wèn)題,在大型網(wǎng)站開(kāi)發(fā)中往往采用這種方法。
????????
普通數(shù)據(jù)庫(kù)訪問(wèn)中,客戶(hù)程序得到的是物理連接對(duì)象,使用完后調(diào)用連接對(duì)象的
close()
方法關(guān)閉連接。而連接池技術(shù)則是在一個(gè)連接池中先創(chuàng)建多個(gè)數(shù)據(jù)庫(kù)物理連接,通過(guò)數(shù)據(jù)源來(lái)調(diào)用連接池中的數(shù)據(jù)庫(kù)連接。用戶(hù)用完數(shù)據(jù)庫(kù)連接完后并不會(huì)直接關(guān)閉連接對(duì)象的物理連接,而只是將其釋放回連接池,供下個(gè)用戶(hù)使用,這樣就就節(jié)省了創(chuàng)建連接的時(shí)間。

?
???????? Tomcat 提供了數(shù)據(jù)源和連接池的實(shí)現(xiàn),我們直接使用就行了。在使用的時(shí)候還要明白這個(gè)原理: 由于是使用 Tomcat 提供的數(shù)據(jù)源實(shí)現(xiàn)來(lái)訪問(wèn)數(shù)據(jù)庫(kù)(注意:數(shù)據(jù)源本身并不提供具體的數(shù)據(jù)庫(kù)訪問(wèn)功能,只是作為連接對(duì)象的工廠,實(shí)際的數(shù)據(jù)訪問(wèn)操作仍然是由對(duì)應(yīng)數(shù)據(jù)庫(kù)的 JDBC 驅(qū)動(dòng)來(lái)完成), 這里是 Tomcat 需要 JDBC 驅(qū)動(dòng),而不再是應(yīng)用程序需要 JDBC 驅(qū)動(dòng),所以得先將對(duì)應(yīng)數(shù)據(jù)庫(kù)的 JDBC 驅(qū)動(dòng)類(lèi)庫(kù)( .jar 格式)拷貝到 Tomcat 目錄中的 lib 文件夾下,供 Tomcat 調(diào)用。
???????? 由于是 Tomcat 來(lái)訪問(wèn)數(shù)據(jù)庫(kù),所以在程序中不用寫(xiě)訪問(wèn)數(shù)據(jù)庫(kù)的信息,但得先配置(或告知) Tomcat 這些信息。
一般可以在 Tomcat 目錄下 \conf\context.xml 文件的 <Context> 元素內(nèi)添加 <Resource> 元素來(lái)配置 JDBC 數(shù)據(jù)源信息,以 Orcale 為例,其他類(lèi)似(注意一點(diǎn)的是, 在 Tomcat 下的配置信息對(duì)所有 Web 項(xiàng)目程序都有效 )。
< Resource name = "jdbc/oracleds" auth = "Container" type = "javax.sql.DataSource" maxIdle = "30" maxWait = "10000" maxActive = "10" username = "cotte" password = "tiger" driverClassName = "oracle.jdbc.OracleDriver" url = "jdbc:oracle:thin:@127.0.0.1:1521:oracle9i" />
這些屬性的含義如下:
鍵名
|
含義
|
name
|
指定資源相對(duì)于
java:comp/env
上下文的
JNDI
名。(可按需修改)
|
auth
|
指定資源的管理者。(默認(rèn)
Container
即可)
|
type
|
指定資源所屬的
Java
類(lèi)的完整限定名。(默認(rèn)即可)
|
maxIdle
|
指定連接池中保留的空閑數(shù)據(jù)庫(kù)連接的最大數(shù)目。(可按需修改)
|
maxWait
|
指定等待一個(gè)數(shù)據(jù)庫(kù)連接成為可用狀態(tài)的最大時(shí)間,單位毫秒。(可按需修改)
|
username
|
指定連接數(shù)據(jù)庫(kù)的用戶(hù)名。(按讀者的具體情況修改)
|
password
|
指定連接數(shù)據(jù)庫(kù)的密碼。(也是按讀者的具體情況修改)
|
driverClassName
|
指定
JDBC
驅(qū)動(dòng)程序類(lèi)名。(按讀者使用的數(shù)據(jù)庫(kù)程序修改,具體值可參加前面列的
“
常見(jiàn)數(shù)據(jù)庫(kù)的
JDBC
驅(qū)動(dòng)類(lèi)名
”
)
|
url
|
指定連接數(shù)據(jù)庫(kù)的
URL
。(也是按讀者使用的情況修改,具體值可參加前面列的
“
常見(jiàn)數(shù)據(jù)庫(kù)
JDBC URL
的形式
”
)
|
除了配置
Tomcat
的
context.xml
文件外,也可
在
web
項(xiàng)目的
META-INF
文件夾下新增文件
context.xml
,
其內(nèi)容和上面的基本一樣
,
如下。(因?yàn)?
Web
程序部署發(fā)布時(shí)
Tomcat
會(huì)自動(dòng)加載
WEB-INF
下的內(nèi)容
,也就可以獲得這些信息了,
所以和上面的是一樣的效果。但要明白一點(diǎn)的是:
這樣的配置就只對(duì)當(dāng)前
Web
項(xiàng)目有效,其他項(xiàng)目不能使用這些信息
)
<?
xml
version
=
'1.0'
encoding
=
'utf-8'
?>
<
Context
reloadable
=
"true"
>
<
Resource
name
=
"jdbc/oracleds"
auth
=
"Container"
type
=
"javax.sql.DataSource"
maxIdle
=
"30"
maxWait
=
"10000"
maxActive
=
"10"
username
=
"lzy"
password
=
"lzy"
driverClassName
=
"oracle.jdbc.OracleDriver"
url
=
"jdbc:oracle:thin:@127.0.0.1:1521:oracle9i"
/>
</
Context
>
做好前面的準(zhǔn)備后,下面就只需簡(jiǎn)單的幾行訪問(wèn)代碼就可以訪問(wèn)數(shù)據(jù)庫(kù)了,代碼如下:
????????
???
javax.naming.Context ctx =
new
javax.naming.InitialContext();
????????
???
javax.sql.DataSource ds = (javax.sql.DataSource)ctx.lookup(
"java:comp/env/jdbc/oracleds"
);
????????
???
java.sql.Connection conn = ds.getConnection();
?
????
????
????
????????
???
java.sql.Statement stmt=conn.createStatement();
???????? ??? java.sql.ResultSet rs = stmt.executeQuery( "select * from jobs" );
????????
其過(guò)程與前面的差不多,只是用了
Context
對(duì)象的
lookup()
方法找到
DataSource
對(duì)象,再用
DataSource
對(duì)象的
getConnection()
方法就獲得了數(shù)據(jù)庫(kù)連接對(duì)象。
?
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元
