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

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

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

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