MySQL中连接池的技术实现和分析

为什么必须使用数据库连接池:
使用连接池和不使用连接池的区别在哪里?上
普通的JDBC数据库连接(Connection对象)使用 DriverManager 来获取,每次向数据库建立连接的时候都要将 Connection 加载到内存中,再验证用户名和密码(得花费0.05s~1s的时间)—->建立JDBC连接的开销(成本)是很多。
需要数据库连接的时候,就向数据库要求一个,执行完成后再断开连接。这样的方式将会消耗大量的资源和时间。
数据库的连接资源并没有得到很好的重复利用.若同时有几百人甚至几千人在线,频繁的进行数据库连接操作将占用很多的系统资源,严重的甚至会造成服务器的崩溃。
对于每一次数据库连接,使用完后都得断开。否则,如果程序出现异常而未能关闭,将会导致数据库系统中的内存泄漏,最终将导致重启数据库。
这种开发不能控制被创建的连接对象数,系统资源会被毫无顾及的分配出去,如连接过多,也可能导致内存泄漏,服务器崩溃.
连接池最大的好处: 重复利用了每一个Connection对象,节省了性能开销.

连接池概述:
在Java中,连接池使用javax.sql.DataSource接口来表示连接池/数据源.
注意:DataSource和JDBC一样仅仅只是一个接口,由各大服务器厂商来实现(Tomcat,JBoss等).

DataSource(数据源)和连接池(Connection Pool)是同一个.


如何获取连接对象:
没有连接池: 通过DriverManager来获取,直接和DBMS连接.
存在连接池: 直接通过连接池来获取连接对象.
Connection conn = DataSource对象.getConnection();

释放连接对象:
没有连接池: conn.close():和数据库服务器(DBMS)断开连接.
存在连接池: conn.close():把Connection对象归还给连接池,并没有和DBMS断开.

接下来介绍主流的几个连接池项目之一
DBCP连接池和Druid连接池对比:

常用的DataSource的实现:
C3P0: Hibernate推荐的,但是该连接池在07年之后就不再更新了,不建议使用:性能太太差了.
DBCP: Apache组织的项目,Spring推荐的. 真心不错.
Druid连接池(德鲁伊),阿里巴巴的连接池,世界上最好的连接池.
https://github.com/alibaba/druid/wiki
Java语言领域性能最好的数据库连接池//性能超群
类似于DBCP连接池.
连接池(Connection pool)管理连接Connection对象
数据源(DataSource)用来连接数据库,创建连接Connection对象

另外要提及的一点是:Druid和DBCP的连接属性是完全相同的,创建连接池的对象不同.

DBCP和Druid连接池使用代码如下除了几条语句不一样之外,其他代码都一样:

public class DBCPTestDemo {
    /**
     *使用dbcp连接池来做操作   需要添加2个jar包
     * commons-dbcp.jar
     * commons-poor.jar
     * 使用Druid连接池做操作   需添加的jar包
     * druid.jar
     * 连接池连接数据库  然后客户端从连接池中获取连接对象
     * 这里记得方法后可以传入一个URL参数  这里就不传入直接设置URL做测试
     */
    @Test
    public void testDruid() throws Exception {
        String sql = "SELECT * FROM t_student";

//BasicDataSource dataSource = new BasicDataSource();//DBCP

 DruidDataSource dataSource = new DruidDataSource();//Druid

  //以上是二种不同连接池下的DataSource对象获取区别
        dataSource.setUsername("root");
        dataSource.setPassword("admin");
        dataSource.setUrl("jdbc:mysql:///jdbc");
        Connection conn = dataSource.getConnection();
        //利用datasource连接池对象中的getConnection()方法获取Connection连接对象.
        PreparedStatement ps = conn.prepareStatement(sql);
        ResultSet set = ps.executeQuery();
        while (set.next()) {
            long id = set.getLong("id");
            String name = set.getString("name");
            int age = set.getInt("age");
            System.out.println("id=" + id  + "name=" + name + "age=" + age );
        }
        jdbcUtil.close(conn, ps, set);
    }
}   

拓展:利用properties文件来解决硬编码问题,将数据库连接池的属性内容存于此文件中.

DBCP的properties文件代码(Druid连接池的properties文件属性一致):

driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql:///jdbc
username=root
password=admin
maxActive=5//此值是设置连接池的最大连接数

将获取连接池中的Connection对象封装成为一个Util工具类:

public class DruidUtil {
private static DataSource dataSource;
 static{
 try {
    Properties p = new Properties();
ClassLoader loader = Thread.currentThread().getContextClassLoader();
InputStream input = loader.getResourceAsStream("druid.properties");
p.load(input);
//以下是二种不同连接池获取Datasource对象的区别对比:
//dataSource = BasicDataSourceFactory.createDataSource(p);//DBCP

  dataSource = DruidDataSourceFactory.createDataSource(p);//Druid

//对比以上二条代码,比较可以看出DBCP连接池和Druid连接池获取datasource对象的方式别无差异
        } catch (Exception e) {
            throw new RuntimeException("加载classpath根路径下的dbcp.properties文件失败",e);
        }

    }
        public static Connection getConn()
        {
        try {
            return dataSource.getConnection();
            } catch (Exception e) {
            throw new RuntimeException("数据库连接异常",e);
            }
        }
            public static void close(Connection conn, Statement st, ResultSet res) {

        //释放资源Util抽取
        try {
            if (st != null) {
                st.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            try {
                if (conn != null) {
                    conn.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

附上数据库连接池的测试

测试执行申请归还连接1,000,000(一百万)次总耗时性能对比。

Java6的环境下:
Java6下连接池测试

Java7的环境下:
Java7下连接池测试

结论1.Druid是性能最好的数据库连接池,tomcat-jdbc和druid性能接近。
2.proxool在激烈并发时会抛异常,完全不靠谱。
3.c3p0和proxool都相当慢,慢到影响sql执行效率的地步。
4.bonecp性能并不优越,采用LinkedTransferQueue并没有能够获得性能提升。
5.除了bonecp,其他的在JDK 7上跑得比JDK 6上快
6.jboss-datasource虽然稳定,但是性能很糟糕

而且可以目前的所有的数据库连接池中Druid还提供更新支持,以及有很多强大的功能,例如SQL语句检查和日志分析功能等.反正以后就使用Druid连接池就可以了,即使当前你企业的连接池配置是DBCP以及其他的,也能很快的转配成Druid的.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值