天天看點

dbcp001:dbcp連接配接資料庫的三種方式

  • 使用傳統的資料庫連接配接方式,有以下缺點
    dbcp001:dbcp連接配接資料庫的三種方式
    是以我們使用連接配接池來優化資料庫連接配接,其原理如下。每次的連接配接不是直接和資料庫進行互動,而是從連接配接池裡面拿,這樣減少了和資料庫互動的次數,提高了效率
    dbcp001:dbcp連接配接資料庫的三種方式
現在很多WEB伺服器(Weblogic, WebSphere, Tomcat)都提供了DataSoruce的實作,即連接配接池的實作。通常我們把DataSource的實作,按其英文含義稱之為資料源,資料源中都包含了資料庫連接配接池的實作
  • DBCP 是 Apache 軟體基金組織下的開源連接配接池實作,使用DBCP資料源,應用程式應在系統中增加如下兩個 jar 檔案:

    Commons-dbcp.jar:連接配接池的實作

    Commons-pool.jar:連接配接池實作的依賴庫

    Tomcat 的連接配接池正是采用該連接配接池來實作的。該資料庫連接配接池既可以與應用伺服器整合使用,也可由應用程式獨立使用

  • 第一種連接配接方式:;使用連接配接池和屬性配置檔案來連接配接資料庫。這裡屬性配置檔案裡面寫資料庫連接配接的URL,賬号,密碼等,然後通過反射機制加載到類中,進而連接配接資料庫
  • 建立一個類,類裡面實作資料庫的連接配接與斷開
package com.z.JdbcUtils;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
import javax.sql.DataSource;
import org.apache.commons.dbcp.BasicDataSourceFactory;
public class Jdbc {
	private static DataSource ds;
	static{
		try {
			Properties pro=new Properties();//加載屬性配置檔案
			InputStream in=Jdbc.class.getClassLoader().getResourceAsStream("dbcpconfig.properties");//讀檔案
			pro.load(in);//加載,發生關系
			//建立一個基本的資料源工廠
			BasicDataSourceFactory bdsf=new BasicDataSourceFactory();
			ds=bdsf.createDataSource(pro);
		} catch (Exception e) {
			throw new ExceptionInInitializerError(e);
		}
	}
	public static Connection getConnection() throws SQLException{
			return ds.getConnection();
	}
	
	//從資料庫連接配接池裡面擷取連結
	public static void main(String[] args) throws SQLException {
		System.out.println(getConnection());
	}
	//關閉資料庫,此時這的關閉不是真正的關閉連結,而是歸還到池中
	public static void close(ResultSet rs,Statement st,Connection con){
		try {
			if(rs!=null) rs.close();
		} catch (SQLException e) {
			throw new RuntimeException();
		}finally{
			try {
				if(st!=null) st.close();
			} catch (SQLException e) {
				throw new RuntimeException();
			}finally{
				try {
					if(con!=null) con.close();
				} catch (SQLException e) {
					throw new RuntimeException();
				}
			}
		}
	}
}

           
  • 建立屬性配置檔案,配置路徑,密碼,賬号,連接配接池最小連接配接數,最大連接配接數等
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/test
password=
username=root
initialSize=10
maxActive=50
maxIdle=20
minIdle=5
maxWait=60000
           
  • 運作如果報的錯誤是java.lang.NoClassDefFoundError: org/apache/commons/pool/impl/GenericObjectPool

    在網上查找錯誤的原因,說是缺少了一個commons-pool.jar檔案

    在myeclipse的安裝目錄下搜尋,得到這個檔案.放進lib檔案夾.

    dbcp001:dbcp連接配接資料庫的三種方式
    資料庫連接配接需要一個Jar包,連接配接池DBCP需要兩個Jar包,都需要放在項目的webroot下的lib包底下。
    dbcp001:dbcp連接配接資料庫的三種方式
  • 第二種連接配接方式:通過Tomcat通路頁面時,從連接配接池裡面獲得連接配接。
  • 先把上一種方法中提出的那三個Jar包放到Tomcat下的lib目錄下。
D:\Tomcat6.0\lib
           

在D:\Tomcat6.0\conf下的server.xml中配置

<Context path="/toncatdbcp">
                     <Resource name="jdbc/datasource"
                     auth="Container"
                     username="root"
                     password=""
                     driverClassName="com.mysql.jdbc.Driver"
                     url="jdbc:mysql://localhost:3306/test"
                     maxActive="8"
                     maxIdle="4" />
           </Context>
           
dbcp001:dbcp連接配接資料庫的三種方式

寫Jdbc

package com.z.dbcp;

