java设计思想-池化-手写数据库连接池

 

池:同一类对象集合

连接池的作用 
1. 资源重用 
由于数据库连接得到重用,避免了频繁创建、释放连接引起的大量性能开销。在减少系统消耗的基础上,另一方面也增进了系统运行环境的平稳性(减少内存碎片以及数据库临时进程 / 线程的数量)。 
2. 更快的系统响应速度 
数据库连接池在初始化过程中,往往已经创建了若干数据库连接置于池中备用。此时连接的初始化工作均已完成。对于业务请求处理而言,直接利用现有可用连接,避免了数据库连接初始化和释放过程的时间开销,从而缩减了系统整体响应时间。 
3. 新的资源分配手段 
对于多应用共享同一数据库的系统而言,可在应用层通过数据库连接的配置,使用数据库连接池技术。设置某一应用最大可用数据库连接数,避免某一应用独占所有数据库资源。 
4. 统一的连接管理,避免数据库连接泄漏 
在较为完备的数据库连接池实现中,可根据预先设定的连接占用超时时间,强制收回被超时占用的连接。从而避免了常规数据库连接操作中可能出现的资源泄漏(当程序存在缺陷时,申请的连接忘记关闭,这时候,就存在连接泄漏了)。

示例

配置文件

jdbcDriver=com.mysql.jdbc.Driver
jdbcurl=jdbc:mysql://localhost:3306/mybatis
userName=root
password=root
initCount=10
stepSize=4
poolMaxSize=150

 

数据库连接封装

public class PooledConnection {
    private boolean isBusy = false;
    private Connection connection;
<span class="hljs-keyword">public</span> Connection <span class="hljs-title function_">getConnection</span><span class="hljs-params">()</span> {
    <span class="hljs-keyword">return</span> connection;
}

<span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">setConnection</span><span class="hljs-params">(Connection connection)</span> {
    <span class="hljs-built_in">this</span>.connection = connection;
}

<span class="hljs-keyword">public</span> <span class="hljs-type">boolean</span> <span class="hljs-title function_">isBusy</span><span class="hljs-params">()</span> {
    <span class="hljs-keyword">return</span> isBusy;
}

<span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">setBusy</span><span class="hljs-params">(<span class="hljs-type">boolean</span> isBusy)</span> {
    <span class="hljs-built_in">this</span>.isBusy = isBusy;
}

<span class="hljs-keyword">public</span> <span class="hljs-title function_">PooledConnection</span><span class="hljs-params">(Connection connection, <span class="hljs-type">boolean</span> isBusy)</span> {
    <span class="hljs-built_in">this</span>.connection = connection;
    <span class="hljs-built_in">this</span>.isBusy = isBusy;
}

<span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">close</span><span class="hljs-params">()</span> {
    <span class="hljs-built_in">this</span>.isBusy = <span class="hljs-literal">false</span>;
}

<span class="hljs-keyword">public</span> ResultSet <span class="hljs-title function_">queryBysql</span><span class="hljs-params">(String sql)</span> {
    <span class="hljs-type">Statement</span> <span class="hljs-variable">sm</span> <span class="hljs-operator">=</span> <span class="hljs-literal">null</span>;
    java.sql.<span class="hljs-type">ResultSet</span> <span class="hljs-variable">rs</span> <span class="hljs-operator">=</span> <span class="hljs-literal">null</span>;

    <span class="hljs-keyword">try</span> {
        sm = connection.createStatement();
        rs = sm.executeQuery(sql);
    } <span class="hljs-keyword">catch</span> (SQLException e) {
        e.printStackTrace();
    }

    <span class="hljs-keyword">return</span> rs;
}

}

 

 

连接池接口

public interface IMyPool {
<span class="hljs-function">PooledConnection <span class="hljs-title">getConnection</span>()</span>;

<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">createConnection</span>(<span class="hljs-params"><span class="hljs-built_in">int</span> count</span>)</span>;

}

 

 

实现

import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;
import java.util.Vector;

