java--开源数据库连接池(dbcp数据源)

现在很多WEB服务器(Weblogic, WebSphere, Tomcat)都提供了DataSoruce的实现,即连接池的实现。通常我们把DataSource的实现,按其英文含义称之为数据源,数据源中都包含了数据库连接池的实现。
也有一些开源组织提供了数据源的独立实现:
        DBCP 数据库连接池
        C3P0 数据库连接池
实际应用时不需要编写连接数据库代码,直接从数据源获得数据库的连接。程序员编程时也应尽量使用这些数据源的实现,以提升程序的数据库访问性能。
DBCP数据源
DBCP 是 Apache 软件基金组织下的开源连接池实现,使用DBCP数据源,应用程序应在系统中增加如下两个 jar 文件:
        Commons-dbcp.jar:连接池的实现
        Commons-pool.jar:连接池实现的依赖库
Tomcat 的连接池正是采用该连接池来实现的。该数据库连接池既可以与应用服务器整合使用,也可由应用程序独立使用。

dbcp数据库连接池的两种实现方式

package cn.hncu.dbcp;

import java.sql.Connection;
import java.util.Properties;

import javax.sql.DataSource;

import org.apache.commons.dbcp.BasicDataSource;
import org.apache.commons.dbcp.BasicDataSourceFactory;
import org.junit.Test;

public class DbcpPoolDemo {

    //dbcp数据库连接池----BasicDataSource类对象

    //使用配置文件的方式--利用BasicDataSourceFactory工厂类+Properties的方式创建,参数直接从配置文件读取
    @Test
    public void demo2() throws Exception{
        Properties p=new Properties();
        //src目录下的--配置文件放在classpath下,则可用下面一行来获取
//      p.load(DbcpPoolDemo.class.getClassLoader().getResourceAsStream("dbcp.properties"));
        //配置文件和当前类放在一起
        p.load(DbcpPoolDemo.class.getResourceAsStream("dbcp2.properties"));
        DataSource pool=BasicDataSourceFactory.createDataSource(p);
//      Connection con=pool.getConnection();
//      System.out.println("con:"+con);
        for(int i=0;i<30;i++){//默认是八个,可以通过资源文件(dbcp2.properties)更改 

            Connection con=pool.getConnection();
            System.out.println(con.hashCode());//输出8个(pool.getMaxActive())之后就阻塞了
        }

    }
    @Test//纯Java方式 ---利用空参构造方式BasicDataSource()创建,然后通过setter方法手动设置参数
    public void demo1() throws Exception{
        BasicDataSource pool=new BasicDataSource();
        pool.setDriverClassName("com.mysql.jdbc.Driver");
        pool.setUrl("jdbc:mysql://127.0.0.1:3306/hncu?useUnicode=true&characterEncoding=utf-8");
        pool.setUsername("root");
        pool.setPassword("1234");
//      Connection con=pool.getConnection();
//      System.out.println(con);

        System.out.println("初始连接的个数:"+pool.getInitialSize());//0
        System.out.println("最多能有几个在用的连接:"+pool.getMaxActive());//8
        System.out.println("最多空闲多长时间(若没使用该连接就收回):"+pool.getMaxIdle());//8
        System.out.println("最多等待多长时间(若没获得连接就抛出异常):"+pool.getMaxWait());//-1
        //可以自己更改池的参数
        pool.setMaxActive(10);
        /*
         * 以下测试从池获取多个连接
         */
        for(int i=0;i<15;i++){
            Connection con=pool.getConnection();
            System.out.println(con.hashCode());//输出8个(pool.getMaxActive())之后就阻塞了
            if(i%2==0){//dbcp池中如果有最近使用的连接con,就不会新开一个连接con,而是使用最近用的con
                con.close();
            }
        }
        System.out.println("Over....");
    }
}

dbcp.properties放在src目录下

driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/hncu?useUnicode=true&characterEncoding=utf-8
username=root
password=1234
size=3

开源数据库连接池

package cn.hncu.dbcp;

import java.sql.Connection;
import java.util.Properties;

import javax.sql.DataSource;

import org.apache.commons.dbcp.BasicDataSourceFactory;

public class DbcpUtils {
    //本地线程管理对象,用于实现: 同一个线程获取的连接是同一个
    private static ThreadLocal<Connection> t = new ThreadLocal<Connection>();

    private static DataSource pool = null;
    static{
        Properties p = new Properties();
        try {
            //配置文件和当前类放在一起
            p.load(DbcpUtils.class.getResourceAsStream("dbcp2.properties"));

            pool= BasicDataSourceFactory.createDataSource(p);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static Connection getConn() {
        //先从t中拿,如果有就拿出去,如果没有再到池中拿且把该对象放到t中
        Connection con = t.get();
        if(con==null){
            try {
                con=pool.getConnection();
                t.set(con); //放到t中
            } catch (Exception e) {
                throw new RuntimeException(e.getMessage(), e);
            }
        }
        System.out.println("获取一个连接:"+con);
        return con;
    }

}

dbcp2.properties和当前类放在一起

driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/hncu?useUnicode=true&characterEncoding=utf-8
username=root
password=1234
maxActive=15
package cn.hncu.test;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.UUID;

import org.junit.Test;

import cn.hncu.dbcp.DbcpUtils;

public class DbcpTest {

    @Test
    public void demo() throws Exception{
        Connection con=DbcpUtils.getConn();
        System.out.println("demo-con:"+con);
        try {
            con.setAutoCommit(false);
            saveStud();
            saveStud2();
            con.commit();
            System.out.println("提交一个事务...");
        } catch (SQLException e) {
            con.rollback();
            System.out.println("回滚一个事务...");
        }finally{
            con.setAutoCommit(true);//还原现场
            con.close();
        }

    }

    public void saveStud() throws Exception{
        Connection con=DbcpUtils.getConn();
        System.out.println("saveStud-con:"+con);
        String sql="INSERT INTO stud VALUES(?,?)";
        PreparedStatement pst=con.prepareStatement(sql);
        for(int i=0;i<2;i++){
            String id=UUID.randomUUID().toString().replace("-", "");
            pst.setString(1, id);
            pst.setString(2, "stud"+i);
            pst.addBatch();
        }
        pst.executeBatch();
    }
    public void saveStud2() throws Exception{
        Connection con=DbcpUtils.getConn();
        System.out.println("saveStud2-con:"+con);
        String sql="insert into stud values(?,?)";
        PreparedStatement pst=con.prepareStatement(sql);
        for(int i=3;i<5;i++){
            String id=UUID.randomUUID().toString().replace("-", "");
            pst.setString(1, id);
//          pst.setString(1, "70e56717e7634c9c85aefcad6560afd1");//测试事务回滚
            pst.setString(2, "stud"+i);
            pst.addBatch();
        }
        pst.executeBatch();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值