手写一个JDBC连接池

本文介绍了连接池的作用,强调其在性能和资源管理上的优势,并提供了自定义JDBC连接池的步骤,包括pom文件配置、jdbc.properties设置、DbBean设计、连接池创建、测试及运行结果。此外,还探讨了直接初始化连接数和归还连接的管理方式。
摘要由CSDN通过智能技术生成

1.连接池的作用

连接池一般比直接连接更有优越性,因为它提高了性能的同时还保存了宝贵的资源。在整个应用程序的使用过程,当中重复的打开直接连接将导致性能的下降。而池连接只在服务器启动时打开一次,从而消除了这种性能问题。
        连接池主要考虑的是性能,每次获取连接和释放连接都有很大的工作量,会对性能有很大影响;而对资源来说起的是反作用,因为保存一定数量的连接是要消耗内存的。应用程序每次从池里获得Connection对象,而不是直接从数据里获得,这样不占用服务器的内存资源。所以一般要建立连接池,而连接的数量要适当,不能太大,太大会过多消耗资源。(所以,考虑2个方面,一个是内存,另一个是资源)。 连接池就是为了避免重复多次的打开数据库连接而造成的性能的下降和系统资源的浪费。

目前Java中使用连接池的三种方式:
a.自定义连接池
b.使用第三方连接池
c.使用服务器自带的连接池

在自定义连接池的使用上,上网查看了不少案例,自己总结了一下,不多说直接上代码。

2.pom文件

<dependencies>
        <!--mysql的jdbc驱动jar包依赖-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>

        <!--lombok代码生成工具的jar包依赖-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.8</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
</dependencies>

3.jdbc.properties

jdbc.driverName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://192.168.234.131:3306/bas_db
jdbc.username=root
jdbc.password=@WSX1qaz
jdbc.poolName=jdbcThread
jdbc.minConnections=5
jdbc.maxConnections=10
jdbc.initConnections=2
jdbc.connTimeOut=1000

4.DbBean

import lombok.Data;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

@Data
public class DbBean {

    private  String driverName;

    private  String url;

    private  String userName ;

    private  String password ;

    private  String poolName ;// 连接池名字

    private  int minConnections; // 空闲池,最小连接数

    private  int maxConnections ; // 空闲池,最大连接数

    private  int initConnections ;// 初始化连接数

    private  long connTimeOut;// 重复获得连接的频率


    {
        readConfig();
    }

    private void readConfig() {
        InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("jdbc.properties");
        Properties prop = new Properties();
        if (null != inputStream){
            try {
                prop.load(inputStream);
                this.driverName = prop.getProperty("jdbc.driverName");
                this.url = prop.getProperty("jdbc.url");
                this.userName = prop.getProperty("jdbc.username");
                this.password = prop.getProperty("jdbc.password");
                this.poolName = prop.getProperty("jdbc.poolName");
                this.minConnections = Integer.parseInt(prop.getProperty("jdbc.minConnections"));
                this.maxConnections = Integer.parseInt(prop.getProperty("jdbc.maxConnections"));
                this.initConnections = Integer.parseInt(prop.getProperty("jdbc.initConnections"));
                this.connTimeOut = Long.parseLong(prop.getProperty("jdbc.connTimeOut"));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

5.创建连接池

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.List;
import java.util.Vector;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 连接池
 */
public class ConnectionPoolManager {

    //空闲线程
    private List<Connection> freeConnection = new Vector<Connection>();

    //活跃线程
    private List<Connection> activeConnection = new Vector<Connection>();

    //连接数
    private AtomicInteger connCount = new AtomicInteger();

    //DbBean
    private DbBean dbBean = new DbBean();

    public ConnectionPoolManager() {
        this.init();
    }

    /**
     * 初始化
     */
    private void init() {
        for (int i = 0; i <= dbBean.getInitConnections(); i++) {
            Connection conn = this.CreateConnection();
            if (null != conn) {
                freeConnection.add(conn);
            }
        }
    }

    /**
     * 创建连接
     *
     * @return
     */
    private Connection CreateConnection() {

        try {

            if (null == dbBean) {
                return null;
            }
            Class.forName(dbBean.getDriverName());
            Connection conn = DriverManager.getConnection(dbBean.getUrl(), dbBean.getUserName(), dbBean.getPassword());
            connCount.decrementAndGet();
            return conn;

        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 获取连接
     *
     * @return
     */
    public synchronized Connection getConnection() {

        Connection conn = null;
        try {
            //判断活跃线程是否大于等于最大连接数,大于等于则等待,
            if (activeConnection.size() >= dbBean.getMaxConnections()) {
                //大于等于,则等待
                wait(dbBean.getConnTimeOut());
                this.getConnection();
            } else {
                //小于
                //判断空闲线程数是否大于0,大于则直接从空闲线程中取
                if (freeConnection.size() > 0) {
                    //大于
                    conn = freeConnection.remove(0);
                } else {
                    //小于,则创建连接
                    conn = this.CreateConnection();
                }

                //判断连接是否有效
                if (isAvailable(conn)) {
                    //有效,放入活跃线程中
                    activeConnection.add(conn);
                } else {
                    conn = this.getConnection();
                }

            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return conn;
    }

    /**
     * 释放连接
     */
    public synchronized void releaseConnection(Connection conn) {

        if (!isAvailable(conn)) {
            return;
        }

        //判断空闲线程是否大于最小连接数,大于则关闭连接
        if (freeConnection.size() > dbBean.getMinConnections()) {
            //大于,直接关闭
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        } else {
            //小于,空闲线程加1
            freeConnection.add(conn);
            this.connCount.decrementAndGet();
        }

    }

    /**
     * 判断连接是否有效
     *
     * @param conn
     * @return
     */
    public boolean isAvailable(Connection conn) {

        try {

            if (null == conn || conn.isClosed()) {
                return false;
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return true;
    }
}

6.测试

import java.sql.Connection;
import java.sql.PreparedStatement;

public class test {
    public static void main(String[] args) {

        final ConnectionPo
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值