手写数据库连接池 基础
package com.curiousby.baoyou.cn.showandshare.customised.dbpool.mysql;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Iterator;
import java.util.Vector;
public class MyCustomisedPool {
/**
* <pre>
* jdbcDriver = "com.mysql.jdbc.Driver"; // 数据库驱动
* dbUrl = "jdbc:mysql://localhost:3306/database"; // 数据 URL
* dbUsername = "root"; // 数据库用户名
* dbPassword = "root"; // 数据库用户密码
* testSql = "select count(*) from t_user"; // 测试连接是否可用的测试表名,默认没有测试表
* initialConnections = 10; // 连接池的初始大小
* incrementalConnections = 5;// 连接池自动增加的大小
* maxConnections = 50; // 连接池最大的大小
* </pre>
* @author baoy
*/
private DBConfig conf;
private Vector<CustomisedConnection> connections;
public static class CustomisedConnection{
private boolean busy = false;
private Connection Connection = null;
public CustomisedConnection(Connection connection) {
Connection = connection;
}
public boolean isBusy() {
return busy;
}
public void setBusy(boolean busy) {
this.busy = busy;
}
public Connection getConnection() {
return Connection;
}
public void setConnection(Connection connection) {
Connection = connection;
}
}
/**
* <pre>
* jdbcDriver = "com.mysql.jdbc.Driver"; // 数据库驱动
* dbUrl = "jdbc:mysql://localhost:3306/database"; // 数据 URL
* dbUsername = "root"; // 数据库用户名
* dbPassword = "root"; // 数据库用户密码
* testSql = "select count(*) from t_user"; // 测试连接是否可用的测试表名,默认没有测试表
* initialConnections = 10; // 连接池的初始大小
* incrementalConnections = 5;// 连接池自动增加的大小
* maxConnections = 50; // 连接池最大的大小
* </pre>
* @author baoy
*/
public static class DBConfig{
private String jdbcDriver = "com.mysql.jdbc.Driver"; // 数据库驱动
private String dbUrl = "jdbc:mysql://localhost:3306/database"; // 数据 URL
private String dbUsername = "root"; // 数据库用户名
private String dbPassword = "root"; // 数据库用户密码
private String testSql = "select count(*) from t_user"; // 测试连接是否可用的测试表名,默认没有测试表
private int initialConnections = 10; // 连接池的初始大小
private int incrementalConnections = 5;// 连接池自动增加的大小
private int maxConnections = 50; // 连接池最大的大小
public String getJdbcDriver() {
return jdbcDriver;
}
public void setJdbcDriver(String jdbcDriver) {
this.jdbcDriver = jdbcDriver;
}
public String getDbUrl() {
return dbUrl;
}
public void setDbUrl(String dbUrl) {
this.dbUrl = dbUrl;
}
public String getDbUsername() {
return dbUsername;
}
public void setDbUsername(String dbUsername) {
this.dbUsername = dbUsername;
}
public String getDbPassword() {
return dbPassword;
}
public void setDbPassword(String dbPassword) {
this.dbPassword = dbPassword;
}
public String getTestSql() {
return testSql;
}
public void setTestSql(String testSql) {
this.testSql = testSql;
}
public int getInitialConnections() {
return initialConnections;
}
public void setInitialConnections(int initialConnections) {
this.initialConnections = initialConnections;
}
public int getIncrementalConnections() {
return incrementalConnections;
}
public void setIncrementalConnections(int incrementalConnections) {
this.incrementalConnections = incrementalConnections;
}
public int getMaxConnections() {
return maxConnections;
}
public void setMaxConnections(int maxConnections) {
this.maxConnections = maxConnections;
}
}
private Connection newConnection() throws SQLException{
Connection conn = DriverManager.getConnection(conf.dbUrl, conf.dbUsername, conf.dbPassword);
if (this.connections == null || this.connections.size() == 0) {
int driverMaxConnections = conn.getMetaData().getMaxConnections();
if (conf.maxConnections > 0 && driverMaxConnections < conf.maxConnections ) {
conf.maxConnections = driverMaxConnections;
}
}
return conn;
}
private void createConnection(int nums) throws SQLException{
for (int i = 0; i < nums; i++) {
// 1如果 最大连接数大于0
// 1.1 并且 当前连接数小于最大连接数 ,可以
// 1.2 当前连接数大于最大连接数,跳出(或者抛出异常,超出最大连接数)
// 2 如果 最大连接数小于0,无最大连接数限制
if (conf.maxConnections > 0 && this.connections.size()>= conf.maxConnections ) {
break;
}
connections.add( new CustomisedConnection(newConnection()));
}
}
public synchronized void initConnection() throws SQLException, InstantiationException, IllegalAccessException, ClassNotFoundException{
if (connections != null) {
return;
}
Driver driver = (Driver) (Class.forName(conf.jdbcDriver).newInstance());
DriverManager.registerDriver(driver);
connections = new Vector<CustomisedConnection>();
createConnection(conf.initialConnections);
}
private CustomisedConnection findFreeConnection() throws SQLException {
Iterator<CustomisedConnection> iterator = connections.iterator();
while (iterator.hasNext()) {
CustomisedConnection customisedConnection = iterator.next();
if (!customisedConnection.isBusy()) {
Connection connection = customisedConnection.getConnection();
if (!testConnection(connection)) {
connection = newConnection();
customisedConnection.setConnection(connection);
}
customisedConnection.setBusy(true);
return customisedConnection;
}
}
return null;
}
private boolean testConnection(Connection connection) throws SQLException {
if (conf.getTestSql() != null && !"".equals(conf.getTestSql())) {
try{
Statement stmt = connection.createStatement();
stmt.execute(conf.getTestSql());
}catch(Exception e){
e.printStackTrace();
closeConnection(connection);
return false;
}
}
return true;
}
private CustomisedConnection getFreeCustomisedConnection() throws SQLException {
CustomisedConnection findFreeConnection = findFreeConnection();
if (findFreeConnection != null) {
return findFreeConnection;
}
if (conf.maxConnections > 0 && conf.maxConnections > connections.size() ) {
int nums = conf.maxConnections > connections.size()+conf.incrementalConnections ? conf.incrementalConnections : conf.maxConnections- connections.size();
createConnection(nums);
}
return findFreeConnection();
}
public synchronized CustomisedConnection getConnection() throws SQLException{
if (connections == null) {
return null;
}
CustomisedConnection conn = getFreeCustomisedConnection();
while (conn == null) {
try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); }
conn = getFreeCustomisedConnection();
}
return conn;
}
public synchronized void returnConnection(Connection conn){
Iterator<CustomisedConnection> iterator = connections.iterator();
while (iterator.hasNext()) {
CustomisedConnection customisedConnection = iterator.next();
if (conn == customisedConnection.getConnection()) {
customisedConnection.setBusy(false);
}
}
}
public synchronized void closeConnection(Connection conn) {
Iterator<CustomisedConnection> iterator = connections.iterator();
while (iterator.hasNext()) {
CustomisedConnection customisedConnection = iterator.next();
if (conn == customisedConnection) {
//设置成true 没有线程继续访问它
customisedConnection.setBusy(true);
//关闭连接
Connection connection = customisedConnection.getConnection();
try { connection.close(); } catch (SQLException e) { e.printStackTrace(); }
// 从池中移除
connections.remove(customisedConnection);
}
}
}
public int getPoolSize(){
if (connections == null) {
return 0;
}
return connections.size();
}
public DBConfig getConf() {
return conf;
}
public void setConf(DBConfig conf) {
this.conf = conf;
}
public Vector<CustomisedConnection> getConnections() {
return connections;
}
public void setConnections(Vector<CustomisedConnection> connections) {
this.connections = connections;
}
public MyCustomisedPool(DBConfig conf) {
this.conf = conf;
}
//test
public static void main(String[] args) throws SQLException, InstantiationException, IllegalAccessException, ClassNotFoundException {
MyCustomisedPool pool = new MyCustomisedPool(new DBConfig() );
pool.initConnection();
for (int i = 0; i < 1000; i++) {
CustomisedConnection connection = pool.getConnection();
System.out.println(pool.getPoolSize());
try{
pool.testConnection(connection.getConnection());
}catch(Exception e){
e.printStackTrace();
pool.closeConnection(connection.getConnection());
}finally{
pool.returnConnection(connection.getConnection());
}
}
}
}
捐助开发者
在兴趣的驱动下,写一个免费
的东西,有欣喜,也还有汗水,希望你喜欢我的作品,同时也能支持一下。 当然,有钱捧个钱场(支持支付宝和微信 以及扣扣群),没钱捧个人场,谢谢各位。
个人主页:http://knight-black-bob.iteye.com/
谢谢您的赞助,我会做的更好!