關於Tomcat與MySQL連接池問題的詳解(原創)
研究了一天,終於有所收穫,希望對大家有所幫助。首先請大家注意:這裡尤其討論Tomcat5.5版本中遇到的問題,為什麼尤其單對這個版本,我一會兒便加以說明。
問題一:Cannot create JDBC driver of class '' for connect URL 'null'
答:
[原因分析]
很多朋友在配置好$Tomcat/conf/server.xml、$Tomcat/conf/context.xml、甚至WEB-INF/web.xml後發現呼叫連線池便會出現以上錯誤。分析錯誤原因,一般是因為大家沒有邦定資料來源(實際錯誤原因是因為driverClassName、url的設定為空,但大家肯定不會忘記設定這個地方,所以肯定是大家設定完了沒有進行連線!)。通常大家配置資料來源有兩種方式(在$Tomcat/conf/context.xml的設定方法就不單算了),一種是在$Tomcat/conf/server.xml的</GlobalNamingResources>前加入如下程式碼:
設定方法一:
<Resource
name="jdbc/test" //資料來源名稱
type="javax.sql.DataSource"
driverClassName="com.mysql.jdbc.Driver" //這就是我剛剛提到的driverClassName的設置
password="admin" //資料庫密碼
maxIdle="2"
maxWait="5000"
username="root" //資料庫使用者名
url="jdbc:mysql://localhost:3306/test?autoReconnect=true" //資料庫URL,就是剛才提到的url
maxActive="4"/>
除了有註解的地方外,都是設定連接數目、閒置狀況和活動狀況的參數,如果你只是做學習試驗,可以不必更改。這種方法配製後的效果等同於在Tomcat圖形介面中配置操作。
另一種發法是在$Tomcat/conf/server.xml的<Context ...></Context>中加入以下程式碼:
設定方法二:
<Resource name="jdbc/test" auth="Container" type="javax.sql.DataSource"/>
<ResourceParams name="jdbc/test">
<parameter>
<name>factory</name>
<value>org.apache.commons.dbcp.BasicDataSourceFactory</value>
</parameter>
<parameter>
<name>username</name>
<value>root</value>
</parameter>
<parameter>
<name>password</name>
<value>admin</value>
</parameter>
<parameter>
<name>driverClassName</name>
<value>com.mysql.jdbc.Driver</value>
</parameter>
<parameter>
<name>url</name>
<value>jdbc:mysql://localhost:3306/test?autoReconnect=true</value>
</parameter>
<parameter>
<name>initialSize</name>
<value>20</value>
</parameter>
<parameter>
<name>maxActive</name>
<value>30</value>
</parameter>
<parameter>
<name>maxWait</name>
<value>10000</value>
</parameter>
</ResourceParams>
這樣設定的通常目的是想讓資料來源在一個單獨的映射目錄中實現,也就是通常這段程式碼出現在<Context docBase="具體目錄(如D:webappsmyjsp)" path= "訪問名稱(如/myjsp)" reloadable="true"></Context>,這樣就可以透過訪問http://localhost:8080/myjsp/XXX.jsp來存取D:webappsmyjsp中的某個jsp頁面進而調取資料來源或進行其它操作調取資料來源。
問題是,無論哪種方法,大家都沒有進行連接!如果不進行ResourceLink,也免或bean等找不到你設定的程式碼,又怎麼找到driverClassName和url呢?實際上任何一個參數設定都不會被找到的!
[解決方法]
知道了原因,解決也就方便了。無論你是使用哪一種方法。
解決方法一:
如果想在某個映射目錄內實作ResourceLink,就在<Context ...></Context>中間加入<ResourceLink global="資料來源名稱" name="映射後的名稱" type="javax.sql.DataSource "/>,注意如果你不了解程式碼關聯關係,一定緊緊貼在<Context ...>後寫就好。
解決方法二:
如果想變成全域性的,在所有映射目錄中都可以使用,就乾脆寫在$Tomcat/conf/context.xml中,萬事OK了。
一般大家會把「資料來源名稱」和「映射後的名稱」設定成同一個,例如我是這樣設定的<ResourceLink global="jdbc/test" name="jdbc/test" type="javax.sql.DataSource "/>。
另外必須說明,在Tomcat5.5中,如果你像上面第二種設定方法,即使加上ResourceLink,也會遇到無法正常運作的問題。
問題二:javax.naming.NameNotFoundException: Name XXX is not bound in this Context
答:
[原因分析]
Tomcat5.5中,在<Context ...><Context>中設定資料來源不能正常運行,我看過一位外國人寫的帖子,我英文程度不高,不過剛好能看懂。他說這是因為比較高的版本中(應該是說Tomcat和dbcp),factory的值由org.apache.commons.dbcp.BasicDataSourceFactory改為了org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory。但是我進行過嘗試,並不能解決問題。而且我發現Tomcat5.5標準版自備dbcp,就在$Tomcatcommonlib中。我看過另一個網友的解說,他說用第二種設定方法是不行的。這說明第二種設定方法只適用以前版本,現在的版本我不知道要在哪部分做更改,但錯誤原因是想一起那麼設置,伺服器找不到「資料來源名稱」對應的資料來源。
[解決方法]
知道原因就可以解決了,看來只有把資料來源聲明在<GlobalNamingResources>中才能運作。所以大家就按照第一種設定方法設定Tomcat5.5(這就是我為什麼尤其講Tomcat5.5)就可以了。
問題三:Cannot load JDBC driver class 'com.mysql.jdbc.Driver'
答:
[原因分析]
不光對於mysql,對於別的資料庫,只要找不到,就會拋出這個錯誤"Cannot load JDBC driver class",那麼為什麼找不到資料庫驅動類別呢?如何才能找到呢?其實很簡單。
[解決方法]
只要把jdbc拷貝到$Tomcatcommonlib中就可以了。
問題四:Cannot get a connection, pool exhausted
[原因分析]
很簡單,不能建立連接,連接池溢出,這表示你的連接資源都浪費了,原因是你沒有及時回收它們。
[解決方法]
及時正確使用close()方法釋放ResultSet、Statement、Connection,具體語句我就不說了,推薦在finally中寫。
總結:所以,如果你想用Tomcat5.5建立一個資料來源連接池,只要三步驟。
第一:設定資料來源,推薦用圖形操作介面,如果手動就在$Tomcat/conf/server.xml中</GlobalNamingResources>前面加入以下程式碼:
<Resource
name="jdbc/test" //資料來源名稱
type="javax.sql.DataSource"
driverClassName="com.mysql.jdbc.Driver" //這就是我剛剛提到的driverClassName的設置
password="admin" //資料庫密碼
maxIdle="2"
maxWait="5000"
username="root" //資料庫使用者名
url="jdbc:mysql://localhost:3306/test?autoReconnect=true" //資料庫URL,就是剛才提到的url
maxActive="4"/>
註解參數記得改成自己的。
第二:設定Resource連線。推薦在$Tomcat/conf/context.xml中寫入<ResourceLink global="資料來源名稱" name="映射後的名稱" type="javax.sql.DataSource"/>,如果想就在某個單獨映射目錄實現,就在$Tomcat/conf/server.xml中需要映射的目錄中的<Context ...>後寫入。
第三:將JDBC拷貝到$Tomcatcommonlib中
另外,我在這裡不詳細說明如何呼叫資料來源,這個問題比較簡單,但要注意,DataSource ds=(DataSource)envCtx.lookup("引用資料來源");語句中"引用資料來源"隻的是"映射後的名稱",不是"資料來源名稱",所以我建議大家方便起見把兩個名字設為同一個。而且特別要注意及時釋放閒置資源,不然連線池就會溢出!
以上是我今天研究的一些成果,我還是個初學者,希望這篇文章對大家有幫助。有問題可以聯絡我,我的信箱是:[email protected](愛看霓虹燈的人)。本文為neonlight.bokee.com(CSDN_MathMagician)原創,不可轉載! 2006年08月11日
http://blog.csdn.net/mathmagician/archive/2007/03/01/1518689.aspx