JDBC相关(二):数据库连接池技术原理,使用详解和常见的数据库连接池

来源:互联网 发布:淘宝闲鱼怎么搜索 编辑:程序博客网 时间:2024/05/21 22:57

前言:
       对于一个简单的数据库应用,由于对于数据库的访问不是很频繁。这时可以简单地在需要访问数据库时,就新创建一个连接,用完后就关闭它,这样做也不会带来什么明显的性能上的开销。
       但是对于一个复杂的数据库应用,情况就完全不同了。频繁的建立、关闭连接,会极大的减低系统的性能,因为对于连接的使用成了系统性能的瓶颈。
       连接复用:通过建立一个数据库连接池以及一套连接使用管理策略,使得一个数据库连接可以得到高效、安全的复用,避免了数据库连接频繁建立、关闭的开销。
对于共享资源,有一个很著名的设计模式:资源池。该模式正是为了解决资源频繁分配、释放所造成的问题的。把该模式应用到数据库连接管理领域,就是建立一个数据库连接池,提供一套高效的连接分配、使用策略,最终目标是实现连接的高效、安全的复用。
       数据库连接池的基本原理是在内部对象池中维护一定数量的数据库连接,并对外暴露数据库连接获取和返回方法。

1.数据库连接池概念,原理

1.1什么是数据库连接池:

官方:数据库连接池(Connection pooling)是程序启动时建立足够的数据库连接,并将这些连接组成一个连接池,由程序动态地对池中的连接进行申请,使用,释放。
个人理解:创建数据库连接是一个很耗时的操作,也容易对数据库造成安全隐患。所以,在程序初始化的时候,集中创建多个数据库连接,并把他们集中管理,供程序使用,可以保证较快的数据库读写速度,还更加安全可靠。
基本思想:为数据库连接建立一个“缓冲池”。预先在缓冲池中放入一定数量的连接,当需要建立数据库连接时,只需从“缓冲池”中取出一个,使用完毕之后再放回去。我们可以通过设定连接池最大连接数来防止系统无尽的与数据库连接。更为重要的是我们可以通过连接池的管理机制监视数据库的连接的数量﹑使用情况,为系统开发﹑测试及性能调整提供依据。

数据库连接池示意图:

1.2 数据库连接池的运行机制

(1) 程序初始化时创建连接池
(2) 使用时向连接池申请可用连接
(3) 使用完毕,将连接返还给连接池
(4) 程序退出时,断开所有连接,并释放资源

1.3 几种常用的数据库连接池

(1)DBCP (Database Connection Pool)

是一个依赖Jakarta commons-pool对象池机制的数据库连接池,Tomcat的数据源使用的就是DBCP。目前 DBCP 有两个版本分别是 1.3 和 1.4。1.3 版本对应的是 JDK 1.4-1.5 和 JDBC 3,而1.4 版本对应 JDK 1.6 和 JDBC 4。因此在选择版本的时候要看看你用的是什么 JDK 版本了,功能上倒是没有什么区别。

(2)C3P0

是一个开放源代码的JDBC连接池,它在lib目录中与Hibernate一起发布,包括了实现jdbc3和jdbc2扩展规范说明的Connection 和Statement 池的DataSources 对象。

(3)Proxool

是一个Java SQL Driver驱动程序,提供了对你选择的其它类型的驱动程序的连接池封装。可以非常简单的移植到现存的代码中。完全可配置。快速,成熟,健壮。可以透明地为你现存的JDBC驱动程序增加连接池功能

(4)BoneCP

是一个开源的快速的 JDBC 连接池。BoneCP很小,只有四十几K(运行时需要log4j和Google Collections的支持,这二者加起来就不小了),而相比之下 C3P0 要六百多K。另外个人觉得 BoneCP 有个缺点是,JDBC驱动的加载是在连接池之外的,这样在一些应用服务器的配置上就不够灵活。当然,体积小并不是 BoneCP 优秀的原因,BoneCP 到底有什么突出的地方呢,请看看性能测试报告。

2.数据库连接池的使用:

该博客使用C3P0数据库连接池技术,依赖的JAR包为:
这里写图片描述

点此处下载C3P0的JAR包

其次将jar包导入到工程当中,然后就可以使用cp30了。

2.1池参数(所有池参数都有默认值):

    初始大小:10个    最小空闲连接数:3个    增量:一次创建的最小单位(5个)    最大空闲连接数:12个    最大连接数:20个    最大的等待时间:1000毫秒

2.2 四大连接参数

连接池也是使用四大连接参数来完成创建连接对象!

2.3 实现的接口

    连接池必须实现:javax.sql.DataSource接口!    Java为数据库连接池提供了公共的接口:javax.sql.DataSource,各个厂商可以让自己的连接池实现这个接口。这样应用程序可以方便的切换不同厂商的连接池!

