手寫 基礎 資料庫連線池
阿新 • • 發佈:2018-11-20
手寫資料庫連線池 基礎
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/
謝謝您的贊助,我會做的更好!