数据库连接池

 

  》数据库连接的建立及关闭极其耗资源,对系统性能影响尤为明显.

    》传统数据库连接方式:一个数据库连接均对应一个物理连接,每次操作都要打开、关闭该物理操作,这种频繁性,会造成系统性能下降,此时,考虑数据库连接池.

    》数据库连接池解决方案:当应用程序启动时,系统主动建立足够的连接(按指定的初始化数据),并将这些连接组成一个池.每次应用程序请求数据库连接时,无需重新打开连接,而是从池中取出已有的连接,使用完后,不再关闭,而是直接将该连接归还池,使用连接池,可大大提高系统运行效率.

    》数据库连接池介绍

    》 对于共享资源的情况,有一个通用的设计模式--资源池(Resource Pool),用于解决资源的频繁请求、释放所造成的性能下降.为解决数据库连接的这种频繁性,JDBC2.0规范引入了数据库连接池技术,实际上,数据库连接池是Connection对象的工厂,常用参数有:

    @数据库的初始连接数   @连接池的最大连接数   @连接池每次增加的连接数

    》连接池的工作示意图 {JDBC标准的API并没有提供连接池的实现,仅仅提供了DataSource接口具体的实现有一些厂商提供}

    》 连接池的分配与释放

    @程序启动,分配初始化数目的连接,按需分配,用过归还、超时归还,当申请时无或者达到指定的最小值,按增量参数值分配新的连接

    @为确保连接池中最小的连接数,通常有如下策略:

    :动态--定时检查连接池,一旦发现数量小于最小连接数,则补充相应的新连接,保证连接池正常运转

    :静态--空闲连接不足时,系统才检测是否达到最小连接

    》连接池的实现

    连接池通常包括连接池类(DBConnectionPool)和连接池管理类(DBConnectionPoolManager):

    》连接池类是某一数据库所有连接的缓冲池,主要实现功能:@从连接池获取或者创建可用连接,@使用完毕,归还给池连接,@系统关闭前,断开所有连接并释放连接占用的资源,@处理无效连接,@限制池中连接的数节目,介于最小值和最大值之间

    》连接池管理类是连接池类的包装类,该类采用单态模式设计,保证系统中只有一个实例,主要用于管理多个连接池对象,主要实现以下功能:@注册数据库驱动程序,@根据配置文件,创建连接池对象,@命名、管理连接池,@跟踪连接池的使用,需要时关闭并释放资源

    :数据库连接池的管理是个难点,管理不当,造成系统开销过大,将成为性能瓶颈.对于高并发的WEB应用,采用连接池技术效率和稳定性比传统的连接方式要好的多

    :并发问题--数据库必须考虑此问题,对于并发,Java语言提供管理并发的支持,使用synchronized关键字可确保方法线程的安全.故,DataSource的getConnection方法必须以该该关键字修饰

    public synchronized Connection getConnection(); //保证线程安全

    :事务处理--JDBC的Connection本身通过设置Connection的AutoCommit属性为false,提供对事务的支持,然后,显式地调用commit或rollback方法提交或回滚事务.

    连接池需要复用connection,因此,必须提供相应的事务支持机制.考虑采用每个事务独占一个连接,此法可降低事务管理复杂性.

    :多数据库服务器和多用户--JDBC规范中,DataSource具备同时连接不同数据库的能力,如同时连oracle和sql server.此时,考虑使用xml配置文件来配置连接所需的相关信息.然后,提供一个Singleton模式的连接池管理类,该管理类每次启动时读取配置文件信息,创建多个连接池类的实例,每个实例对应一个数据库连接池.连接池管理类实例命名每个连接池实例,通过不同的名称管理不同的连接池.

    对于多个用户访问同一个数据库的情况,也可考虑使用xml配置文件.

    》常见的数据库连接池

通常,没有必要自己实现连接池.商用应用服务器都有自己的连接池实现,如WebLogic和WebSphere,其性能和稳定性绝佳,即使没有商用应用服务器,也可使用开源的连接池.目前流行的有2个:@DBCP连接池   @C3P0连接池

