现成的各种开源连接池已经很多,而且很完善,为什么我们要 自己动手写连接池呢,
因为框架都是别人写好的,你直接拿来用未必就懂里面的原理,所以为了能更好的理解连接池的工作原理,我们还是自己动手写一遍,本文提供的代码, 是经过笔者多年的多个项目实际运行考验的,相当的稳健了。
首页 > 大数据 > Hadoop > 自己动手写java 数据库连接池
现成的各种开源连接池已经很多,而且很完善,为什么我们要 自己动手写连接池呢,
因为框架都是别人写好的,你直接拿来用未必就懂里面的原理,所以为了能更好的理解连接池的工作原理,我们还是自己动手写一遍,本文提供的代码, 是经过笔者多年的多个项目实际运行考验的,相当的稳健了。
直接贴上代码了。
DB.JAVA
用来维护连接池的连接的基础包
package com;
/* * To change this template, choose Tools | Templates * and open the template in the editor. *//** * * @author user */
import java.sql.Connection;import java.sql.ResultSet;import java.sql.SQLException;import java.util.Vector;import java.sql.Statement;
public class DB {
Connection con = null; private String testTable = "test"; // 测试连接是否可用的测试表名,默认没有测试表 private Vector
private DB() { init(); }
private void init() { pool = new Vector
public synchronized void release(Connection cn) { pool.add(cn); }
public synchronized void closePool() { if(pool!=null&&pool.size()>0){ for (int i = 0; i < pool.size(); i++) { try { ((Connection) pool.get(i)).close(); pool.remove(i); pool=null; } catch (SQLException e) { e.printStackTrace(); }
} } }
public static DB getInstance() { if (instance == null) { instance = new DB(); } return instance; }
public synchronized Connection getConnection() { Connection conn; if (pool!=null&&pool.size() > 0) { conn = pool.get(0); pool.remove(conn); return conn;
} else { //return null; addConnection(); conn = pool.get(0); pool.remove(conn); return conn; } }
public void addConnection() { Connection conn = null; if(pool!=null&&pool.size()>=0){
}else{ init(); } for ( int i = pool.size(); i < poolSize; i++) //i=0; { try { Class.forName(driverClassName); conn = java.sql.DriverManager.getConnection(url, username, password); pool.add(conn); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } } }
private void readConfig() { try { this.driverClassName = "com.mysql.jdbc.Driver"; this.username = "root";//你的数据库连接用户名 this.password = "123456";//你的数据库连接密码 this.url = "jdbc:mysql://localhost:3306/mydatebase?userUnicode=true&characterEncoding=utf-8&autoReconnect=true"; this.poolSize = 5;//连接池中的连接数
} catch (Exception e) { // TODO: handle exception // util_my.send_mail("DB异常报告",e.getMessage()); e.printStackTrace(); System.out.print("出错了!"); } }
/** * 测试一个连接是否可用,如果不可用,关掉它并返回 false * 否则可用返回 true * * @param conn 需要测试的数据库连接 * @return 返回 true 表示此连接可用, false 表示不可用 */ public boolean testConnection(Connection conn) { ResultSet rs = null; int i = 0; try {
//check if this connection is valid
Statement stmt = conn.createStatement(); rs = stmt.executeQuery("select count(*) num from test"); if (rs.next()) { i = rs.getInt("num"); } if (i == 1) { return true; } else { closeConnection(conn); return false; } } catch (SQLException e) { e.printStackTrace(); // 上面抛出异常,此连接己不可用,关闭它,并返回 false; closeConnection(conn); return false;
} catch (Exception e) { e.printStackTrace(); closeConnection(conn); return false; }
// 连接可用,返回 true
}
public void closeConnection(Connection conn) { try {
conn.close();
} catch (SQLException e) { e.printStackTrace();
System.out.println(" 关闭数据库连接出错: " + e.getMessage());
} }
dbcomm flle,封装了 select ,update,insert 操作,并且管理了获取和释放连接池的连接
package com;
import java.sql.*;
public class dbconn{
private Connection conn=null; private ResultSet rs=null; private Statement stmt=null; DB db = null;
public dbconn(){ db = DB.getInstance(); } public ResultSet executeQuery(String sql){ try{ if(stmt!=null){ stmt.close(); stmt=null;} if(rs!=null){ rs.close(); rs=null;} if(conn!=null){ conn.close(); conn=null; } try{ this.conn=db.getConnection(); int loop1=0; while(!testConnection(this.conn)){ loop1=loop1+1; this.conn=db.getConnection(); if(loop1==20) { db.closePool(); this.conn=db.getConnection(); break; } } this.stmt=conn.createStatement(); this.rs=stmt.executeQuery(sql); }catch(SQLException e){ stmt.close(); stmt=null; rs.close(); rs=null; conn.close(); conn=null; db.closePool(); conn=db.getConnection(); stmt=conn.createStatement(); rs=stmt.executeQuery(sql); } }catch(SQLException ex){DB.getInstance().closePool(); } return this.rs; } public int executeUpdate(String sql){ int result=-1; try{
try{ this.conn=db.getConnection(); int loop1=0; while(!testConnection(this.conn)){ loop1=loop1+1; this.conn=db.getConnection(); if(loop1==20) { db.closePool(); this.conn=db.getConnection(); System.out.print("try connect:"+loop1); break; } } this.stmt=conn.createStatement(); result=stmt.executeUpdate(sql); }catch(SQLException e){
this.conn=db.getConnection(); this.stmt=conn.createStatement(); result=stmt.executeUpdate(sql); e.printStackTrace(); }
}catch(SQLException ex){DB.getInstance().closePool();ex.printStackTrace(); /* util_my.send_mail("executeUpdate异常报告",ex.getMessage()+" result:"+result);*/ } return result;
}
public void closeConnection(){ try{ if(rs!=null){ rs.close();rs=null; } if(stmt!=null){ stmt.close(); stmt=null; } if(conn!=null){ db.release(conn); conn=null; } }catch(SQLException er){er.printStackTrace(); /*util_my.send_mail("closeConnection异常报告",er.getMessage());*/ } finally{ try{ if(rs!=null){ rs.close();rs=null; } if(stmt!=null){ stmt.close(); stmt=null; } if(conn!=null){ db.release(conn); // conn.close(); conn=null; } }catch(SQLException er){} } }
/** * 测试一个连接是否可用,如果不可用,关掉它并返回 false * 否则可用返回 true * * @param conn 需要测试的数据库连接 * @return 返回 true 表示此连接可用, false 表示不可用 */ public boolean testConnection(Connection conn) { ResultSet rs = null; int i = 0; try {
//check if this connection is valid
this.stmt = conn.createStatement(); this.rs = stmt.executeQuery("select count(*) num from test"); if (this.rs.next()) { i = this.rs.getInt("num"); } if (i == 1) { return true; } else { return false; } } catch (SQLException e) { e.printStackTrace(); // 上面抛出异常,此连接己不可用,关闭它,并返回 false; db.closeConnection(conn); return false;
} catch (Exception e) { e.printStackTrace(); db.closeConnection(conn); return false; }
// 连接可用,返回 true
}}
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/22921085/viewspace-1112342/ ,如需转载,请注明出处,否则将追究法律责任。