public class MyPoolImpl implements IMyPool {

<span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-type">String</span> <span class="hljs-variable">jdbcDriver</span> <span class="hljs-operator">=</span> <span class="hljs-literal">null</span>;
<span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-type">String</span> <span class="hljs-variable">jdbcUrl</span> <span class="hljs-operator">=</span> <span class="hljs-literal">null</span>;
<span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-type">String</span> <span class="hljs-variable">userName</span> <span class="hljs-operator">=</span> <span class="hljs-literal">null</span>;
<span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-type">String</span> <span class="hljs-variable">password</span> <span class="hljs-operator">=</span> <span class="hljs-literal">null</span>;

<span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-type">int</span> initCount;

<span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-type">int</span> stepSize;

<span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-type">int</span> poolMaxSize;

<span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> Vector&lt;PooledConnection&gt; pooledConnections = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Vector</span>&lt;&gt;();

<span class="hljs-keyword">public</span> <span class="hljs-title function_">MyPoolImpl</span><span class="hljs-params">()</span> {

    init();
}

<span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">init</span><span class="hljs-params">()</span> {

    <span class="hljs-type">InputStream</span> <span class="hljs-variable">inputStream</span> <span class="hljs-operator">=</span> <span class="hljs-built_in">this</span>.getClass().getClassLoader().getResourceAsStream(<span class="hljs-string">"jdbc.properties"</span>);

    <span class="hljs-comment">//字节信息 key value 形式化</span>
    <span class="hljs-type">Properties</span> <span class="hljs-variable">pro</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Properties</span>();
    <span class="hljs-keyword">try</span> {
        pro.load(inputStream);
    } <span class="hljs-keyword">catch</span> (IOException e) {
        e.printStackTrace();
    }

    jdbcDriver = pro.getProperty(<span class="hljs-string">"jdbcDriver"</span>);
    jdbcUrl = pro.getProperty(<span class="hljs-string">"jdbcurl"</span>);
    userName = pro.getProperty(<span class="hljs-string">"userName"</span>);
    password = pro.getProperty(<span class="hljs-string">"password"</span>);

    initCount = Integer.valueOf(pro.getProperty(<span class="hljs-string">"initCount"</span>));
    stepSize = Integer.valueOf(pro.getProperty(<span class="hljs-string">"stepSize"</span>));
    poolMaxSize = Integer.valueOf(pro.getProperty(<span class="hljs-string">"poolMaxSize"</span>));

    <span class="hljs-keyword">try</span> {
        <span class="hljs-type">Driver</span> <span class="hljs-variable">mysqlDriver</span> <span class="hljs-operator">=</span> (Driver) Class.forName(jdbcDriver).newInstance();

        DriverManager.registerDriver(mysqlDriver);

        createConnection(initCount);

    } <span class="hljs-keyword">catch</span> (IllegalAccessException e) {
        e.printStackTrace();
    } <span class="hljs-keyword">catch</span> (InstantiationException e) {
        e.printStackTrace();
    } <span class="hljs-keyword">catch</span> (SQLException e) {
        e.printStackTrace();
    } <span class="hljs-keyword">catch</span> (ClassNotFoundException e) {
        e.printStackTrace();
    }


}


<span class="hljs-keyword">public</span> PooledConnection <span class="hljs-title function_">getConnection</span><span class="hljs-params">()</span> {
    <span class="hljs-keyword">if</span> (pooledConnections.size() == <span class="hljs-number">0</span>) {
        System.out.println(<span class="hljs-string">"获取链接管道失败,原因是连接池中没有可用管道"</span>);
        <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">RuntimeException</span>(<span class="hljs-string">"创建管道对象失败,原因是即将超过最大上限值"</span>);
    }
    <span class="hljs-comment">//连接池中的管道是没有超时  没有其他线程占用</span>
    <span class="hljs-type">PooledConnection</span> <span class="hljs-variable">connection</span> <span class="hljs-operator">=</span> getRealConnection();

    <span class="hljs-keyword">while</span> (connection == <span class="hljs-literal">null</span>) {
        createConnection(stepSize);
        connection = getRealConnection();
        <span class="hljs-keyword">try</span> {
            Thread.sleep(<span class="hljs-number">300</span>);
        } <span class="hljs-keyword">catch</span> (InterruptedException e) {
            e.printStackTrace();
        }
    }
    <span class="hljs-keyword">return</span> connection;
}