》DBCP连接池

    Appache提供的开源实现,依赖于两个jar文件

    @commons-dbcp-1.2.1.jar:连接池的实现

    @commons-pool.jar:连接池实现的依赖库

    Tomcat的连接池正是采用该连接池实现的.连接该连接池,既允许与应用服务器整合使用,又可由应用程序独立使用.下面的代码DBConn类通过DBCP获得数据库连接:

    public class DBConn

    {

    private static DBConn dc;

    private Connection conn = null;

    private Statement stmt = null;

    private DBConn()

    {

    }

    public static DBConn instance()

    {

    if (dc == null)

    {

    dc = new DBConn();

    }

    return dc;

    }

    public Statement openStmt()

    {

    if (stmt == null)

    {

    conn = getConn();

    try

    {

    stmt = conn.createStatement();

    }

    catch (Exception e)

    {

    System.err.println("创建Statement异常: " + e.getMessage());

    }

    }

    return stmt;

    }

    public void closeStmt()

    {

    if (stmt != null)

    {

    try

    {

    stmt.close();

    }

    catch (Exception e)

    {

    System.err.println("Statement关闭异常");

    }

    }

    if (conn != null)

    {

    try

    {

    conn.close();

    }

    catch (Exception e)

    {

    System.err.println("数据库关闭异常");

    }

    }

    }

    private Connection getConn()

    {

    if (conn == null)

    {

    try

    {

    BasicDataSource ds = new BasicDataSource();

    ds.setDriverClassName("com.mysql.jdbc.Driver");

    ds.setUrl("jdbc:mysql://localhost:3306/j2ee");

    ds.setUsername("root");

    ds.setPassword("123456");

    conn = ds.getConnection();

    }

    catch (Exception e)

    {

    e.printStackTrace();

    }

    }

    return conn;

    }

    }

    》C3P0连接池

Hibernate推荐使用该优秀的连接池,它实现了JDBC3.0规范的部分功能,故其性能更加突出,该池不仅可自动清理不再使用的Connection,还可以自动清理Statement和ResultSet.C3P0连接池需要jre1.3以上,推荐jre1.4

若需使用C3P0连接池,应将包c3p0-0.8.5.jar文件复制进系统.下面代码是通过C3P0连接池获得数据库连接:

    public class DBConn

    {

    private static DBConn dc;

    private Connection conn = null;

    private Statement stmt = null;

    private DBConn()

    {

    }

    public static DBConn instance()

    {

    if (dc == null)

    {

    dc = new DBConn();

    }

    return dc;

    }

    public Statement openStmt()

    {

    if (stmt == null)

    {

    conn = getConn();

    try

    {

    stmt = conn.createStatement();

    }

    catch (Exception e)

    {

    System.err.println("创建Statement异常: " + e.getMessage());

    }

    }

    return stmt;

    }

    public void closeStmt()

    {

    if (stmt != null)

    {

    try

    {

    stmt.close();

    }

    catch (Exception e)

    {

    System.err.println("Statement关闭异常");

    }

    }

    if (conn != null)

    {

    try

    {

    conn.close();

    }

    catch (Exception e)

    {

    System.err.println("数据库关闭异常");

    }

    }

    }

    public Connection getConn()

    {

    if (conn == null)

    {

    try

    {

    ComboPooledDataSource ds = new ComboPooledDataSource();

    ds.setDriverClass("com.mysql.jdbc.Driver");

    ds.setJdbcUrl("jdbc:mysql://localhost:3306/j2ee");

    ds.setUser("root");

    ds.setPassword("32147");

    ds.setMaxPoolSize(40);

    ds.setMinPoolSize(2);

    ds.setMaxStatements(180);

    conn = ds.getConnection();

    }

    catch (Exception e)

    {

    e.printStackTrace();

    }

    }

    return conn;

    }

    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值