程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> MYSQL數據庫 >> MySQL綜合教程 >> 使用JDBC連接MySQL數據庫--典型案例分析(三)----使用ApachDBCP連接池d

使用JDBC連接MySQL數據庫--典型案例分析(三)----使用ApachDBCP連接池d

編輯:MySQL綜合教程

使用JDBC連接MySQL數據庫--典型案例分析(三)----使用ApachDBCP連接池d


問題:

案例要求使用Apach DBCP 連接數據池重構類DBUtility 為ConnectionSource類,並重構案例“實現DBUtility”,提供連接的獲取,關閉功能的"中的EmpDAO類,在該類中使用ConnectionSource來獲取連接。

方案:

直接使用JDBC訪問數據庫時,需要避免一下隱患:

1.每一次數據操作請求都是需要建立數據庫連接,打開連接,存取數據和關閉數據等步驟。而建立和打開數據庫是一件既耗資源有費時間的過程,如果頻繁發生這樣的數據庫操作,勢必會使系統性能下降。

2.連接對象代表著數據庫系統的連接進程,是有限的資源。如果系統的使用用戶非常多,有可能超出數據庫服務器的承受極限,造成系統的崩潰。

數據庫連接池是解決上述問題最常用的方法。所謂連接池,即可以創建並持有數據庫連接的組件。連接池可以預先創建並封裝一些連接對象並將其緩存起來,當需要使用連接對象時可以向連接池“借”一個“連接”,用完之後將其“歸還”到連接池中。數據庫連接池的主要功能如下:

1>連接池對象的創建和釋放。

2>服務器啟動時,創建指定數量的數據庫連接。

3>為用戶請求提供可用連接。如果沒有空閒連接,且連接數沒有超出最大值,創建一個新的數據庫連接。

4>將用戶不再使用的連接標識為可用連接,等待其他用戶請求。

5>當空閒的連接數過多時,釋放連接對象。

連接池組件一般都需要實現JDBC規范中的javax.sql.DataSource接口。DataSource接口定義了獲取連接對象的方法getConnection()方法。常用的連接池組件有DBCP、c3p0和proxool等,本案例以Apache的DBCP組件為例,來實現數據庫連接池。簡單的應用代碼如下;

BasicDataSource ds=new BasicDataSource();
	ds.setUrl("jdbc:mysql://127.0.0.1:3306/emp");
	ds.setDriverClassName("com.mysql.jdbc.Driver");
	ds.setUsername("wonderq");
	ds.setPassword("root");
	Connection con=ds.getConnection();
	Statement stmt=con.createStatement();
	ResultSet rs=stmt.executeQuery("select count(*) from emp")
	if(rs.next()){
			System.out.println(rs.getInt(1));
		}
	stmt.close();
	con.close();

步驟:

實現此案例需要按照如下步驟進行;

步驟一:導入使用DBCP組件所需的jar包

在當前工程下,導入使用DBCP組件所需的jar包,包括commons-dbcp.jar以及commons-pool.jar兩個jar包,這兩個jar包的名字可能會因為版本的不同,名字的最後版本信息,例如:commons-dbcp-1.4.jar commons-pool-1.5.jar 有時還需要commons-collections-3.1.jar

步驟二:重構db.properties

重構此文件,在該文件中添加創建數據庫連接池所需的信息,包括初始化連接數、最大空閒連接數、最小空閒連接數、最大連接數量以及超時回收時間。該文件內容如下:

<span style="white-space:pre">	</span>jdbc.driver=com.mysql.jdbc.Driver
	jdbc.url=jdbc:mysql://127.0.0.1:3306/emp
	jdbc.user=wonderq
	jdbc.password=root
	dataSource.initialSize=10;//初始化連接大小
	dataSource.maxIdle=20;//最大空閒數
	dataSource.minIdle=5;//最小空閒數
	dataSource.maxActive=50;//最大連接數
	dataSource.maxWait=1000//超時等待時間,以毫秒為單位。

步驟三:穿件ConnectionSource類,然後在該類中添加init方法,在該方法中對數據源信息進行初始化,代碼如下所示:

