JavaWeb 连接池详解

 

首先一句话说清为什么要引入连接池呢?
传统的jdbc操作数据库步骤就是:

  • 建立数据库连接
  • 增删改查数据
  • 关闭数据库连接

分析这个过程对资源的损耗:服务器连接数据库是类似于socket通信的连接方式,连接速度慢,最后又关闭了连接,下次操作又需要重新建立连接,一会儿连接,一会儿关闭,资源造成了巨大的烂费!因此引入数据源(连接池)。
连接池的核心:将连接的指向改了,现在是指向数据源,而不是数据库。

手写简单连接池底层源码

package pool;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import core.DBManager;

/**
 * 连接池的类
 * @author john
 *
 */
public class DBConnPool {
	
	/**
	 * 连接池对象
	 */
	private static List<Connection> pool; 
	/**
	 * 最大连接个数
	 */
	private static final int POOL_MAX_SIZE=DBManager.getConf().getPoolMaxSize();
	/**
	 * 最小连接数
	 */
	private static final int POOL_MIN_SIZE=DBManager.getConf().getPoolMinSize(); 
	
	
	
	/**
	 * 初始化连接池、使池中的连接数达到最小值
	 */
	public void initPool(){
		if(pool==null){
			pool=new ArrayList<Connection>();
		}
		
		while(pool.size()<DBConnPool.POOL_MIN_SIZE){
			pool.add(DBManager.creatConn());
			//System.out.println("初始化池,池中连接数:"+pool.size());
		}
	}
	
	/**
	 * 从连接池中取出一个连接
	 * 注意:连接池是否为空
	 * @return
	 */
	public synchronized Connection getConnection(){
		if(pool.isEmpty()==false){
			int last_index=pool.size()-1;
			Connection conn=pool.get(last_index);
			pool.remove(last_index);
			return conn;
		}else{
			return DBManager.creatConn();
		}	
	}
	
	/**
	 * 将连接放回连接池中
	 * 注意:连接池中连接数超过最大就真的关闭
	 * @param conn
	 */
	public synchronized void close(Connection conn){
		if(pool.size()>POOL_MAX_SIZE){
			if (conn!=null) {
				try {
					conn.close();
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}else{
			pool.add(conn);
		}
		
	}
	
	public DBConnPool(){
		initPool();
	}

}
 

 

常见连接池:Tomcat-dbcp、dbcp、c3p0、druid(略) 

Tomcat-dbcp连接池(以mysql为例):

a.配置数据源:数据库连接池,位置:/conf/context.xml(类似于JNDI)

<Resource name="student" auth="Container" type="javax.sql.DataSource" 
		maxActive="400" 
		maxIdle="20"  maxWait="5000"  username="root" password="123456" 
driverClassName="com.mysql.jdbc.Driver"  url="jdbc:mysql://localhost:3306/student" />

b.在web.xml中指定数据源 :

<resource-ref>
    <res-ref-name>student</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
</resource-ref>


c.使用数据源  (注意:这里要知道数据源(DataSource) 是用来管理数据库连接池的即可)

传统的Connection的获取方式(JDBC操作)

connection = DriverManager.getConnection(URL,USERNAME,PASSWORD);

数据源方式:

Context ctx = new InitialContext() ;//context.xml
DataSource ds = (DataSource)ctx.lookup("java:comp/env/student") ;
connection = ds.getConnection();//ds.getConnection()就是 数据源(连接池)

 

dbcp连接池(以oracle为例)

a.引入jar包(commons-dbcp-1.4.jar、commons-pool.jar)

b.两种创建数据源方式

1)BasicDataSource方式(硬编码)

    //获取dbcp方式的ds对象
    public static DataSource getDataSourceWIthDBCP(){
        BasicDataSource dbcp = new BasicDataSource();
        dbcp.setDriverClassName("oracle.jdbc.driver.OracleDriver");
        dbcp.setUrl("jdbc:oracle:thin:@127.0.0.1:1521:ORCL");
        dbcp.setUsername("scott");
        dbcp.setPassword("tiger");
        dbcp.setInitialSize(20);
        dbcp.setMaxActive(10);
        return dbcp;
    }

2)BasicDataSourceFactory方式(配置方式):.properties文件, 编写方式key=value
 