2.4自定义数据库连接池:

  • 分析:ItcastPool需要有一个List,用来保存连接对象。在ItcastPool的构造器中创建5个连接对象放到List中!当用人调用了ItcastPool的getConnection()时,那么就从List拿出一个返回。当List中没有连接可用时,抛出异常。
  • 我们需要对Connection的close()方法进行增强,所以我们需要自定义ItcastConnection类,对Connection进行装饰!即对close()方法进行增强。因为需要在调用close()方法时把连接“归还”给池,所以ItcastConnection类需要拥有池对象的引用,并且池类还要提供“归还”的方法。

这里写图片描述

ItcastPool.java:

public class ItcastPool implements DataSource {    private static Properties props = new Properties();    private List<Connection> list = new ArrayList<Connection>();    //静态代码块,项目启动时执行,读取数据库驱动    static {        InputStream in = ItcastPool.class.getClassLoader()                .getResourceAsStream("dbconfig.properties");        try {            props.load(in);            Class.forName(props.getProperty("driverClassName"));        } catch (Exception e) {            throw new RuntimeException(e);        }    }//构造函数,创建对象时被系统调用,创建5个链接对象    public ItcastPool() throws SQLException {        for (int i = 0; i < 5; i++) {            Connection con = DriverManager.getConnection(                    props.getProperty("url"), props.getProperty("username"),                    props.getProperty("password"));            ItcastConnection conWapper = new ItcastConnection(con, this);            list.add(conWapper);                }    }    //添加连接对象    public void add(Connection con) {        list.add(con);    }    //获取连接对象,项目每获取一个连接对象,连接池中remove一个连接对象    public Connection getConnection() throws SQLException {        if(list.size() > 0) {            return list.remove(0);        }        throw new SQLException("没连接了");    }    ......}

ItcastConnection.java:

public class ItcastConnection extends ConnectionWrapper {    private ItcastPool pool;    public ItcastConnection(Connection con, ItcastPool pool) {        super(con);        this.pool = pool;    }    @Override    //重写close方法,项目每关闭一个connection,连接池增加一个connection;    public void close() throws SQLException {        pool.add(this);    }}

2.5 C3P0连接池的使用:

(1)C3P0中池类是:ComboPooledDataSource:

不使用配置文件:

public void fun1() throws PropertyVetoException, SQLException {        ComboPooledDataSource ds = new ComboPooledDataSource();        ds.setJdbcUrl("jdbc:mysql://localhost:3306/mydb1");        ds.setUser("root");        ds.setPassword("123");        ds.setDriverClass("com.mysql.jdbc.Driver");        ds.setAcquireIncrement(5);        ds.setInitialPoolSize(20);        ds.setMinPoolSize(2);        ds.setMaxPoolSize(50);        Connection con = ds.getConnection();        System.out.println(con);        con.close();    }

(2)c3p0指定配置文件,而且配置文件可以是properties,也可骒xml的。当然xml的高级一些了。但是c3p0的配置文件名必须为c3p0-config.xml,并且必须放在类路径下。
使用配置文件的使用方法如下:

配置文件:

<?xml version="1.0" encoding="UTF-8"?><c3p0-config>    <default-config>        <property name="jdbcUrl">jdbc:mysql://localhost:3306/mydb1</property>        <property name="driverClass">com.mysql.jdbc.Driver</property>        <property name="user">root</property>        <property name="password">123</property>        <property name="acquireIncrement">3</property>        <property name="initialPoolSize">10</property>        <property name="minPoolSize">2</property>        <property name="maxPoolSize">10</property>    </default-config>    <named-config name="oracle-config">        <property name="jdbcUrl">jdbc:mysql://localhost:3306/mydb1</property>        <property name="driverClass">com.mysql.jdbc.Driver</property>        <property name="user">root</property>        <property name="password">123</property>        <property name="acquireIncrement">3</property>        <property name="initialPoolSize">10</property>        <property name="minPoolSize">2</property>        <property name="maxPoolSize">10</property>    </named-config></c3p0-config>

c3p0的配置文件中可以配置多个连接信息,可以给每个配置起个名字,这样可以方便的通过配置名称来切换配置信息。上面文件中默认配置为mysql的配置,名为oracle-config的配置也是mysql的配置。

MySql的使用:

public void fun2() throws PropertyVetoException, SQLException {        ComboPooledDataSource ds = new ComboPooledDataSource();        Connection con = ds.getConnection();        System.out.println(con);        con.close();    }

Orcale数据库的使用:

    public void fun2() throws PropertyVetoException, SQLException {        ComboPooledDataSource ds = new ComboPooledDataSource("orcale-config");        Connection con = ds.getConnection();        System.out.println(con);        con.close();    }

点此处下载C3P0的JAR包

原创粉丝点击