package dao;
import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
import org.apache.commons.dbcp.BasicDataSource;
public class ConnectionSource {
		private static BasicDataSource dataSource=null;
		public ConnectionSource(){
		}
		public static void init(){
			Properties dbprops=new Properties();
			//取配置文件可以根據實際的不同修改
			try {
		dbprops.load(ConnectionSource.class.getClassLoader().getResourceAsStream("db.properties"));
			} catch (Exception e) {
				e.printStackTrace();
			}
			try {
				String driverClassName=dbprops.getProperty("jdbc.driver");
				String url=dbprops.getProperty("jdbc.url");
				String username=dbprops.getProperty("jdbc.user");
				String password=dbprops.getProperty("jdbc.password");
				
				String initialSize=dbprops.getProperty("dataSource.initialSize");
				String minIdle=dbprops.getProperty("dataSource.minIdle");
				String maxIdle=dbprops.getProperty("dataSource.maxIdle");
				String maxWait=dbprops.getProperty("dataSource.maxWait");
				String maxActive=dbprops.getProperty("dataSource.maxActive");
				
				dataSource =new BasicDataSource();
				dataSource.setDriverClassName(driverClassName);
				dataSource.setUrl(url);
				dataSource.setUsername(username);
				dataSource.setPassword(password);
				
				//初始化連接數
				if(initialSize!=null){
					dataSource.setInitialSize(Integer.parseInt(initialSize));
				}
				//最小空閒連接
				if(minIdle!=null){
					dataSource.setMinIdle(Integer.parseInt(minIdle));
				}
				//最大空閒連接
				if(maxIdle!=null){
					dataSource.setMaxIdle(Integer.parseInt(maxIdle));
				}
				//超時回收時間(以毫秒為單位)
				if(maxWait!=null){
					dataSource.setMaxWait(Long.parseLong(maxWait));
				}
				//最大連接數
				if(maxActive!=null){
					if(!maxActive.trim().equals("0")){
						dataSource.setMaxActive(Integer.parseInt(maxActive));
					}
				}
				
			} catch (Exception e) {
				e.printStackTrace();
				System.out.println("創建連接池失敗!請檢查設置!!!");
			}
		}
}
步驟四:添加獲取連接的方法

在ConnectionSource類中添加獲取連接的方法,getConnection,代碼如下所示:

public static synchronized Connection getConnection() throws SQLException{
			if(dataSource==null){
				init();
			}
			Connection con=null;
			if(dataSource!=null){
				con=dataSource.getConnection();
			}
			return con;
		}
步驟四:重構EmpDAO類

重構EmpDAO類,在該類中使用ConnectionSource類的getConnection()方法獲取連接,代碼如下所示:

package dao;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class EmpDAO {
	public static void main(String [] args){
		EmpDAO dao=new EmpDAO();
		dao.findAll();
	}
	public void findAll(){
		Connection con=null;
		Statement stmt=null;
		ResultSet rs=null;
		
		try {
			con=ConnectionSource.getConnection();
			stmt=con.createStatement();
			rs=stmt.executeQuery("select empno,ename,sal,hiredate from emp;");
			while(rs.next()){
				System.out.println(rs.getInt("empno")+","+rs.getString("ename")+","+rs.getDouble("sal")+","+rs.getDate("hiredate"));
			}
		} catch (SQLException e) {
			System.out.println("數據庫訪問異常!");
			throw new RuntimeException(e);
		}
		finally{
			try {
				if(rs!=null){
						rs.close();
					}
					if(stmt!=null){
						stmt.close();
					}
					if(con!=null){
						con.close();
					}
			} catch (SQLException e) {
				System.out.println("釋放資源時發生異常!");
			}
		}
	}
}
在此,調用Connection類的close方法關閉連接,會將該連接歸還到連接池中。

運行EmpDAO類,輸出如下:

和之前的案例輸出結果一致。

本節,先更新到這裡,下次繼續寫:如何更新和插入Emp數據。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved