JDBC连接池的简单实现

先说明一下,我本身是做android开发的,java web是我的弱项,只是近来京东云免费,于是去折腾了几下,有了些许经验,特作分享。如果文章中内容有误,还请各高手指正。

我在web端,需要连接数据库进行查询插入等操作,但是每次进行操作都先获取连接用完后就断开的话,未免效率太低。以前知道tomcat中可以配置,但是京东云引擎的tomcat并不能由自己配置。因为我折腾的东西较小,所以也不考虑使用框架,于是就想自己写一个。

我写的连接池很简单,在初始化时创建5个连接,并放在一个列表当中。如果要获取连接,从列表中获取,同时列表移除,还回来时,列表添加上。也就是列表保存的是闲置的连接。

如果列表已经为空了,那么判断是否超过最大连接了,没有就创建,有的话就等待。当然,我这里做的是很简单的实现,所以没有去做等待超时等处理。

代码如下:

package com.githang.tucao.web.dbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.LinkedList;

public class DatabaseConnection {
    private static final String CREATE_TABLE_TWITTER = "CREATE TABLE IF NOT EXISTS twitter (id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY, msg varchar(300) not null) DEFAULT CHARSET=utf8";
    final static String HOST = "host";
    final static String PORT = "port";
    final static String DB_NAME = "dbname";
    final static String USERNAME = "username";
    final static String PASSWORD = "password";
    final static String url = "jdbc:mysql://" + HOST + ":" + PORT + "/" + DB_NAME
            + "?useUnicode=true&characterEncoding=utf-8";
    private static final DatabaseConnection instance = new DatabaseConnection();
    private final int INIT_COUNT = 5;
    private final int MAX_COUNT = 30;
    private int count = 0;

    private final Object wait = new Object();

    private  LinkedList<Connection> CONN_POOL;

