久久福利_99r_国产日韩在线视频_直接看av的网站_中文欧美日韩_久久一

您的位置:首頁技術文章
文章詳情頁

Java中幾種常用數據庫連接池的使用

瀏覽:7日期:2022-08-11 16:29:20
目錄一、應用程序直接獲取數據庫連接的缺點二、使用數據庫連接池優化程序性能2.1、數據庫連接池的基本概念2.2、編寫數據庫連接池三、開源數據庫連接池3.1、DBCP數據源3.2、在應用程序中加入dbcp連接池3.3、C3P0數據源(重點)四、Tomcat中配置數據庫源4.1、JNDI技術簡介4.2、配置Tomcat數據源 包結構:注意了:有個問題坑了我一天具體請看:tomcat虛擬路徑的配置一、應用程序直接獲取數據庫連接的缺點

用戶每次請求都需要向數據庫獲得鏈接,而數據庫創建連接通常需要消耗相對較大的資源,創建時間也較長。假設網站一天10萬訪問量,數據庫服務器就需要創建10萬次連接,極大的浪費數據庫的資源,并且極易造成數據庫服務器內存溢出、拓機。如下圖所示:

Java中幾種常用數據庫連接池的使用

二、使用數據庫連接池優化程序性能2.1、數據庫連接池的基本概念

數據庫連接是一種關鍵的有限的昂貴的資源,這一點在多用戶的網頁應用程序中體現的尤為突出.對數據庫連接的管理能顯著影響到整個應用程序的伸縮性和健壯性,影響到程序的性能指標.數據庫連接池正式針對這個問題提出來的.數據庫連接池負責分配,管理和釋放數據庫連接,它允許應用程序重復使用一個現有的數據庫連接,而不是重新建立一個。如下圖所示:

Java中幾種常用數據庫連接池的使用

數據庫連接池在初始化時將創建一定數量的數據庫連接放到連接池中, 這些數據庫連接的數量是由最小數據庫連接數來設定的.無論這些數據庫連接是否被使用,連接池都將一直保證至少擁有這么多的連接數量.連接池的最大數據庫連接數量限定了這個連接池能占有的最大連接數,當應用程序向連接池請求的連接數超過最大連接數量時,這些請求將被加入到等待隊列中.

數據庫連接池的最小連接數和最大連接數的設置要考慮到以下幾個因素:

最小連接數:是連接池一直保持的數據庫連接,所以如果應用程序對數據庫連接的使用量不大,將會有大量的數據庫連接資源被浪費. 最大連接數:是連接池能申請的最大連接數,如果數據庫連接請求超過次數,后面的數據庫連接請求將被加入到等待隊列中,這會影響以后的數據庫操作 如果最小連接數與最大連接數相差很大:那么最先連接請求將會獲利,之后超過最小連接數量的連接請求等價于建立一個新的數據庫連接.不過,這些大于最小連接數的數據庫連接在使用完不會馬上被釋放,他將被放到連接池中等待重復使用或是空間超時后被釋放.2.2、編寫數據庫連接池

編寫連接池需實現java.sql.DataSource接口。DataSource接口中定義了兩個重載的getConnection方法:

Connection getConnection() Connection getConnection(String username, String password)

實現DataSource接口,并實現連接池功能的步驟:

在DataSource構造函數中批量創建與數據庫的連接,并把創建的連接加入LinkedList對象中。 實現getConnection方法,讓getConnection方法每次調用時,從LinkedList中取一個Connection返回給用戶。 當用戶使用完Connection,調用Connection.close()方法時,Collection對象應保證將自己返回到LinkedList中,而不要把conn還給數據庫。Collection保證將自己返回到LinkedList中是此處編程的難點

數據庫連接池核心代碼

使用動態代理技術構建連接池中的connection

Java中幾種常用數據庫連接池的使用

JdbcPool.java:

大致思路:1、讀取配置文件,將屬性值取出

2、注冊jdbc驅動

3、通過數據庫連接數和驅動管理器獲得相應連接(.getConnection()),因為DataSource是接口,所以這個方法需要 我們手動實現

4、重點:實現getConnection()方法

思考:當外部有連接需求時,直接從connectList拿出一個connect,就實現了這個方法,但是我們再想想,它用完了怎么回收呢,確實,有close()方法,但是這個方法作用是將這個連接還給數據庫,而不是數據庫連接池,這樣會導致數據庫連接池中 的連接越來越少,這樣可不行,但是我們也不能影響它的正常使用吧,在這種情況下,我們想要監測這個連接對象的動態,在它調用close()方法時,我們將其再添加進connectList,這樣連接池中的連接不就沒少了嗎,在java中對于監聽一個對象的動態,最常用也最實用的便是動態代理,對于動態代理,其實我們可以把它想象成就是一個大盒子,里面裝著一個真實對象小盒子,這就在大盒子和小盒子間形成了一個橫切空隙,而真實做事的還是這個對象,代理只是個接活的,接到活就給內部的小盒子干,自然這個空隙可以用來監測真實對象的事務,也就是監聽對象的方法。具體可以看看這個,動態代理:https://www.jb51.net/article/213416.htm

