JDBC操作的步驟:
1、 載入驅動程式
2、 串連資料庫
3、 操作資料庫
4、 關閉資料庫,釋放串連
也就是說,所有的使用者都需要經過此四步進行操作,但是這四步之中有三步對所有人都是一樣的,而所有人只有在操作上是不一樣,那麼這就造成了效能的損耗。
那麼最好的做法是,準備出一個空間,此空間裡專門儲存著全部的資料庫連接,以後使用者用資料庫操作的時候不用再重新載入驅動、串連資料庫之類的,而直接從此空間中取走串連,關閉的時候直接把串連放回到此空間之中。
那麼此空間就可以稱為串連池(儲存所有的資料庫連接),但是如果要想實現此空間的話,則必須有一個問題要考慮?
1、 如果沒有任何一個使用者使用串連,那麼那麼應該維持一定數量的串連,等待使用者使用
2、 如果串連已經滿了,則必須開啟新的串連,供更多使用者使用
3、 如果一個伺服器就只能有100個串連,那麼如果有第101個人過來呢?應該等待其他使用者釋放串連
4、 如果一個使用者等待時間太長了,則應該告訴使用者,操作是失敗的
如果直接用程式實現以上功能,則會比較麻煩,所以在Tomcat4.1.27之後,在伺服器上就直接增加了資料來源的配置選項,直接在伺服器上配置好資料來源串連池即可。
在J2EE伺服器上儲存著一個資料庫的多個串連。
每一個串連通過DataSource可以找到。
DataSource被綁定在了JNDI樹上(為每一個DataSource提供一個名字)
用戶端,通過名稱找到在JNDI樹上綁定的DataSource,再由DataSource找到一個串連。
那麼在以後的操作中,除了資料庫的串連方式不一樣之外,其他的所有操作都一樣,只是關閉的時候不是徹底地關閉資料庫,而是把資料庫的串連放回到串連池中去。
如果要想使用此配置,則必須配置虛擬目錄,因為此配置是在虛擬目錄之上起作用的。
當然,需要注意的是,如果要想完成以上的功能,在伺服器上一定要儲存好各個資料庫的驅動程式。
server.xml: <Contextpath="/dao" docBase="E:\eclipsedemo\DAOProject\WebRoot" debug="5"reloadable="true" crossContext="true"> <Resourcename="jdbc/oracle" auth="Container"type="javax.sql.DataSource" maxActive="100" maxIdle="30" maxWait="10000" username="scott" password="tiger" driverClassName="oracle.jdbc.driver.OracleDriver" url="jdbc:oracle:thin:@localhost:1521:MLDN"/> </Context>
只要在伺服器上使用以上的配置,就表示配置好串連池了,那麼在配置之中,有以下幾個主要的屬性需要注意:
•<Resource>中定義的是資源的配置使用
|-name:表示以後要尋找的名稱。通過此名稱可以找到DataSource,此名稱任意更換,但是程式中最終要尋找的就是此名稱,為了不與其他的名稱混淆,所以使用jdbc/oracle,現在配置的是一個jdbc的關於oracle的命名服務。
|-auth:由容器進行授權及管理,指的使用者名稱和密碼是否可以在容器上生效
|-type:此名稱所代表的類型,現在為javax.sql.DataSource
|-maxActive:表示一個資料庫在此伺服器上所能開啟的最大串連數
|-maxIdle:表示一個資料庫在此伺服器上維持的最小串連數
|- maxWait:最大等待時間。10000毫秒
|- username:資料庫連接的使用者名稱
|- password:資料庫連接的密碼
|-driverClassName:資料庫連接的驅動程式
|- url:資料庫連接的地址
但是,在Tomcat5.5之後的伺服器,如果要想正確的使用此資料來源串連,則必須在web.xml中進行一系列的配置。
web.xml:
<resource-ref> <description>DBConnection</description> <res-ref-name>jdbc/oracle</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> </resource-ref>
以上表示配置的資源引用:
• res-ref-name:表示引用資源的名稱
•res-type:此資源對應的類型為javax.sql.DataSource
• res-auth:容器授權管理
如果配置完資料來源串連池之後,就可以按照以下的步驟進行訪問:
• 初始化名稱尋找上下文
• 通過JNDI名稱找到DataSource
• 通過DataSource取得一個串連
• 操作資料庫
•關閉資料庫,關閉的時候是將串連放回到串連池之中。
<%@ page language="java" import="java.util.*"pageEncoding="ISO-8859-1"%><%@ pageimport="java.sql.*,javax.sql.*,javax.naming.*"%><html> <head> <title>MyJSP 'MyJsp.jsp' startingpage</title> </head> <body> <% Context ctx = newInitialContext() ; DataSource ds =(DataSource)ctx.lookup("jdbc/oracle") ; Connection conn =ds.getConnection() ; %> <%=conn%> <% conn.close() ; %> </body></html>
但是以上代碼運行時發生了以下的錯誤:
javax.servlet.ServletException: Name jdbc is not bound in thisContext
此錯誤的提示是,找不到名稱。
但是,所有的名稱都已經配置正確了,為什麼還不能訪問呢?
• 在JAVAEE中對於所有的名稱訪問前都應該設定一個環境屬性:java:comp/env/名稱,有些伺服器已經自動化佈建好了此屬性,所以直接存取名稱即可,但是Tomcat並沒有自動化佈建好,所以在訪問串連的時候,串連地址要換成:java:comp/env/jdbc/oracle
<% Context ctx = newInitialContext() ; DataSource ds =(DataSource)ctx.lookup("java:comp/env/jdbc/oracle") ; Connection conn =ds.getConnection() ; %> <%=conn%> <% conn.close() ; %>
則以後在使用DataBaseConnection的時候,就直接使用DataSource串連了。
DataBaseConnection.java:
package org.lxh.oracle.dbc;import java.sql.Connection;import java.sql.SQLException;import javax.naming.Context;import javax.naming.InitialContext;import javax.naming.NamingException;import javax.sql.DataSource;public class DataBaseConnection { private static final String JNDINAME ="java:comp/env/jdbc/oracle"; private Connection conn = null; public DataBaseConnection() { try { Context ctx =new InitialContext(); DataSource ds= (DataSource) ctx.lookup(JNDINAME); conn =ds.getConnection(); } catch (NamingException e){ e.printStackTrace(); } catch (SQLException e){ e.printStackTrace(); } } public Connection getConnection() { return this.conn; } public void close() { if (this.conn != null) { //如果不為空白,則表示資料庫已經開啟了 try { this.conn.close(); } catch(SQLException e) { //TODO Auto-generated catch block e.printStackTrace(); } } }}
總結
使用串連池可以提升資料庫的訪問效能,但是在使用資料庫連接池的時候,需要注意的是,串連池是在Tomcat上配置的,所以必須在Tomcat中才可以取得串連。