//配置文件:dbcpconfig.properties
driverClassName=oracle.jdbc.driver.OracleDriver
url=jdbc:oracle:thin:@127.0.0.1:1521:ORCL
username=scott
password=tiger
initialSize=10
 public static DataSource getDataSourceWIthDBCPByProperties() throws Exception{
        DataSource dbcp = null ;
        Properties props = new Properties();
        //将字符串变成输入流
        InputStream input = new                  DBCPDemo().getClass().getClassLoader().getResourceAsStream("dbcpconfig.properties");
        //加载配置文件        
        props.load(  input );

        //只需要记住以下一句
        dbcp = BasicDataSourceFactory.createDataSource(props ) ;
        return dbcp;
    }

 c3p0连接池(以oracle为例):

a.导入jar包 (c3p0.jar  c3p0-oracle-thin-extras.jar)

b.两种创建数据源方式


1)无参,硬编码

    public static DataSource getDataSourceWithC3P0(){
        ComboPooledDataSource c3p0 = new ComboPooledDataSource();
        try {
            c3p0.setDriverClass("oracle.jdbc.driver.OracleDriver");
        } catch (PropertyVetoException e) {
            e.printStackTrace();
        }
        c3p0.setJdbcUrl("jdbc:oracle:thin:@127.0.0.1:1521:ORCL");
        c3p0.setUser("scott");
        c3p0.setPassword("tiger");

        return c3p0 ;
    }

2)有参,配置文件(c3p0-config.xml)

<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
    <default-config>
        <!-- 如果要研究某个xml中可以设置哪些属性。找相关类的 属性 或者setXxx()-->
        <property name="user">scott</property>
        <property name="password">tiger</property>
        <property name="driverClass">oracle.jdbc.driver.OracleDriver</property>
        <property name="jdbcUrl">jdbc:oracle:thin:@127.0.0.1:1521:ORCL</property>
        <property name="checkoutTimeout">30000</property>
    </default-config>


    <named-config name="yanqun">
        <property name="user">scott</property>
        <property name="password">tiger</property>
        <property name="driverClass">oracle.jdbc.driver.OracleDriver</property>
        <property name="jdbcUrl">jdbc:oracle:thin:@127.0.0.1:1521:ORCL</property>
        <property name="checkoutTimeout">20000</property>

    </named-config>
</c3p0-config>
    public static DataSource getDataSourceWithC3P0ByXml(){
        ComboPooledDataSource c3p0 = new ComboPooledDataSource("yanqun");
        return c3p0 ;
    }

 

整合为工具类:

package com.yanqun.util;

import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.apache.commons.dbcp.BasicDataSource;
import org.apache.commons.dbcp.BasicDataSourceFactory;

import javax.sql.DataSource;
import java.beans.PropertyVetoException;
import java.io.InputStream;
import java.util.Properties;

public class DataSourceUtil {


    //获取dbcp方式的ds对象
    public static DataSource getDataSourceWIthDBCP(){
        BasicDataSource dbcp = new BasicDataSource();
        dbcp.setDriverClassName("oracle.jdbc.driver.OracleDriver");
        dbcp.setUrl("jdbc:oracle:thin:@127.0.0.1:1521:ORCL");
        dbcp.setUsername("scott");
        dbcp.setPassword("tiger");
        dbcp.setInitialSize(20);
        dbcp.setMaxActive(10);
        return dbcp;
    }


    public static DataSource getDataSourceWIthDBCPByProperties() throws Exception{
        DataSource dbcp = null ;
        Properties props = new Properties();
        InputStream input = new DBCPDemo().getClass().getClassLoader().getResourceAsStream("dbcpconfig.properties");
        props.load(  input );

        //只需要记住以下一句
        dbcp = BasicDataSourceFactory.createDataSource(props ) ;
        return dbcp;
    }

    public static DataSource getDataSourceWithC3P0(){
        ComboPooledDataSource c3p0 = new ComboPooledDataSource();
        try {
            c3p0.setDriverClass("oracle.jdbc.driver.OracleDriver");
        } catch (PropertyVetoException e) {
            e.printStackTrace();
        }
        c3p0.setJdbcUrl("jdbc:oracle:thin:@127.0.0.1:1521:ORCL");
        c3p0.setUser("scott");
        c3p0.setPassword("tiger");

        return c3p0 ;
    }

    public static DataSource getDataSourceWithC3P0ByXml(){
        ComboPooledDataSource c3p0 = new ComboPooledDataSource("yanqun");
        return c3p0 ;
    }

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值