package jdbcPoolTest; import java.io.IOException;import java.io.InputStream;import java.io.PrintWriter;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;import java.sql.Connection;import java.sql.DriverManager;import java.sql.SQLException;import java.sql.SQLFeatureNotSupportedException;import java.util.LinkedList;import java.util.Properties;import java.util.logging.Logger; import javax.sql.DataSource; import org.omg.PortableServer.POA; public class JdbcPool implements DataSource{private static LinkedList<Connection> listConnections = new LinkedList<>();static {//靜態代碼塊中加載db.properties配置文件InputStream in = JdbcPool.class.getClassLoader().getResourceAsStream('db.properties');Properties prop = new Properties();try {//讀取文件內容prop.load(in);String driver = prop.getProperty('driver');String url = prop.getProperty('url');String username = prop.getProperty('username');String password = prop.getProperty('password');//數據庫連接池的初始化連接大小int jdbcPoolInitSize = Integer.parseInt(prop.getProperty('jdbcPoolInitSize'));//加載數據庫驅動Class.forName(driver);for(int i=0; i<jdbcPoolInitSize; i++) {//獲取連接Connection conn = DriverManager.getConnection(url, username, password);System.out.println('獲取連接:'+conn);//將conn連接加入listConnections集合中,此時的listConnections就是一個連接池listConnections.add(conn);}} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}catch (ClassNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();}catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}} @Overridepublic Connection getConnection() throws SQLException {// TODO Auto-generated method stub//如果數據庫連接池的連接數大于0System.out.println('進來了');if (listConnections.size()>0) {//從listConnections中獲取一個連接final Connection conn = listConnections.removeFirst();System.out.println('數據庫連接池的大小為:'+listConnections.size());//返回Connection的代理,利用代理可以處理一些橫切事件System.out.println('取出的連接為:'+conn);return (Connection) Proxy.newProxyInstance(JdbcPool.class.getClassLoader(), conn.getClass().getInterfaces(), new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {// TODO Auto-generated method stub//如果不是執行關閉操作,則通過反射執行相應方法if (!method.getName().equals('close')) {return method.invoke(conn, args);}else {//否則,將conn歸還給連接池listConnections.add(conn);System.out.println('歸還連接:'+conn);System.out.println('連接池大小為:'+listConnections.size());return null;}}});}else {throw new RuntimeException('對不起,數據庫正忙');}}@Overridepublic PrintWriter getLogWriter() throws SQLException {// TODO Auto-generated method stubreturn null;} @Overridepublic int getLoginTimeout() throws SQLException {// TODO Auto-generated method stubreturn 0;} @Overridepublic Logger getParentLogger() throws SQLFeatureNotSupportedException {// TODO Auto-generated method stubreturn null;} @Overridepublic void setLogWriter(PrintWriter arg0) throws SQLException {// TODO Auto-generated method stub} @Overridepublic void setLoginTimeout(int arg0) throws SQLException {// TODO Auto-generated method stub} @Overridepublic boolean isWrapperFor(Class<?> arg0) throws SQLException {// TODO Auto-generated method stubreturn false;} @Overridepublic <T> T unwrap(Class<T> arg0) throws SQLException {// TODO Auto-generated method stubreturn null;} @Overridepublic Connection getConnection(String username, String password) throws SQLException {// TODO Auto-generated method stubreturn null;} }

寫一個JdbcUtil測試數據庫連接池

package jdbcPoolTest; import java.sql.Connection;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Statement; public class JdbcUtil { private static JdbcPool jdbcPool = new JdbcPool();public static Connection getConnection() throws SQLException {return jdbcPool.getConnection();}//釋放的資源包括Connection數據庫連接對象,負責執行SQL命令的Statement對象,存儲查詢結果的ResultSet對象public static void release(Connection conn,Statement st ,ResultSet rs) {if (conn!=null) {try {conn.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}if (st!=null) {try {st.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}if (rs!=null) {try {rs.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}rs = null;}}}

db.properties配置文件如下:

driver=com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3306/student username=root password=123456 jdbcPoolInitSize=10三、開源數據庫連接池

現在很多WEB服務器(Weblogic, WebSphere, Tomcat)都提供了DataSoruce的實現,即連接池的實現。通常我們把DataSource的實現,按其英文含義稱之為數據源,數據源中都包含了數據庫連接池的實現。也有一些開源組織提供了數據源的獨立實現:

DBCP 數據庫連接池 C3P0 數據庫連接池

在使用了數據庫連接池之后,在項目的實際開發中就不需要編寫連接數據庫的代碼了,直接從數據源獲得數據庫的連接。

3.1、DBCP數據源

DBCP 是 Apache 軟件基金組織下的開源連接池實現,要使用DBCP數據源,需要應用程序應在系統中增加如下兩個 jar 文件:

Commons-dbcp.jar:連接池的實現 Commons-pool.jar:連接池實現的依賴庫

Tomcat 的連接池正是采用該連接池來實現的。該數據庫連接池既可以與應用服務器整合使用,也可由應用程序獨立使用。

3.2、在應用程序中加入dbcp連接池

1.導入相關jar包 commons-dbcp-1.2.2.jar、commons-pool.jar、common-logging.jar三個包2、在類目錄下加入dbcp的配置文件:dbcpconfig.properties

用了官方的連接池,自然配置文件內容也就多了

dbcpconfig.properties的配置信息如下:

注意這段:

#driver default 指定由連接池所創建的連接的只讀(read-only)狀態。 #如果沒有設置該值,則“setReadOnly”方法將不被調用。(某些驅動并不支持只讀模式,如:Informix) defaultReadOnly=

如果設置為ture,那就只能進行查詢操作

#連接設置 報錯com.mysql.jdbc.Connection.isValid(I)Z,更新mysql包driverClassName=com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3306/student username=root password=123456 #初始化連接池大小 jdbcPoolInitSize=10 #最大連接數量 maxActive=50 #<!-- 最大空閑連接 --> maxIdle=20 #<!-- 最小空閑連接 --> minIdle=5 #<!-- 超時等待時間以毫秒為單位 6000毫秒/1000等于60秒 --> maxWait=60000 #JDBC驅動建立連接時附帶的連接屬性的格式必須為這樣:[屬性名=property;] #注意:'user' 與 'password' 兩個屬性會被明確地傳遞,因此這里不需要包含他們。 connectionProperties=useUnicode=true;characterEncoding=UTF8 #指定由連接池所創建的連接的自動提交(auto-commit)狀態。 defaultAutoCommit=true #driver default 指定由連接池所創建的連接的只讀(read-only)狀態。 #如果沒有設置該值,則“setReadOnly”方法將不被調用。(某些驅動并不支持只讀模式,如:Informix) defaultReadOnly= #driver default 指定由連接池所創建的連接的事務級別(TransactionIsolation)。 #可用值為下列之一:(詳情可見javadoc。)NONE,READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE defaultTransactionIsolation=READ_UNCOMMITTED

包結構:

Java中幾種常用數據庫連接池的使用

jdbcUtils_DBCP:

大致思路:

1、從配置文件中獲取輸入流,進行加載

2、有了BasicDataSoureFactory,那我們也不需要將配置文件中的屬性值一個一個讀取出來了,它有個方法createDataSource()能自動獲取到數據源

3、接下來只需要拿著這個數據源對象ds去獲取連接了,具體如何連接,就不需要我們關心,大致思路與我們自行編寫連接池類似,只不過多了些其他屬性的出來方法。從而簡化了我們的開發

package zdb.jdbc.util; import java.io.IOException;import java.io.InputStream;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Statement;import java.util.Properties; import javax.sql.DataSource; import org.apache.commons.dbcp2.BasicDataSourceFactory; public class jdbcUtils_DBCP { /** * 在java中,編寫數據庫連接池需實現java.sql.DataSource接口,每一種數據庫連接池都是DataSource接口的實現 * DBCP連接池就是java.sql.DataSource接口的一個具體實現 */private static DataSource ds = null;static {InputStream in = jdbcUtils_DBCP.class.getClassLoader().getResourceAsStream('dbcpconfig.properties');Properties prop = new Properties();try {prop.load(in);//創建數據源ds = BasicDataSourceFactory.createDataSource(prop); } catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}public static Connection getConnection() throws SQLException{return ds.getConnection();}//釋放的資源包括Connection數據庫連接對象,負責執行SQL命令的Statement對象,存儲查詢結果的ResultSet對象public static void release(Connection conn,PreparedStatement ps ,ResultSet rs) {if (conn!=null) {try {conn.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}if (ps!=null) {try {ps.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}if (rs!=null) {try {rs.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}rs = null;}}}

接下來我們通過在表中插入屬性值來測試--DataSourceTest:

注意這段:

//由于包版本問題:必須加上PreparedStatement.RETURN_GENERATED_KEYS,不然將會報主鍵錯誤 ps = conn.prepareStatement(sql,PreparedStatement.RETURN_GENERATED_KEYS);

package zdb.jdbc.util; import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException; import javafx.css.PseudoClass; public class DataSourceTest { public static void jdbcDataSource() {PreparedStatement ps = null;ResultSet rs = null;Connection conn = null;try {//conn = jdbcUtils_DBCP.getConnection();conn = jdbcUtils_DBCP.getConnection();String sql = 'insert into user(uname) values(?)';//由于版本兼容問題:必須加上PreparedStatement.RETURN_GENERATED_KEYSps = conn.prepareStatement(sql,PreparedStatement.RETURN_GENERATED_KEYS);ps.setString(1, 'lonewolf');ps.executeUpdate();//獲得主鍵rs = ps.getGeneratedKeys();if (rs.next()) {System.out.println(rs.getInt(1));}} catch (SQLException e) {// TODO Auto-generated catch blockrse.printStackTrace();}finally {jdbcUtils_DBCP.release(conn, ps, rs);//jdbcUtils_C3P0.release(conn, ps, rs);}} public static void main(String[] args) {new DataSourceTest().jdbcDataSource();}}3.3、C3P0數據源(重點)

C3P0是一個開源的JDBC連接池,它實現了數據源和JNDI綁定,支持JDBC3規范和JDBC2的標準擴展。目前使用它的開源項目有Hibernate,Spring等。C3P0數據源在項目開發中使用得比較多。

c3p0與dbcp區別

dbcp默認不自動回收空閑連接,需要手動開啟c3p0默認自動回收空閑連接功能3.4、在應用程序中加入C3P0連接池

1.導入相關jar包  c3p0-0.9.5.2.jar、mchange-commons-java-0.2.12jar,如果操作的是Oracle數據庫,那么還需要導入c3p0-oracle-thin-extras-0.9.2-pre1.jar

注意:導入包時,兩個包的版本也是需要匹配的

不然會報錯:Exception in thread 'main' java.lang.NoClassDefFoundError: com/mchange/v2/ser/Indirector

但是這兩個包版本是匹配的,下載鏈接c3p0_jar_jb51.rar

2、包結構:

Java中幾種常用數據庫連接池的使用

3、在類目錄下加入C3P0的配置文件:c3p0-config.xml,即在項目根目錄下讀取文件

c3p0-config.xml的配置信息如下:

注意:配置文件中有兩種內容相似的配置,一種缺省配置,意思是在沒有指定配置文件名時,調用該配置,一種命名配置,也就是在使用配置文件時,加上配置名即可引用,如接下來會說的:new ComboPooledDataSource('MySQL');

<c3p0-config> <!-- C3P0的缺省(默認)配置, 如果在代碼中“ComboPooledDataSource ds = new ComboPooledDataSource();”這樣寫就表示使用的是C3P0的缺省(默認)配置信息來創建數據源 --> <default-config> <property name='driverClass'>com.mysql.jdbc.Driver</property> <property name='jdbcUrl'>jdbc:mysql://localhost:3306/student</property> <property name='user'>root</property> <property name='password'>123456</property> <property name='acquireIncrement'>5</property> <property name='initialPoolSize'>10</property> <property name='minPoolSize'>5</property> <property name='maxPoolSize'>20</property> </default-config> <!-- C3P0的命名配置, 如果在代碼中“ComboPooledDataSource ds = new ComboPooledDataSource('MySQL');”這樣寫就表示使用的是name是MySQL的配置信息來創建數據源 --> <named-config name='MySQL'> <property name='driverClass'>com.mysql.jdbc.Driver</property> <property name='jdbcUrl'>jdbc:mysql://localhost:3306/student</property> <property name='user'>root</property> <property name='password'>123456</property> <property name='acquireIncrement'>5</property> <property name='initialPoolSize'>10</property> <property name='minPoolSize'>5</property> <property name='maxPoolSize'>20</property> </named-config> </c3p0-config>

jdbcUtils_C3P0:

大致思路:

我們可以通過代碼看到,c3p0將我們的代碼量又縮減了許多

ComboPooledDataSource ds = new ComboPooledDataSource('MySQL');我們直接new一個ComboPooledDataSource()對象就可以獲得數據源,所以這就是為什么之前需要將xml配置文件放在根目錄下,“MySQL”就是我們的配置的名字

package zdb.jdbc.util; import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException; import com.mchange.v2.c3p0.ComboPooledDataSource; public class jdbcUtils_C3P0 {private static ComboPooledDataSource ds = null;static {ds = new ComboPooledDataSource('MySQL');}public static Connection getConnection() throws SQLException{ //從數據源中獲取數據庫連接 return ds.getConnection();}//釋放的資源包括Connection數據庫連接對象,負責執行SQL命令的Statement對象,存儲查詢結果的ResultSet對象public static void release(Connection conn,PreparedStatement ps ,ResultSet rs) {if (conn!=null) {try {conn.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}if (ps!=null) {try {ps.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}if (rs!=null) {try {rs.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}rs = null;}} }

測試C3P0數據源-DataSourceTest

package zdb.jdbc.util; import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException; import javafx.css.PseudoClass; public class DataSourceTest { public static void jdbcDataSource() {PreparedStatement ps = null;ResultSet rs = null;Connection conn = null;try {//conn = jdbcUtils_DBCP.getConnection();conn = jdbcUtils_C3P0.getConnection();String sql = 'insert into user(uname) values(?)';//由于版本兼容問題:必須加上PreparedStatement.RETURN_GENERATED_KEYSps = conn.prepareStatement(sql,PreparedStatement.RETURN_GENERATED_KEYS);ps.setString(1, 'lonewolf');ps.executeUpdate();//獲得主鍵rs = ps.getGeneratedKeys();if (rs.next()) {System.out.println(rs.getInt(1));}} catch (SQLException e) {// TODO Auto-generated catch blockrse.printStackTrace();}finally {jdbcUtils_DBCP.release(conn, ps, rs);//jdbcUtils_C3P0.release(conn, ps, rs);}} public static void main(String[] args) {new DataSourceTest().jdbcDataSource();}}

這些便是數據庫連接池的大致內容。

接下來說說

四、Tomcat中配置數據庫源

在實際開發中,我們有時候還會使用服務器提供給我們的數據庫連接池,比如我們希望Tomcat服務器在啟動的時候可以幫我們創建一個數據庫連接池,那么我們在應用程序中就不需要手動去創建數據庫連接池,直接使用Tomcat服務器創建好的數據庫連接池即可。要想讓Tomcat服務器在啟動的時候幫我們創建一個數據庫連接池,那么需要簡單配置一下Tomcat服務器。

4.1、JNDI技術簡介

JNDI(Java Naming and Directory Interface),Java命名和目錄接口,它對應于J2SE中的javax.naming包,這 套API的主要作用在于:它可以把Java對象放在一個容器中(JNDI容器),并為容器中的java對象取一個名稱,以后程序想獲得Java對象,只需 通過名稱檢索即可。其核心API為Context,它代表JNDI容器,其lookup方法為檢索容器中對應名稱的對象。

Tomcat服務器創建的數據源是以JNDI資源的形式發布的,所以說在Tomat服務器中配置一個數據源實際上就是在配置一個JNDI資源

服務器創建好數據源之后,我們的應用程序又該怎么樣得到這個數據源呢,Tomcat服務器創建好數據源之后是以JNDI的形式綁定到一個JNDI容器中的,我們可以把JNDI想象成一個大大的容器,我們可以往這個容器中存放一些對象,一些資源,JNDI容器中存放的對象和資源都會有一個獨一無二的名稱,應用程序想從JNDI容器中獲取資源時,只需要告訴JNDI容器要獲取的資源的名稱,JNDI根據名稱去找到對應的資源后返回給應用程序。我們平時做javaEE開發時,服務器會為我們的應用程序創建很多資源,比如request對象,response對象,服務器創建的這些資源有兩種方式提供給我們的應用程序使用:第一種是通過方法參數的形式傳遞進來,比如我們在Servlet中寫的doPost和doGet方法中使用到的request對象和response對象就是服務器以參數的形式傳遞給我們的。第二種就是JNDI的方式,服務器把創建好的資源綁定到JNDI容器中去,應用程序想要使用資源時,就直接從JNDI容器中獲取相應的資源即可。

對于上面的name='jdbc/datasource'數據源資源,在應用程序中可以用如下的代碼去獲取

Context initCtx = new InitialContext();Context envCtx = (Context) initCtx.lookup('java:comp/env');dataSource = (DataSource)envCtx.lookup('jdbc/datasource');

此種配置下,數據庫的驅動jar文件需放置在tomcat的lib下

4.2、配置Tomcat數據源 包結構:

Java中幾種常用數據庫連接池的使用

如果報錯com.mysql.jdbc.Connection.isValid(I)Z,說明包太舊了,更新mysql包即可解決

配置數據源JNDI的方式有很多,詳細請看:https://www.jb51.net/article/213425.htm

注意了:有個問題坑了我一天

先看我的這篇文章---解決Tomcat中修改server.xml和content.xml后自動還原問題:https://www.jb51.net/article/213429.htm

之前我是直接在外部的tomcat文件下的conf文件夾下去修改這兩個文件,所以落坑

看完這篇文章應該知道了server.xml、context.xml的大概配置,接下來,我們來具體配置

我使用---配置全局JNDI數據源,應用到所有Tomcat下部署的應用

第一步、找到Tomcat的server.xml中GlobalNamingResources節點,在節點下加一個全局數據源

注意:name='jdbc/mysql'中“jdbc/mysql”為數據源名,在文件中多處引用

<Resource name='jdbc/mysql' scope='Shareable' type='javax.sql.DataSource' factory='org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory' url='jdbc:mysql://localhost:3306/test' driverClassName ='com.mysql.jdbc.Driver' username='root' password='root' />

第二步,找到Tomcat的context.xml,在Context節點下加一個ResourceLink節點對第一步配置的數據源進行引用

這個XML配置文件的根節點就是<Context>

Java中幾種常用數據庫連接池的使用

插入代碼:

<ResourceLink global='jdbc/mysql' name='jdbc/mysql' type='javax.sql.DataSource'/>

第三步,配置web.xml文件,添加資源映射(此步驟可要可不要

<resource-ref> <description>DB Connection</description> <res-ref-name>jdbc/mysql</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> </resource-ref>

這種配置方式

優點:重用性,一次性到位

缺點:沒有可控性(tomcat原始文件遭到修改)

配置文件配置好了,現在就來寫代碼

JdbcUtils_JNDI:

package zdb.util.JNDI_tomcat; import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException; import javax.naming.Context;import javax.naming.InitialContext;import javax.naming.NamingException;import javax.sql.DataSource; public class JdbcUtils_JNDI {private static DataSource ds = null;static {try {//初始化JNDIContext initCtx = new InitialContext();//得到JNDI容器Context envCtx = (Context) initCtx.lookup('java:comp/env');//從JNDI容器中檢索name為jdbc/datasource的數據源ds = (DataSource) envCtx.lookup('jdbc/mysql');} catch (NamingException e) {// TODO Auto-generated catch blocke.printStackTrace();}}public static Connection getConnection() throws SQLException{ //從數據源中獲取數據庫連接 return ds.getConnection(); }//釋放的資源包括Connection數據庫連接對象,負責執行SQL命令的Statement對象,存儲查詢結果的ResultSet對象public static void release(Connection conn,PreparedStatement ps ,ResultSet rs) {if (conn!=null) {try {conn.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}if (ps!=null) {try {ps.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}if (rs!=null) {try {rs.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}rs = null;} }}

測試下

JNDI_test:

package zdb.util.JNDI_tomcat; import java.io.IOException;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet; import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;@WebServlet('/JNDI_test')public class JNDI_test extends HttpServlet{public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Connection conn = null; PreparedStatement st = null; ResultSet rs = null; try{ //獲取數據庫連接 conn = JdbcUtils_JNDI.getConnection(); System.out.println('mysql Connection pool connected !!'); String sql = 'insert into user(uname) values(?)'; st = conn.prepareStatement(sql,PreparedStatement.RETURN_GENERATED_KEYS); st.setString(1, 'gacl'); st.executeUpdate(); //獲取數據庫自動生成的主鍵 rs = st.getGeneratedKeys(); if(rs.next()){ System.out.println(rs.getInt(1)); } }catch (Exception e) { e.printStackTrace(); }finally{ //釋放資源 JdbcUtils_JNDI.release(conn, st, rs); } } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }

我再通過寫一個jsp頁面來映射到該servlet測試下

test.jsp:

<%@ page language='java' contentType='text/html; charset=UTF-8' pageEncoding='UTF-8'%><!DOCTYPE html PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN' 'http://www.w3.org/TR/html4/loose.dtd'><html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'><title>Insert title here</title><style>body{text-align:center;}</style></head><body><a href='http://www.gepszalag.com/bcjs/${pageContext.servletContext.contextPath }/JNDI_test' rel='external nofollow' >測試</a></body>

測試結果成功:

Java中幾種常用數據庫連接池的使用

拓展:由于此種配置模式的缺點,我們還可以通過增加一個新的xml文件來增加節點,而不用動原始文件

具體請看:tomcat虛擬路徑的配置

幾篇文章推薦給大家看下:

tomcat下面web應用發布路徑配置( 即虛擬目錄配置 ):http://www.voidcn.com/article/p-zctzsjte-rs.html

Tomcat服務器原理詳解:https://www.cnblogs.com/crazylqy/p/4706223.html

Tomcat中主目錄配置與虛擬目錄配置問題自我總結:http://blog.51cto.com/longx/1357666

文章借鑒參照:-孤傲蒼狼-原文:https://www.cnblogs.com/xdp-gacl/p/4002804.html

到此這篇關于Java中幾種常用數據庫連接池的使用的文章就介紹到這了,更多相關Java 數據庫連接池內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!

標簽: Java
相關文章:
主站蜘蛛池模板: 三级色黄| 国产伦精品一区二区三区照片91 | 五月综合婷 | 欧美久久一区二区 | 精品二区视频 | 欧美第一页 | 精品伦理一区二区三区 | 亚洲成人精品在线观看 | 国产精品入口麻豆www | 成人超碰| 久久久亚洲 | 欧美午夜寂寞影院 | 中文字幕av在线 | 麻豆国产露脸在线观看 | 午夜老湿影院 | 国产成人综合在线 | 欧美久久成人 | 亚洲日韩欧美一区二区在线 | 女同videos另类 | 午夜影院毛片 | 国产老头老太作爱视频 | 免费视频久久久久 | 在线精品亚洲欧美日韩国产 | av成人在线观看 | 国产成人精品一区二区三区视频 | 国产日韩欧美在线 | 国产一区二区成人 | 欧美最猛性xxxxx亚洲精品 | 一区二区三区有限公司 | 五月在线视频 | 日本黄色电影网站 | 91精品国产日韩91久久久久久 | 国产精品久久久久久久久久东京 | 超碰人人射 | 欧美日韩不卡合集视频 | 久久免费精品视频 | 亚洲精品在线成人 | 日韩精品无码一区二区三区 | 久久精品综合 | 中文字国产精久久无 | www成人精品 | 一区二区三区在线免费观看 | 国产精品久久久久久福利一牛影视 | 99热这里有精品 | 国产色片在线 | 国产成人午夜高潮毛片 | 国产免费一区 | 久久av一区二区 | 国产视频福利在线 | 日韩二三区 | 国产亚洲精品久 | 欧美一区二区三区四区五区 | 九九久久精品 | 成人在线免费 | 欧美日韩一区二区在线观看 | 日本欧美国产 | 国产精品欧美一区二区三区 | 欧美日韩一区二区中文字幕 | 国产午夜精品一区二区三区免费 | 亚洲人成人一区二区在线观看 | 欧美色综合 | 免费的一级黄色片 | 欧美久久精品 | 亚洲一区二区三区四区在线观看 | 欧美日韩精品一区 | 久久久亚洲精品中文字幕 | 91高清在线 | 久久全国免费视频 | 国产视频一区二区 | 成年人网站在线免费观看 | 亚洲日韩欧美一区二区在线 | 国产单男 | 日韩精品久久久久久 | 色综合天天天天做夜夜夜夜做 | 国产欧美日韩综合精品一 | 国产亚洲久久 | 天天爱天天操 | 久久福利 | 婷婷色狠狠 | 欧美在线视频不卡 | 亚洲 精品 综合 精品 自拍 | 精品国产31久久久久久 | 91精品国产人妻国产毛片在线 | 欧美一区二区精品 | 日韩中文一区二区 | 亚洲一区二区三区日韩 | 欧美日韩精品电影 | 播放一区| 91中文字幕在线观看 | av在线一区二区三区 | 久久99精品久久久久久久青青日本 | 一级大片一级一大片 | 欧美一区2区三区4区公司二百 | 国产乱码精品一区二区三区中文 | 国产午夜久久久久 | 日穴视频在线观看 | 国产成人精品一区二区三区四区 | 无码日韩精品一区二区免费 | 奇米精品一区二区三区在线观看 | 日韩国产二区 | 午夜国产羞羞视频免费网站 | 中文字幕日韩在线 | 天堂av2020| 国产91网 | 精品国产一区三区 | 国产二区视频 | 亚洲一区二区中文字幕在线观看 | 欧美成人高清视频 | 天天干国产 | 国产野精品久久久久久久不卡 | 日韩中文在线 | 毛片入口 | 日韩成人不卡 | 成人黄色免费 | 91久久国产综合久久 | 久久久天天| 成人精品一区二区三区电影黑人 | www.欧美精品| 麻豆久久久久久 | 欧美3区| 久久激情网站 | 欧美精品中文字幕久久二区 | 亚洲二区视频 | 亚洲欧美日韩另类精品一区二区三区 | 91丁香婷婷综合久久欧美 | 在线观看免费成人av | 狠狠的日| 狠狠干av| 国产免费黄色 | www.伊人网| 成人在线精品视频 | 欧美一区二区三区在线观看视频 | 蜜桃视频在线观看www社区 | 精品综合 | 国产精品久久久久久亚洲调教 | xnxx 日本19 | a级黄色毛片免费观看 | 色先锋资源| 精品一区久久 | 久久久久久久久久久九 | 91cn在线观看 | 中文字幕一区二区在线观看 | 亚洲精品久久 | 国产精品国色综合久久 | 91免费在线视频 | 日韩中文不卡 | 日韩精品一区二区在线观看 | 99亚洲精品 | 欧美三级视频 | 欧美三级影院 | 亚洲视频在线免费观看 | 久久亚洲天堂 | www.国产.com| 亚洲瑟瑟| 亚洲成人第一区 | 自拍一区视频 | 可以在线观看的黄色 | 日韩一区二区三区在线 | 91在线视频观看 | 成人精品一区二区三区中文字幕 | 午夜私人影院 | 日操干 | 欧美日韩精品一区二区 | 一级毛片在线 | 在线观看成人小视频 | 极品久久久久久 | av大片网 | 99这里只有精品视频 | 日日摸日日碰夜夜爽亚洲精品蜜乳 | 久久久久久国产视频 | 色免费在线观看 | 欧美天堂在线观看 | 国产一区二区三区视频在线观看 | 日韩av免费在线观看 | 成人免费在线视频 | www.99热| 亚洲高清电影 | 久久精品无码一区二区日韩av | 美女视频黄色 | 91精品国产91久久久久久吃药 | 国产在线成人 | 毛片网站大全 | 日本亚洲精品成人欧美一区 | 久久久国产精品视频 | 日韩精品免费在线视频 | 干狠狠| 日韩高清中文字幕 | 少妇一级淫片免费放 | 国产第一页在线播放 | 欧美一区二区二区 | 久久兔费看a级 | 天天看天天爽 | 国产一区二区三区久久 | 欧美视频在线播放 | 亚洲一区中文 | 久久亚洲国产精品 | 国产精品不卡视频 | 国产精品99久久久久 | 欧美第一视频 | 国产日韩欧美在线 | 亚洲精品乱码 | 婷婷色国产偷v国产偷v小说 | 国产精品久久久久久亚洲影视 | 全毛片 | 麻豆一区 | www,久久久 | 国产精品九九九 | 97久久久 | 亚洲天天| 高清精品一区二区 | 欧美大成色www永久网站婷 | 国产视频精品自拍 | 国产精品1区二区 | 免费亚洲视频 | 成人国产在线观看 | 日韩精品无码一区二区三区 | 免费欧美一级 | 一级片免费在线视频 | 国产精品毛片久久久久久久 | 亚洲一区二区三区国产 | jizz在线看片 | 黄色片在线免费观看 | 亚洲精品一区二区三区 | 97国产一区二区 | 精品一区二区视频 | 人人干人人干人人 | 精品亚洲一区二区三区四区五区 | 欧洲亚洲精品久久久久 | 午夜婷婷丁香 | 欧美卡一卡二 | 久久综合一区二区 | 羞羞的视频在线 | 成人午夜在线视频 | 日韩精品中文字幕一区二区三区 | 视频一区二区三区在线观看 | 欧美6一10sex性hd | 日韩高清一区二区 | 中文字幕日韩专区 | 久久久国产精品入口麻豆 | 日韩欧美一区二区在线观看视频 | 久久国产精品视频 | 最新国产毛片 | 亚洲高清在线 | 在线播放三级 | 国产乱码精品一区二区三区手机版 | 成人亚洲视频在线观看 | 久久精品国产一区二区三 | 91视频免费在线 | 国变精品美女久久久久av爽 | 热99这里只有精品 | 国内精品视频一区二区三区 | 国产大片aaa | 激情久久久久 | 国产伦精品一区二区三区在线 | 日韩中文一区 | 亚洲成人久久久 | 成人精品视频在线观看 | a级性视频 | 一区三区视频 | 午夜日韩 | 日本美女一区二区三区 | 九色91视频| 亚洲国产成人av | 欧美自拍网站 | 成人综合在线观看 | 日韩在线观看高清 | 北条麻妃一区二区三区在线观看 | 亚洲一区二区av | 精品亚洲一区二区三区 | 美女91 | 网站av| 午夜影院a | 亚洲一区精品在线 | 色黄网站 | 狠狠撸在线 | 亚洲国产一区二 | 国产欧美日韩一区 | 国产综合精品 | 欧美视频二区 | 国产午夜精品久久久久久久 | 亚洲欧美一区二区三区在线 | 日韩中文字幕一区二区 | 毛片真人毛毛片毛片 | 欧美日韩国产在线播放 | 国产精品影院在线观看 | 一级在线观看 | 一区二区三区视频在线播放 | 亚洲高清一区二区三区 | 麻豆高清免费国产一区 | 欧美成人免费视频 | 日日骚| 国产精品一区久久久 | 搜一级毛片 | 亚洲八区 | 欧美极品一区二区三区 | 中文在线视频 | 国产精品久久久久久久久免费 | 成人不卡视频 | 亚洲成人一区二区三区 | 天天亚洲 | 国产一区二区三区在线免费观看 | 四虎免看黄 | 九九免费视频 | 99re在线视频 | 久久国产亚洲精品 | 亚洲三区视频 | 国产综合亚洲精品一区二 | 国产精品久久久久久久久 | 国产一区二区在线免费观看 | 欧美在线高清 | 成人夜晚看av | 国产精品18久久久 | 午夜免费观看视频 | 日本视频一区二区三区 | 中文字幕日韩欧美 | 在线一级片 | 国产一区二区三区在线看 | 日韩精品免费 | 中文字幕亚洲精品 | av毛片免费看 | 国偷自产av一区二区三区 | 亚洲免费视频在线观看 | 久草在线观看福利视频 | 国产一区二区欧美 | 久久久久国产一区 | 91精品国产综合久久久久久漫画 | 久久av网 | 精品久久久久久久 | 国产草草视频 | 国产在线视频xxx | 午夜影院普通用户体验区 | 成人欧美 | 日韩一区二区视频 | 青青草久久网 | 在线成人 | 91精品国产综合久久婷婷香蕉 | 日韩欧美一区二区三区久久婷婷 | 亚洲欧洲精品一区二区三区 | 一区二区三区久久 | 粉嫩国产精品一区二区在线观看 | 97超碰免费 | 久久精品视频一区 | 久久伊 | 亚洲精品国产精品国自产 | 欧美成人精品激情在线观看 | 久久免费视频网 | 精品日韩| 国产精品久久久久久久久久免费 | 在线99热| 国产精品二区三区 | 精品美女在线观看视频在线观看 | 在线视频亚洲 | 欧美日韩在线观看中文字幕 | 日韩一二三区在线观看 | 在线视频亚洲 | 狠狠躁夜夜躁人人爽视频 | 精品av| 亚洲精品久久久 | www.日韩在线观看 | 国产一级片a | 91亚洲日本 | 久久综合成人精品亚洲另类欧美 | a级性视频 | 国产视频二 | 欧美日韩精| av网站观看| 精品一区二区三区不卡 | 免费成人在线视频网站 | 亚洲精品久久久久久国产精华液 | 国产免费观看一区二区三区 | 久久www免费视频 | www.日韩.com | 人人射人人舔 | 麻豆网址| 国产91久久久久 | 啪啪网站免费 | 97久久精品午夜一区二区 | 欧美日韩精品久久 | 一区二区三区成人 | 成av在线| 成人av影视在线观看 | 成人毛片在线观看 | 国产精品久久久久久久久久久免费看 | 日韩三级在线 | 久久性视频 | www在线观看国产 | 欧美一级免费看 | 日韩在线成人 | 精品天堂 | 午夜爽 | 精品天堂| 天天干天天干天天干天天射 | 91精品国产综合久久久蜜臀图片 | 伊人小视频 | 国产91九色| 一区二区在线视频 | 国产在线观看av | 成人国产精品久久 | 久久在线 | 欧美日韩不卡合集视频 | 99国产精品一区 | 亚洲三区在线观看 | 亚洲福利一区二区 | 蜜桃一区二区 | 91大片| 国产精品一区二区三区免费 | 毛片91| 欧美精品片 | 日韩精品在线网站 | 国产福利在线观看 | 日韩成人| 一区二区三区四区在线 | 国产精品久久久久久久久久久久久 | 久久精彩视频 | 成人久久久 | 色猫猫国产区一区二在线视频 | 成人欧美一区二区三区在线播放 | 中文字幕国产 | 欧美日韩亚洲一区 | 亚洲第一色片 | 亚洲第一av| 亚洲a人 | 久久国内 | 欧美日韩在线免费 | 天天操天天碰 | 欧美一区二区在线看 | 99精品欧美一区二区三区 | 不卡一区二区三区四区 | 精品国产黄a∨片高清在线 日韩一区二 | 午夜精品久久久久久久久 | 亚洲视频一 | 中文字幕精品一区 | 久久成人国产精品 | 精品国产一区二区三区久久久蜜臀 | 国产女人高潮视频在线观看 | 国产精品日韩在线观看 | 北条麻妃99精品青青久久 | 日韩超碰在线观看 | 久久久久久久久免费视频 | 欧美日韩福利 | 成人久久久 | 久久久久女人精品毛片九一韩国 | 欧美日韩国产一区二区三区在线观看 | 中文字幕在线观看www | 亚洲国产成人在线观看 | 午夜影院在线观看版 | 久久国产精品视频 | 青青草视频网站 | h片免费| 久久影院国产 | 一区二区不卡 | 国产精品原创av片国产免费 | 日韩字幕一区 | 伊人热久久婷婷 | 午夜精品在线 | 久久国产高清 | 99精品免费| 在线小视频 | 午夜老湿影院 | 波多野结衣一二三区 | 久久av一区二区三区 | 精品国产一区二区三区在线观看 | av一区在线观看 | 久久99精品久久久噜噜最新章节 | 成人免费看 | 日本一区二区三区四区 | 国产免费一区二区三区最新不卡 | 亚洲一级淫片 | 中文天堂在线观看视频 | 成人免费福利视频 | 精品免费国产 | 久久精品亚洲一区 | www.五月天婷婷| 亚洲精彩视频 | 国产一级一级片 | 国产99久久久久久免费看农村 | 91麻豆精品国产91久久久久久久久 | 久久另类ts人妖一区二区 | 精品久久久久久国产 | 国产精品久久久久久久久 | 日日日操| 丁香久久 | 在线播放亚洲 | 五月色综合 | 久久99国产精品久久99大师 | 99亚洲国产 | 九色91| 欧美精品亚洲精品日韩精品 | av在线免费观看一区二区 | 久久久.com| 91在线免费看 | 国产精品成人久久久久 | 精品一区二区三区免费 | 精品成人免费视频 | 看毛片网站 | 色噜噜色综合 | 精品久 | www.欧美亚洲 | 亚洲在线视频 | 玖玖精品视频 | 国产成人免费视频网站高清观看视频 | 91九色视频国产 | 91婷婷射| 日本亚洲欧美 | 两性午夜视频 | 色综合天天天天做夜夜夜夜做 | 日本久久综合 | 亚洲一区二区三区四区的 | 成人福利在线 | 成人精品在线 | 精品少妇一区二区三区在线播放 | 国产综合精品 | 亚洲人黄色片 | 久久精品成人 | 求av网址| 在线中文字幕日韩 | www中文字幕| 久久精品99国产精品日本 | 一区二区影视 | 亚洲一区二区三区四区五区中文 | 神马久久久久久 | 亚洲国产一区二区三区四区 | 免费高清一级毛片 | 成人免费在线视频 | 91免费版在线看 | 久久99深爱久久99精品 | 伊人色综合网 | www欧美 | 九九视频在线观看视频6 | 色综合天天天天做夜夜夜夜做 | www婷婷| 中国妞xxx| 久热精品视频在线播放 | 国产精品嫩草55av | 欧美精品久久久久久久久老牛影院 | 欧美极品欧美精品欧美视频 | 国产精品免费一区 | 亚洲情综合五月天 | 日狠狠 | 香蕉视频成人在线观看 | 国产免费拔擦拔擦8x高清在线人 | 亚洲午夜精品视频 | 自拍偷拍亚洲欧美 | 伊人网在线视频观看 | 午夜精品久久久久久久星辰影院 | 一区二区三区国产 | 亚洲一区二区在线免费观看 | 国产中文字幕在线观看 | 国产传媒一区 | 国产 在线 | 日韩 | 欧洲精品一区二区 | 高清国产视频 | 日韩在线观看 | 伊人手机在线视频 | www.操.com | 亚洲精选一区二区 | 国产日韩成人 | 一区二区日本 | 日本成人中文字幕 | 国产精品久久久久久久电影 | 人人干美女 | 国产精品免费在线 | 亚洲精品66 | 亚洲一区在线日韩在线深爱 | 国偷自产一区二区免费视频 | 久久久久国产一区二区三区四区 | 国产一区二区三区四区在线观看 | 日比视频网站 | 中文字幕 国产精品 | 成人亚洲区 | 欧美色图另类 | 一级特黄| 中文字幕在线观看2021 | 国产一在线 | 中文字幕亚洲二区 | 天堂久久精品 | 久久国产一区二区三区 | 国产一级一级国产 | 成人午夜视频在线 | 久久精品一区二区三区四区 | 欧美日韩中文字幕 | 欧美二区三区 | 久草高清在线 | 国产日韩在线视频 | 九色在线 | 精品欧美日韩 | 欧美一级片在线观看 | 蜜桃视频网站在线观看 | 男人的天堂亚洲 | 亚洲无吗电影 | 涩涩视频观看 | 噜噜噜天天躁狠狠躁夜夜精品 | 免费观看日韩一级片 | 国产在线一区二区三区 | 精品在线一区二区 | 精品国产欧美一区二区 | 亚洲成人一区 | 精品久久久久久久久久久 | 中文字幕亚洲在线观看 | 午夜天堂精品久久久久 | 午夜在线电影 | 成人天堂资源www在线 | 在线中文一区 | 久色视频在线观看 | 色com| 日韩欧美大片在线观看 | 亚洲久久一区 | 亚洲精品一区二区网址 | 国产高清美女一级a毛片久久 | 五月婷婷色 | 亚洲 成人 av | 午夜精品久久久久久久久久久久 | 日韩字幕一区 | 欧美一区二区三区男人的天堂 | 精品一区二区三区免费 |