java-mysql數據庫連接池

閒來無事,寫了一個MySql數據庫連接池

工程結構如圖

 

 

源碼如下:

DBConnectioin.java如下

 

package com.database;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;

public class DBConnection {
 private Connection conn = null;  //數據庫連接句柄
 private Statement stm = null;  
 private boolean used = false;  //該鏈接是否正被使用
 private boolean inPools = true;  //是否在連接池中
 private ArrayList<String> batchSql = null; //批量處理sql
 
 public DBConnection(){
 }
 /**
  * Description 構造方法
  * @param drivername 數據庫驅動名稱
  * @param url 數據庫地址
  */
 protected DBConnection(String drivername, String url, String username,
   String password){
  try{
   Class.forName(drivername);
   conn = DriverManager.getConnection(url, username, password);
  }
  catch(Exception e){
   e.printStackTrace();
  }
 }
 
 /**
  * Description 構造方法
  * @param drivername 數據庫驅動名稱
  * @param username 用戶名
  * @parma password 密碼
  * @param url 數據庫地址
  * @param inPools 是否在緩衝池裏
  */
 protected DBConnection(String drivername, String url, String username,
   String password, boolean inPools){
  try{
   Class.forName(drivername).newInstance();
   conn = DriverManager.getConnection(url, username, password);
   this.inPools = inPools;
  }
  catch(Exception e){
   e.printStackTrace();
  }
  this.inPools = inPools;
 }
 /**
  * 關閉連接
  */
 public void closeConn(){
  try{
   if(conn != null && !conn.isClosed()){
    try{
     conn.close();
     conn = null;
    }
    catch(SQLException e){
     e.printStackTrace();
    }
   }
  }catch(SQLException e){
   e.printStackTrace();
  }
 }
 
 /**
  * @return the conn
  */
 public Connection getConn() {
  return conn;
 }

 /**
  * @param conn the conn to set
  */
 private void setConn(Connection conn) {
  this.conn = conn;
 }

 /**
  * FunName setAutoCommit
  * Description 設置自動提交
  * @param bool 是否自動提交
  */
 public void setAutoCommit(boolean bool){
  try{
   if(conn.getAutoCommit() != bool){
    conn.setAutoCommit(bool);
    closeStm();
    createStatement();
   }
  }
  catch(Exception e){
   e.printStackTrace();
  }
 }

 /**
  * @return the used
  */
 protected boolean isUsed() {
  return used;
 }

 /**
  * @param used the used to set
  */
 protected void setUsed(boolean used) {
  this.used = used;
 }

 /**
  * @return the inPools
  */
 protected boolean isInPools() {
  return inPools;
 }

 /**
  * @param inPools the inPools to set
  */
 protected void setInPools(boolean inPools) {
  this.inPools = inPools;
 }
 
 /**
  * FunName execute
  * Description 執行sql語句
  */
 public boolean execute(String sql){
  boolean success = false;
  try{
   createStatement();
   success = stm.execute(sql);
  }
  catch(Exception e){
   e.printStackTrace();
   success = false;
  }
  return success;
 }
 /**
  * FunName addBatch
  * Description 添加批量處理sql語句
  */
 public void addBatch(String sql){
  if(batchSql == null)
   batchSql = new ArrayList();
  batchSql.add(sql);
 }

 /**
  * FunName batch
  * Description 批量執行sql語句
  */
 public boolean batch(){
  try{
   createStatement();
   setAutoCommit(false);
   stm.execute("START TRANSACTION;");
   for(int i = 0; i < batchSql.size(); i++){
    stm.addBatch(batchSql.get(i));
   }
   stm.executeBatch();
   conn.commit();
  }
  catch(Exception e){
   try{
    conn.rollback();
   }
   catch(Exception el){
    el.printStackTrace();
   }
   e.printStackTrace();
  }
  batchSql = null;
  setAutoCommit(true);
  return true;
 }
 
 /**
  * FunName query
  * Description 執行查詢語句
  * @param sql 查詢語句
  * @return 查詢結果集ResultSet
  */
 public ResultSet query(String sql){
  ResultSet rs = null;
  try{
   createStatement();
   rs = stm.executeQuery(sql);
  }
  catch(Exception e){
   e.printStackTrace();
  }
  return rs;
 }
 /**
  * FunName createStatement
  * Description 創建Statement
  */
 private void createStatement() throws Exception{
  if(stm == null){
   stm = conn.createStatement();
  }
 }
 /**
  * FunName closeStm
  * Description 關閉Statement
  */
 protected void closeStm(){
  try{
   if(stm != null)
    stm.close();
  }
  catch(Exception e){
   e.printStackTrace();
  }
  stm = null;
 }
 /**
  * FunName closeRs
  * Description 關閉Result
  */
 public void closeRs(ResultSet rs){
  try{
   if(rs != null)
    rs.close();
  }
  catch(Exception e){
   e.printStackTrace();
  }
 }
}

 

DBConnectionPool.java如下

 

package com.database;

import java.sql.Connection;
import java.util.Iterator;
import java.util.Properties;
import java.util.Vector;

/*
 *
 */