<span class="hljs-meta">@Override</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">createConnection</span><span class="hljs-params">(<span class="hljs-type">int</span> count)</span> {
    <span class="hljs-keyword">if</span> (poolMaxSize &gt; <span class="hljs-number">0</span> &amp;&amp; pooledConnections.size() + count &gt; poolMaxSize) {
        System.out.println(<span class="hljs-string">"创建管道对象失败,原因是即将超过最大上限值"</span>);
        <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">RuntimeException</span>(<span class="hljs-string">"创建管道对象失败,原因是即将超过最大上限值"</span>);
    }

    <span class="hljs-keyword">for</span> (<span class="hljs-type">int</span> <span class="hljs-variable">i</span> <span class="hljs-operator">=</span> <span class="hljs-number">0</span>; i &lt; count; i++) {
        <span class="hljs-keyword">try</span> {
            <span class="hljs-type">Connection</span> <span class="hljs-variable">conn</span> <span class="hljs-operator">=</span> DriverManager.getConnection(jdbcUrl, userName, password);

            <span class="hljs-type">PooledConnection</span> <span class="hljs-variable">pooledConnection</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">PooledConnection</span>(conn, <span class="hljs-literal">false</span>);
            pooledConnections.add(pooledConnection);
        } <span class="hljs-keyword">catch</span> (SQLException e) {
            e.printStackTrace();
        }

    }
}

<span class="hljs-keyword">private</span> <span class="hljs-keyword">synchronized</span> PooledConnection <span class="hljs-title function_">getRealConnection</span><span class="hljs-params">()</span> {
    <span class="hljs-keyword">for</span> (PooledConnection conn : pooledConnections) {
        <span class="hljs-keyword">if</span> (!conn.isBusy()) {
            <span class="hljs-type">Connection</span> <span class="hljs-variable">connection</span> <span class="hljs-operator">=</span> conn.getConnection();
            <span class="hljs-keyword">try</span> {

                <span class="hljs-comment">//发送一个信息给数据库 2000毫秒内  收到返回信息 认为 这个管道没有超时</span>
                <span class="hljs-keyword">if</span> (!connection.isValid(<span class="hljs-number">2000</span>)) {
                    <span class="hljs-type">Connection</span> <span class="hljs-variable">validConn</span> <span class="hljs-operator">=</span> DriverManager.getConnection(jdbcUrl, userName, password);
                    conn.setConnection(validConn);
                }
            } <span class="hljs-keyword">catch</span> (SQLException e) {
                e.printStackTrace();
            }
            conn.setBusy(<span class="hljs-literal">true</span>);
            <span class="hljs-keyword">return</span> conn;
        }
    }
    <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
}

}

 

 

连接池管理

public class PoolManager {
<span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">createPool</span> {

    <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-type">MyPoolImpl</span> <span class="hljs-variable">poolImpl</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">MyPoolImpl</span>();

}

<span class="hljs-comment">/**
 * 内部类单利模式产生使用对象
 * <span class="hljs-doctag">@return</span>
 */</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> MyPoolImpl <span class="hljs-title function_">getInstance</span><span class="hljs-params">()</span> {
    <span class="hljs-keyword">return</span> createPool.poolImpl;
}

}

 

 

测试类

import java.sql.ResultSet;
import java.sql.SQLException;

public class MypoolTest {

<span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> MyPoolImpl poolImpl = PoolManager.getInstance();

<span class="hljs-function"><span class="hljs-keyword">public</span> synchronized <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">selctData</span>()</span> {
    PooledConnection connection = poolImpl.getConnection();
    ResultSet rs = connection.queryBysql(<span class="hljs-string">"SELECT * FROM user"</span>);
    <span class="hljs-keyword">try</span> {
        <span class="hljs-keyword">while</span> (rs.next()) {
            System.<span class="hljs-keyword">out</span>.println(rs.getString(<span class="hljs-string">"ID"</span>) + <span class="hljs-string">"\t\t"</span>);
            System.<span class="hljs-keyword">out</span>.println(rs.getString(<span class="hljs-string">"USERNAME"</span>) + <span class="hljs-string">"\t\t"</span>);
            System.<span class="hljs-keyword">out</span>.println(rs.getString(<span class="hljs-string">"PASSWORD"</span>) + <span class="hljs-string">"\t\t"</span>);
            System.<span class="hljs-keyword">out</span>.println();
        }
        rs.close();
        connection.close();
    } <span class="hljs-keyword">catch</span> (SQLException e) {
        e.printStackTrace();
    }

}

<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span>(<span class="hljs-params">String[] args</span>)</span> {
    <span class="hljs-keyword">for</span> (<span class="hljs-built_in">int</span> i = <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">1500</span>; i++) {
        <span class="hljs-keyword">new</span> Thread(<span class="hljs-keyword">new</span> Runnable() {
            @Override
            <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">run</span>()</span> {
                selctData();
            }
        }).start();
    }
}

}