java写一个简单的jdbc数据库连接池

                                   java写一个简单的jdbc数据库连接池

 

一、实现原理

1、声明一个静态的变量 public static Vector<Connection> pools

2、将获取到的 java.sql.Connection 对象添加到 pools 中

3、获取的 Connection 对象将 Vector 池中移除

4、释放资源将Connection对象放回 Vector 池中

 

二、代码实现

1、写一个简单的连接池 PoolUtils.java

package com.xx.xx;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Vector;
/**
* @description: 写一个简单的连接池
* @author w
* @date 2018年8月7日 16:50:54
*/
public class PoolUtils {
    private static Vector<Connection> pools ;
    private static Integer poolSize = 10 ;
    private static PoolUtils instance ;
    public static final String URL = "jdbc:mysql://localhost:3306/chapter";
    public static final String USER = "root";
    public static final String PWD = "123";

    /**
    * 构造方法私有化,避免外部 直接new 获取当前对象实例。
    */
    private PoolUtils() {
        init();
    }

    /**
    * 获取当前类石例 --- 单例 懒汉式
    * @return
    */
    public synchronized static PoolUtils getInstance(){
        if(null == instance){
            instance = new PoolUtils();
        }
        return instance;
    }

    /**
    * 初始化连接池
    */
    private void init(){
        pools=new Vector<>(poolSize);
        for (int i = 0; i < poolSize; i++) {
            Connection c = null;
            try {
                c = DriverManager.getConnection(URL,USER,PWD);
            } catch (SQLException e) {
                e.printStackTrace();
            }
            pools.add(c);
        }
    }

    /**
    * 获取一个连接对象
    * synchronized : 避免多线程环境下,同一个连接被获取多次
    * @return
    */
    public synchronized Connection getConnection(){
        if(pools.size() > 0){
            return pools.remove(0);
        }
        return null ;
    }

    /**
    * 释放链接资源
    * @param conn
    */
    public void release(Connection conn){
        if(conn != null){
            pools.add(conn);
        }
    }

    /**
    * 获取连接池剩余的连接数
    * @return
    */
    public static int getPoolsSize(){
        if(!pools.isEmpty()){
            return pools.size();
        }
        return 0;
    }

    /**
    * 直接获取连接,不使用连接池
    * @param i 站位 ,实现重载
    * @return
    */
    public static Connection getConnection(int i){
        try {
            Connection connection = DriverManager.getConnection(URL,USER,PWD);
            return connection;
        } catch (SQLException e) {
            e.printStackTrace();
        }
            return null ;
    }
}

 

三、测试 --- 连接池和直接获取连接

1、比较使用连接池和直接获取连接对象执行效率情况

package com.xx.xx;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* 针对数据库连接池获取连接和直接获取连接 执行查询情况,效率对比。
* @author w
*/
public class PoolTest {
    public static void main(String[] args) {
        // 执行查询的次数
        int sum = 100;
        long start = System.currentTimeMillis();
        poolsExecute(sum);
        System.out.println("使用连接池耗时:"+(System.currentTimeMillis()-start)+" ms");
        start = System.currentTimeMillis();
        connExecute(sum);
        System.out.println("直接获取连接耗时:"+(System.currentTimeMillis()-start)+" ms");
    }


    /**
    * 使用连接池,获取连接,执行查询
    * @param sum
    */
    private static void poolsExecute(int sum) {
        for (int i = 0; i < sum; i++) {
            Connection connection = PoolUtils.getInstance().getConnection();
            try {
                query(connection,sum);
            } catch (Exception e) {
                e.printStackTrace();
            }finally{
                // 释放资源
                PoolUtils.getInstance().release(connection);
            }
        }
    }

    /**
    * 直接获取连接,不使用连接池 执行查询
    * @param sum 占位符
    */
    private static void connExecute(int sum) {
        for (int i = 0; i < sum; i++) {
            Connection connection = PoolUtils.getConnection(sum);
            query(connection,sum);
            // 增加是否关闭连接,测试耗时情况
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    /**
    * 具体执行查询的方法
    * @param connection 数据库连接对象
    * @param sum 占位符
    */
    private static void query(Connection connection,int sum) {
        String sql = "SELECT * from client limit 1";
        try {
            PreparedStatement prepareStatement = connection.prepareStatement(sql);
            ResultSet resultSet = prepareStatement.executeQuery();
            while(resultSet.next()){
                String id = resultSet.getString("id");
                String name = resultSet.getString("name");
                // System.out.println("id :"+id + " name: "+name);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

 

四、测试结果

1、使用连接池耗时:1615 ms

2、直接获取连接耗时:5947 ms

3、结论: 连接池可以极大查询效率,避免每次都获取连接对象,从而造成资源浪费。 本连接池以极简的方式实现,便于理解。 因使用的jdk1.7 ,可以省略加载数据库驱动部分。(Class.forName("com.mysql.jdbc.Driver");)

4、可优化部分: 数据库资料改到配置文件中;测试连接池对象足够时,可开启多线程执行查询,充分利用资源。 本示例测试代码中,只用了连接池中一个连接对象。 。。。。 等等。。

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章