public class DBConnectionPool {
 /**
  * 連接地址
  */
 private static String url;
 /**
  * 字符編碼
  */
 private static String encoding;
 /**
  * 驅動程序
  */
 private static String drivername;
 /**
  * 數據庫名
  */
 private static String database;
 /*
  * 用戶名
  */
 private static String username;
 /*
  * 密碼
  */
 private static String password;
 /**
  * 數據庫連接池
  */
 private static Vector<DBConnection> pools = new Vector();
 /**
  * 當前連接池可用連接句柄數據
  */
 private static int currConnCount = 0;
 /**
  * 連接池最高連接數據
  */
 private static int maxConnCount = 30;
 /**
  * 連接池最小連接數據
  */
 private static int minConnCount = 10;
 /**
  * 連接池增長速度
  */
 private static int createSpeed = 10;
 /**
  * 連接池
  */
 private static DBConnectionPool dbConnectionPool = null;
 
 /*
  * FunName DBConnectionPool
  * Description 構造方法
  */
 private DBConnectionPool(){
  ReadDBProperties readProperties = new ReadDBProperties();
  Properties properties = readProperties.getProperties();
  drivername = properties.getProperty("drivername"); //從資源文件中讀取數據庫驅動名稱
  database = properties.getProperty("database");  //從資源文件中讀取數據庫名稱
  username = properties.getProperty("username");  //從資源文件中讀取用戶名
  password = properties.getProperty("password");  //從資源文件中讀取密碼
  encoding = properties.getProperty("encoding");  //從資源文件中讀取數據庫編碼
  url = properties.getProperty("url")+"/"+database
   +"?useUnicode=true&characterEncoding="+encoding;//從資源文件中讀取數據庫路徑
  int max = 5; //默認連接池中最大連接數
  try{
   max = Integer.parseInt(properties.getProperty("maxConnCount")); //從資源文件中讀取最大連接數
   maxConnCount = max;
  }catch(Exception e){
   e.printStackTrace();
  }
  int min = 1; //默認連接池中最小連接數
  try{
   min = Integer.parseInt(properties.getProperty("minConnCount")); //從資源文件中讀取最小連接數
   if(min > max)
    min = max;
   minConnCount = min;
  }catch(Exception e){
   e.printStackTrace();
  }
  int speed = 1; //默認數據庫連接增長速度爲1
  try{
   speed = Integer.parseInt(properties.getProperty("createSpeed"));//從資源文件中讀取數據庫連接增長速度
   if(speed > max)
    speed = max;
   createSpeed = speed;
  }catch(Exception e){
   e.printStackTrace();
  }
  InitConnections();
 }
 /**
  * FunName InitConnections
  * Description 初始化連接池pools
  */
 private void InitConnections(){
  for(int i = 0; i < minConnCount; i++){
   DBConnection dbConnection = new DBConnection(drivername, url, username, password);
   pools.add(dbConnection);
  }
  currConnCount = minConnCount;
 }
 
 /**
  * FunName createConnection
  * Description 創建連接句柄
  */
 private static void createConnection(){
  int leaveCount = maxConnCount - pools.size(); //計算剩下多少個可創建的數據庫連接
  int createCount = createSpeed < leaveCount ? createSpeed : leaveCount; //計算此次創建多少個數據庫連接
  for(int i = 0; i < createCount; i++){
   DBConnection dbConnection = new DBConnection(drivername, url, username, password);
   pools.add(dbConnection);
  }
  currConnCount += createCount; //計算當前可用數據庫連接
 }
 
 /**
  * 得到一個連接句柄
  * @return dbConnection
  */
 public static DBConnection getDBConnection(){
  //如果未初始化連接池,那麼執行初始化
  if(dbConnectionPool == null){
   dbConnectionPool = new DBConnectionPool();
  }
  //連接池連接數量爲0,配置文件出錯
  if(pools.size() == 0){
   System.out.println("創建連接池失敗,請檢查配置文件!");
   return null;
  }
  //遍歷連接池,尋找一個可用連接
  Iterator<DBConnection> it = pools.iterator();
  while(it.hasNext()){
   //從連接池中得到一個連接
   DBConnection dbConnection = it.next();
   //判斷是否可用
   if(!dbConnection.isUsed()){
    //得到連接名柄
    Connection connection = dbConnection.getConn();
    try{
     //如果連接名柄可用,從連接池中返回,否則銷燬
     if(connection!=null && !connection.isClosed()){
      dbConnection.setUsed(true);
      currConnCount--;
      return dbConnection;
     }
     else{
      pools.remove(dbConnection);
     }
    }catch(Exception e){
     e.printStackTrace();
    }
   }
  }
  //遍歷完連接池也找不到1個可用連接創建新的連接
  //判斷是否連接池中的連接數量是否還可增長,可增長則由連接池創建連接,否則返回額外的連接名柄
  if(currConnCount <= 0 && pools.size() < maxConnCount){
   createConnection();
  }
  else if(pools.size() >= maxConnCount){
   return new DBConnection(drivername, url, username, password, false);
  }
  return new DBConnection(drivername, url, username, password, false);
 }
 