    private DatabaseConnection() {
        CONN_POOL = new LinkedList<Connection>();
        try {
            Class.forName("com.mysql.jdbc.Driver");
            for (int i = 0; i < INIT_COUNT; i++) {
                Connection connection = createConnection();
                if(connection != null) {
                    CONN_POOL.add(createConnection());
                    count++;
                }
            }
     //       Connection connection = getConnection();
     //       Statement stmt = connection.createStatement();
     //       stmt.execute(CREATE_TABLE_TWITTER);
     //       stmt.execute("set names 'utf-8'");
     //       stmt.close();
     //       releaseConnection(connection);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static DatabaseConnection getInstance() {
        return instance;
    }

    private static Connection createConnection() {
        try {
            return DriverManager.getConnection(url, USERNAME, PASSWORD);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    public Connection getConnection() {
        synchronized (CONN_POOL) {
            while(CONN_POOL.size() > 0) {
                Connection conn = CONN_POOL.removeLast();
                try {
                    if(conn.isValid(1000)) {
                        return conn;
                    } else {
                        count--;
                    }
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(count < MAX_COUNT) {
                count++;
                return createConnection();
            }
            synchronized (wait) {
                try {
                    wait.wait(3000);
                    if(CONN_POOL.size() > 0) {
                        return CONN_POOL.removeLast();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }

    public void releaseConnection(Connection connection) {
        CONN_POOL.add(connection);
        synchronized (wait) {
            wait.notify();
        }
    }

}

其中count用于保存当前连接数(包括闲置和在使用的)。

wait对象用于线程同步锁,主要是获取不到连接并且需要等其他连接被还回来时使用,在getConnection()里面调用 wait,而在releaseConnection()方法中,也就是释放连接时,调用 notify通知其他等待的线程。

另外,在公用的数据库当中,数据库连接通常是不作长连接的。所以在这里连接池中的连接,可能是已经断开的或者是无效的,所以在获取连接时需要判断一下当前拿到的连接是否还有效。没有的话就拿下一个。

JDBC连接池的简单实现

时间: 2024-10-12 17:01:20

JDBC连接池的简单实现的相关文章

数据层优化-jdbc连接池简述、druid简介

终于回到既定轨道上了,这一篇讲讲数据库连接池的相关知识,线程池以后有机会再结合项目单独写篇文章(自己给自己挖坑,不知道什么时候能填上),从这一篇文章开始到本阶段结束的文章都会围绕数据库和dao层的优化去写,本篇是一个开始.本文会介绍连接池技术并对比目前比较流行的java连接池技术,之后,会把druid整合到项目中来,将技术方案落地,实际整合到项目中,让技术能为我所用. 使用连接池的原因 jdbc的demo //第一步,注册驱动程序 //com.MySQL.jdbc.Driver Class.fo

号称性能最好的JDBC连接池:HikariCP

HikariCP号称是现在性能最好的JDBC连接池组件,具体的性能到底如何,我也没有仔细的测试过,不过从它现在的发展来看,其可能确实如它宣传的那样其性能高过目前所有的连接池组件.之前对连接池的记忆一直都是C3P0.DBCP.BoneCP,这三者中BoneCP的性能是最好的,C3P0的性能在现在来说确实是非常差的了,好像C3P0很久都没有更新了,所以我们应该杜绝在项目中使用C3P0,至于是否要使用HikariCP,我觉得可以尝试.HikariCP毕竟是才出来不久,其性能到底如何,也需要实践的检验,

使用了Tomcat JDBC连接池不能重连的问题

在项目中用到了tomcat 的jdbc连接池,发现一个问题是,当数据库重启时,服务没有重新的去连接数据库,需要将部署的项目重新启动才能连接到数据库.经过测试对配置做一下修改: 在配置dataSource的地方加入两个配置属性: <property name="testOnBorrow" value="true"/> <!--在连接返回给调用者前用于校验连接是否有效的SQL语句,如果指定了SQL语句,则必须为一个SELECT语句,且至少有一行结果--

JDBC连接池C3P0

连接池 1)传统方式找DriverManager要连接,数目是有限的. 2)传统方式的close(),并没有将Connection重用,只是切断应用程序和数据库的桥梁,即无发送到SQL命令到数据库端执行 3)项目中,对于Connection不说,不会直接使用DriverManager取得,而使用连接池方式. 4)DBCP和C3P0,都是Java开源的,都必须直接或间接实现javax.sql.DataSource接口 5)DBCP连接池需要dbcp.properties文件,同时需加入3个对应的j

JDBC连接池概述

Reference Source:https://www.progress.com/tutorials/jdbc/jdbc-jdbc-connection-pooling 介绍 本文档提供的信息旨在帮助开发人员为必须处理连接池的应用程序提供连接池策略. 首先, 本文档提供 jdbc 3.0 规范指定的 jdbc 连接池概述. 接下来, 它提供了一些示例, 说明如何使用 DataDirect 连接池管理器 (它随 DataDirect Connect?用于jdbc 和 DataDirect Seq

Spring boot (11) tomcat jdbc连接池

默认连接池 tomcat jdbc是从tomcat7开始推出的一个连接池,相比老的dbcp连接池要优秀很多,spring boot将tomcat jdbc作为默认的连接池,只要在pom.xml中引入了spring boot的jdbc组件,就会自动引入tomcat jdbc连接池. 默认参数 以下是org.apache.tomcat.jdbc.pool.PoolProperties源码,这是tomcat jdbc连接池的默认初始参数.这个类实现了一个接口PoolConfiguration,查看这个

java 连接池的简单实现

最近一个项目中需要自己写个连接池, 写了一个下午,挺辛苦的,但不知道会不会出问题, 所以,贴到博客上,欢迎各路大神指点 1. 配置信息: /** * */ package cn.mjorcen.db.bean; import java.util.ResourceBundle; import org.apache.log4j.Logger; /** * * 配置信息 * * @author mjorcen * @email [email protected] * @dateTime Oct 5,

【转帖】置高并发jdbc连接池

简单的MySQL连接池 [html] view plaincopy <Resource type="javax.sql.DataSource" name="jdbc/TestDB" factory="org.apache.tomcat.jdbc.pool.DataSourceFactory" driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://lo

开源JDBC连接池DBCP和C3P0配置(转)

现在Tomcat下使用的是公司框架默认的 Apache DBCP连接池.此种连接池虽出自名门Apache基金会.但口碑不是很好,在新版的Hibernate中已经放弃了对DBCP的支持,取而代之的是 C3P0.开始我还对DBCP抱有希望,加上各种参数设置,但均无效.后来换上了C3P0,使用其testConnectionOnCheckout. testConnectionOnCheckin参数配置后果然一剑封喉的解决了问题.(说明:此种办法其实会带来一定的性能损耗)一.DBCP和C3P0连接池常用配