import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
public class Jdbc {
	private static DataSource ds;
	static{
		try {
			//建立一個大容器
			Context initCtx = new InitialContext();
			//建立一個子容器
			Context envCtx = (Context) initCtx.lookup("java:comp/env");
			//擷取連結池資源,就是連接配接池對象
			ds=(DataSource) envCtx.lookup("jdbc/datasource");
		} catch (NamingException e) {
			throw new ExceptionInInitializerError(e);
		}
	}
	public static Connection getConnection() throws SQLException{
			return ds.getConnection();
	}
	
	//從資料庫連接配接池裡面擷取連結
	public static void main(String[] args) throws SQLException {
		System.out.println(getConnection());
	}
	//關閉資料庫,此時這的關閉不是真正的關閉連結,而是歸還到池中
	public static void close(ResultSet rs,Statement st,Connection con){
		try {
			if(rs!=null) rs.close();
		} catch (SQLException e) {
			throw new RuntimeException();
		}finally{
			try {
				if(st!=null) st.close();
			} catch (SQLException e) {
				throw new RuntimeException();
			}finally{
				try {
					if(con!=null) con.close();
				} catch (SQLException e) {
					throw new RuntimeException();
				}
			}
		}
	}	
}

           
  • x寫servlet測試
package com.z.servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.z.dbcp.Jdbc;
public class JdbcServlet extends HttpServlet {
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
	}
	@Override
	protected void service(HttpServletRequest resquest, HttpServletResponse response)
			throws ServletException, IOException {
		try {
			Connection con=Jdbc.getConnection();
			System.out.println(con);
		} catch (SQLException e) {
			
			e.printStackTrace();
		}
	}
	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

	}
}
           

這種方式沒次都需要重新開機伺服器,而且server.xml裡面的項目名是寫死的,每次都需要改,是以特别不友善,不推薦使用。

  • 第三種方式:

    1,還是把那三個Jar包放到Tomcat的lib下面,供所有項目通路,不過也可以放到自己的項目lib下面,這樣的話隻有你自己才能用。

    2,在webroot下的MEAT-INF下建立context.xml檔案,在裡面配置資料庫連接配接

    dbcp001:dbcp連接配接資料庫的三種方式
<Context>
		<Resource name="jdbc/datasource" 
		auth="Container"
        type="javax.sql.DataSource"
        username="root" 
		password=""
     	driverClassName="com.mysql.jdbc.Driver" 
       	url="jdbc:mysql://localhost:3306/test"
       	maxActive="8" 
		maxIdle="4"/>	
</Context>
           

3,做jdbc

package com.z.dbcp;

import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
public class Jdbc {
	private static DataSource ds;
	static{
		try {
			//建立一個大容器
			Context initCtx = new InitialContext();
			//建立一個子容器
			Context envCtx = (Context) initCtx.lookup("java:comp/env");
			//擷取連結池資源,就是連接配接池對象
			ds=(DataSource) envCtx.lookup("jdbc/datasource");
		} catch (NamingException e) {
			throw new ExceptionInInitializerError(e);
		}
	}
	public static Connection getConnection() throws SQLException{
			return ds.getConnection();
	}
	
	//從資料庫連接配接池裡面擷取連結
	public static void main(String[] args) throws SQLException {
		System.out.println(getConnection());
	}
	//關閉資料庫,此時這的關閉不是真正的關閉連結,而是歸還到池中
	public static void close(ResultSet rs,Statement st,Connection con){
		try {
			if(rs!=null) rs.close();
		} catch (SQLException e) {
			throw new RuntimeException();
		}finally{
			try {
				if(st!=null) st.close();
			} catch (SQLException e) {
				throw new RuntimeException();
			}finally{
				try {
					if(con!=null) con.close();
				} catch (SQLException e) {
					throw new RuntimeException();
				}
			}
		}
	}	
}
           

4,測試同上面的測試方法。

使用這種方法有個好處就是不用重新開機伺服器,而且也可以在context.xml裡面寫入oracle的資料庫連接配接,想要連接配接的時候直接在下圖紅色位置吧oracle的連接配接名字寫進去,或者想要用哪個類的時候,直接在這個檔案裡面拿,也是非常的友善
dbcp001:dbcp連接配接資料庫的三種方式

上面三種方式還用到了JNDI技術

JNDI(Java Naming and Directory Interface),Java命名和目錄接口,它對應于Java SE中的javax.naming包,

這套API的主要作用在于:它可以把Java對象放在一個容器中(JNDI容器),并為容器中的java對象取一個名稱,以後程式想獲得Java對象,隻需通過名稱檢索即可。

其核心API為Context,它代表JNDI容器,其lookup方法為檢索容器中對應名稱的對象。JNDI的出現,讓程式員和資料庫的耦合降低!

繼續閱讀