 /**
  * FunName close
  * Description 連接句柄dbConnection放回連接池
  * @param dbConnection
  */
 public static void close(DBConnection dbConnection){
  //如果是連接池的連接,由連接池回收,否則自動銷燬
  if(dbConnection.isInPools()){
   //設置連接處於空閒狀態
   dbConnection.setUsed(false);
   dbConnection.closeStm();
   currConnCount++;
  }
  else
   dbConnection.closeConn();
 }
 
 /*
  * Description 關閉連接池
  */
 public static void closePools(){
  Iterator<DBConnection> it = pools.iterator();
  while(it.hasNext()){
   DBConnection dbConnection = it.next();
   dbConnection.closeConn();
  }
  pools.removeAllElements();
  if(pools.size() == 0){
   System.out.println("連接池關閉成功!");
  }
 }
 
 /**
  * FunName getCurrConnCount
  * Description 返回連接池可用連接數
  * @return 返回連接池可用連接數
  */
 public static int getCurrConnCount() {
  return currConnCount;
 }
 
 /**
  * FunName getConnCount
  * Description 返回連接池連接數
  * @return 返回連接池連接數
  */
 public static int getConnCount(){
  return pools.size();
 }
 
}

 

ReadDBProperties.java如下

 

package com.database;

import java.io.InputStream;
import java.util.Properties;

public class ReadDBProperties {
 private Properties properties;
 private String webUrl = "";
 
 public ReadDBProperties(){
  properties = new Properties();
  InputStream in = null;
  try{
   Package pack = ReadDBProperties.class.getPackage(); //得到類的包對象
   ClassLoader loader = ReadDBProperties.class.getClassLoader(); //得到類的加載路徑對象
   webUrl = loader.getResource("").getPath(); //得到類路徑
   webUrl = java.net.URLDecoder.decode(webUrl, "UTF-8"); //對路徑進行編碼
   webUrl = webUrl.substring(1, webUrl.lastIndexOf("/classes/")); //得到web根路徑
   in = loader.getResourceAsStream("db_init.properties"); //得到數據庫配置文件流
   properties.load(in); //加載數據庫配置文件
   in.close(); //關閉文件流
   in = null;
  }
  catch(Exception e){
   e.printStackTrace();
  }
 }

 public Properties getProperties() {
  return properties;
 }
 
 public String getWebUrl(){
  return webUrl;
 }
}

DBTest.java如下

package com.database;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.PreparedStatement;

public class DBTest {
 public static void main(String args[]){
  DBConnection dbConn1 = DBConnectionPool.getDBConnection();
  System.out.println("連接池:" + DBConnectionPool.getConnCount());
  System.out.println("當前連接池:" + DBConnectionPool.getCurrConnCount());
  System.out.println("-----------------");
  DBConnection dbConn2 = DBConnectionPool.getDBConnection();
  System.out.println("連接池:" + DBConnectionPool.getConnCount());
  System.out.println("當前連接池:" + DBConnectionPool.getCurrConnCount());
  System.out.println("-----------------");
  DBConnection dbConn3 = DBConnectionPool.getDBConnection();
  System.out.println("連接池:" + DBConnectionPool.getConnCount());
  System.out.println("當前連接池:" + DBConnectionPool.getCurrConnCount());
  System.out.println("-----------------");
  DBConnectionPool.close(dbConn1);
  System.out.println("連接池:" + DBConnectionPool.getConnCount());
  System.out.println("當前連接池:" + DBConnectionPool.getCurrConnCount());
  System.out.println("-----------------");
  DBConnectionPool.close(dbConn2);
  DBConnectionPool.close(dbConn3);
  System.out.println("連接池:" + DBConnectionPool.getConnCount());
  System.out.println("當前連接池:" + DBConnectionPool.getCurrConnCount());
  System.out.println("-----------------");
    
  DBConnection dbConn = DBConnectionPool.getDBConnection();
  
  ResultSet rs = dbConn.query("SELECT * FROM MEMBER");
  try{
   while(rs.next()){
    System.out.println("用戶ID:" + rs.getInt("mid"));
    System.out.println("用戶名:" + rs.getString("username"));
    System.out.println("密碼:" + rs.getString("password"));
   }
  }
  catch(Exception e){
  }
  System.out.println("連接池:" + DBConnectionPool.getConnCount());
  System.out.println("當前連接池:" + DBConnectionPool.getCurrConnCount());
  System.out.println("-----------------");
  dbConn.addBatch("INSERT INTO MEMBER (USERNAME, PASSWORD, EMAIL) VALUES ('TEST1', 'TEST1', '[email protected]' )");
  dbConn.addBatch("INSERT INTO MEMBER (MID, USERNAME, PASSWORD, EMAIL) VALUES ('1', 'TEST2', 'TEST2', '[email protected]' )");
  dbConn.batch();
  DBConnectionPool.close(dbConn);
  
 }
}

 

資源文件db_init.properties如下

url=jdbc:mysql://localhost:3306
database=mhome
encoding=UTF-8
drivername=com.mysql.jdbc.Driver
username=root
password=root
maxConnCount=2
minConnCount=1
createSpeed=1

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章