数据库连接池的作用及c3p0的详解 |
您所在的位置:网站首页 › 数据库连接池的优点有哪些 › 数据库连接池的作用及c3p0的详解 |
1.JDBC数据库连接池的必要性 在使用开发基于数据库的web程序时,传统的模式基本是按以下步骤: 在主程序(如servlet、beans)中建立数据库连接。 进行sql操作 断开数据库连接。 这种模式开发,存在的问题: 普通的JDBC数据库连接使用 DriverManager 来获取,每次向数据库建立连接的时候都要将 Connection 加载到内存中,再验证用户名和密码(得花费0.05s~1s的时间)。需要数据库连接的时候,就向数据库要求一个,执行完成后再断开连接。这样的方式将会消耗大量的资源和时间。数据库的连接资源并没有得到很好的重复利用.若同时有几百人甚至几千人在线,频繁的进行数据库连接操作将占用很多的系统资源,严重的甚至会造成服务器的崩溃。 对于每一次数据库连接,使用完后都得断开。否则,如果程序出现异常而未能关闭,将会导致数据库系统中的内存泄漏,最终将导致重启数据库。 这种开发不能控制被创建的连接对象数,系统资源会被毫无顾及的分配出去,如连接过多,也可能导致内存泄漏,服务器崩溃. 2.数据库连接池(connection pool) 为解决传统开发中的数据库连接问题,可以采用数据库连接池技术。 数据库连接池的基本思想就是为数据库连接建立一个“缓冲池”。预先在缓冲池中放入一定数量的连接,当需要建立数据库连接时,只需从“缓冲池”中取出一个,使用完毕之后再放回去。 数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是重新建立一个。 数据库连接池在初始化时将创建一定数量的数据库连接放到连接池中,这些数据库连接的数量是由最小数据库连接数来设定的。无论这些数据库连接是否被使用,连接池都将一直保证至少拥有这么多的连接数量。连接池的最大数据库连接数量限定了这个连接池能占有的最大连接数,当应用程序向连接池请求的连接数超过最大连接数量时,这些请求将被加入到等待队列中。 3.数据库连接池技术的优点 (1)资源重用:由于数据库连接得以重用,避免了频繁创建,释放连接引起的大量性能开销。在减少系统消耗的基础上,另一方面也增加了系统运行环境的平稳性。 (2)更快的系统反应速度:数据库连接池在初始化过程中,往往已经创建了若干数据库连接置于连接池中备用。此时连接的初始化工作均已完成。对于业务请求处理而言,直接利用现有可用连接避免了数据库连接初始化和释放过程的时间开销,从而减少了系统的响应时间 (3)新的资源分配手段对于多应用共享同一数据库的系统而言,可在应用层通过数据库连接池的配置实现某一应用最大可用数据库连接数的限制避免某一应用独占所有的数据库资源. (4)统一的连接管理,避免数据库连接泄露在较为完善的数据库连接池实现中,可根据预先的占用超时设定,强制回收被占用连接,从而避免了常规数据库连接操作中可能出现的资源泄露。 4.c3p0数据库连接池 据说c3p0数据库连接池是最优秀的,下面我就来介绍如何使用c3p0连接池。 (1)下载jar包 (2)配置文件 作为一个数据库连接池自然有很多参数要设置,当然就算你不设置也有默认的,不过那不一定能满足你的要求。这里的配置文件没有什么特别的要求,可以是xml也可以是properties甚至与txt都行,当然如果你愿意也可以写死在程序中。 下面是我的配置文件,我把它放在了src目录下,名字叫“c3p0.properties” [plain] view plain copy #jdbc基本信息 driverClass=oracle.jdbc.driver.OracleDriver jdbcUrl=jdbc:oracle:thin:@192.168.61.250:1521:SXPPMS user=qzp password=111111 #c3p0连接池信息 c3p0.minPoolSize=3 c3p0.maxPoolSize=25 #当连接池中的连接耗尽的时候c3p0一次同时获取的连接数 c3p0.acquireIncrement=3 #定义在从数据库获取新连接失败后重复尝试的次数 c3p0.acquireRetryAttempts=60 #两次连接中间隔时间,单位毫秒 c3p0.acquireRetryDelay=1000 #连接关闭时默认将所有未提交的操作回滚 c3p0.autoCommitOnClose=false #当连接池用完时客户端调用getConnection()后等待获取新连接的时间,超时后将抛出SQLException,如设为0则无限期等待。单位毫秒 c3p0.checkoutTimeout=3000 #每120秒检查所有连接池中的空闲连接。Default: 0 c3p0.idleConnectionTestPeriod=120 #最大空闲时间,60秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 c3p0.maxIdleTime=600 #如果设为true那么在取得连接的同时将校验连接的有效性。Default: false c3p0.testConnectionOnCheckin=true #c3p0将建一张名为c3p0TestTable的空表,并使用其自带的查询语句进行测试。 jdbc.automaticTestTable = c3p0TestTable然后是C3P0ConnentionProvider,它是一个c3p0连接池管理类 [java] view plain copy package com.qzp.util; import java.sql.Connection; import java.sql.SQLException; import java.util.Properties; import javax.sql.DataSource; import com.mchange.v2.c3p0.DataSources; /** * c3p0连接池管理类 * @author ICE * */ public class C3P0ConnentionProvider { private static final String JDBC_DRIVER = "driverClass"; private static final String JDBC_URL = "jdbcUrl"; private static DataSource ds; /** * 初始化连接池代码块 */ static{ initDBSource(); } /** * 初始化c3p0连接池 */ private static final void initDBSource(){ Properties c3p0Pro = new Properties(); try { //加载配置文件 c3p0Pro.load(C3P0ConnentionProvider.class.getResourceAsStream("/c3p0.properties")); } catch (Exception e) { e.printStackTrace(); } String drverClass = c3p0Pro.getProperty(JDBC_DRIVER); if(drverClass != null){ try { //加载驱动类 Class.forName(drverClass); } catch (ClassNotFoundException e) { e.printStackTrace(); } } Properties jdbcpropes = new Properties(); Properties c3propes = new Properties(); for(Object key:c3p0Pro.keySet()){ String skey = (String)key; if(skey.startsWith("c3p0.")){ c3propes.put(skey, c3p0Pro.getProperty(skey)); }else{ jdbcpropes.put(skey, c3p0Pro.getProperty(skey)); } } try { //建立连接池 DataSource unPooled = DataSources.unpooledDataSource(c3p0Pro.getProperty(JDBC_URL),jdbcpropes); ds = DataSources.pooledDataSource(unPooled,c3propes); } catch (SQLException e) { e.printStackTrace(); } } /** * 获取数据库连接对象 * @return 数据连接对象 * @throws SQLException */ public static synchronized Connection getConnection() throws SQLException{ final Connection conn = ds.getConnection(); conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED); return conn; } } SQLHelper.java文件内容如下:用于数据库的查询及增删操作。
[java] view plain copy package com.qzp.util; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.util.ArrayList; import java.util.List; public class SQLHelper { private Connection conn = null; private PreparedStatement ps = null; private ResultSet rs = null; /** * 数据查询 * @param sql语句 * @return 返回结果集List */ public List query(String sql) { if(sql.equals("") || sql == null){ return null; } List list = new ArrayList(); try { conn = C3P0ConnentionProvider.getConnection(); ps = conn.prepareStatement(sql); rs = ps.executeQuery(); ResultSetMetaData rsmd = rs.getMetaData(); // 可以得到有多少列 int columnNum = rsmd.getColumnCount(); // 将数据封装到list中 while (rs.next()) { Object[] objects = new Object[columnNum]; for (int i = 0; i |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |