手写 基础 数据库连接池
程序员文章站
2022-05-22 08:30:52
...
手写数据库连接池 基础
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/
谢谢您的赞助,我会做的更好!
上一篇: 包:命令行如何编译带包结构的源文件?
下一篇: 项目代码分层