连接池dbcp跟c3p0

使用连接池的目的:重复利用Connection资源

连接池概述:

在Java中,我们使用javax.sql.DataSource来表示连接池对象。

DataSource:数据源,其实就是连接池,Connection Pool.

为什么要使用连接池:

普通的JDBC数据库连接使用 DriverManager来获取,每次向数据库建立连接的时候都要将Connection加载到内存中,再验证用户和密码
(得花费0.05s~1s的时间)。需要数据库连接的时候,就向数据库要求一个,执行完成后再断开连接。这样的方式将会消耗大量的资源时间。
数据库的连接资源并没有得到很好的重复利用,若同时有几百人甚至几千人在线,频繁的进行数据库连接操作将会占用很多的系统资源,
严重的甚至会造成服务器系统崩溃。对于每一次数据库连接,使用完后都得断开,否则如果程序出现异常而未能关闭,将会导致数据库系统
中的内存泄露,最终将导致重启数据库。这种开发不能控制被创建的连接对象数,系统资源会被毫无顾忌的分配出去,如连接过多,也可能
导致内存泄露,服务器奔溃。

常见的连接池技术:

dbcp :Spring推荐的连接池技术

c3p0 :HiBernate推荐的连接池技术

使用连接池和不使用连接池在代码上的区别:

使用连接池之前:使用DriverManager来获取Connection对象。

			  Connection  conn  =  DriverManager.getConnection(url,  username,  password);

使用连接池之后:直接找连接池取出(Connection对象),取出Connection即可。

如何创建DataSource对象:

			  Connection conn = DataSource对象.getConnection();

接下来的代码和以前相同。

释放连接:

代码:connection对象.close();

使用连接池之前:直接和数据库服务器建立连接关系,而断开也是和数据库服务器断开连接。

使用连接池之后: 直接和连接池建立连接关系,而断开也是把connection对象还给连接池,供其他客服使用,没有真正的和数据库断开,
如此一来,一个connection对象就得到了充分的利用!!!

思考题:请你给我设计一个连接池。

dbcp连接池:

/**
	 * 1.拷贝jar包。
	 * 		Commons-dbcp-1.4.jar    commons-pool-1.5.6.jar
	 * 2.阅读文档:commons-dbcp-1.3-src/doc/BasicDataSourceExample.java
	 * 
	 * 	步骤:
	 * 		1.创建DataSource对象
	 * 		2.从DataSource对象中获取Connection对象。
	 * 		3.接下来使用Connection就和以前相同
	 */
	
	private DataSource getDS(){
		  //这些是阅读文档:commons-dbcp-1.3-src/doc/BasicDataSourceExample.java查到的。
		  BasicDataSource ds = new BasicDataSource();
	      ds.setDriverClassName("com.mysql.jdbc.Driver");
	      ds.setUsername("root");
	      ds.setPassword("111111");
	      ds.setUrl("jdbc:mysql:///jdbcdemo?useSSL=false");
	      //设置初始化连接数 
	      ds.setInitialSize(5);   
	      return ds;
	}
	
	@Test
	public void testName() throws Exception {
		//获取数据源对象
		//DataSource ds = this.getDS();
		//从数据源对象获取Connection对象
		//Connection conn = ds.getConnection();
		//=======================================
		Connection conn = DBCPUtil.INSTANCE.getConn();//这是使用DBCPUtil工具包的操作!
		String sql = "select * from product";
		PreparedStatement ps = conn.prepareStatement(sql);
		ResultSet rs = ps.executeQuery();
		while (rs.next()){
			Long id = rs.getLong("id");
			String name = rs.getString("productName");
			System.out.println(id +"\t" + name);
		}
		JdbcUtil.INSTANCE.close(conn, ps, rs);
	}
//jdbc的操作工具类
public enum DBCPUtil {

	INSTANCE;

	private static DataSource dataSource;

	//只需要注册一次驱动即可,没必要每次都注册,放到jdbcutil类的静态代码块中(当字节码被加载进jvm,就会执行)
	static {
		Properties p = new Properties();
		try {
			//从classpath的根路径去加载db.properties文件
			//加载dbcp。properties文件,并把该文件的信息读取到properties对象中。
			InputStream inStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("dbcp.properties");
			p.load(inStream);
			//把装有连接信息的P对象传递给工厂类,-->DataSource对象
			dataSource = BasicDataSourceFactory.createDataSource(p);
			//根据Properties对象的信息,创建DataSource对象。
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 创建connection对象
	 * @return
	 */
	public Connection getConn() {
		try {
			//从dataSource中获取一个connection对象
			return dataSource.getConnection();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return null;
	}

	public void close(Connection conn, Statement st, ResultSet rs) {
		try {
			if (rs != null) {
				rs.close();
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (st != null) {
					st.close();
				}
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				try {
					if (conn != null) {
						conn.close();
					}

				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
	}

dbcp.properties文件内容:

url=jdbc:mysql://localhost:3306/jdbcdemo?useSSL=false
username=root
password=111111
driverClassName=com.mysql.jdbc.Driver
initialSize=1
maxActive=50
maxIdle=20

c3p0连接池:

/**
	 * 1.拷贝jar包。
	 * 		Commons-dbcp-1.4.jar    commons-pool-1.5.6.jar
	 * 2.阅读文档:commons-dbcp-1.3-src/doc/BasicDataSourceExample.java
	 * 
	 * 	步骤:
	 * 		1.创建DataSource对象
	 * 		2.从DataSource对象中获取Connection对象。
	 * 		3.接下来使用Connection就和以前相同
	 */
	
	private DataSource getDS() throws Exception {
     	//这些是阅读文档:commons-dbcp-1.3-src/doc/BasicDataSourceExample.java查到的。
		ComboPooledDataSource cpds = new ComboPooledDataSource();
		cpds.setDriverClass("com.mysql.jdbc.Driver"); //loads the jdbc driver            
		cpds.setJdbcUrl("jdbc:mysql:///jdbcdemo?userSSL=false");
		cpds.setUser("root");                                  
		cpds.setPassword("111111");
		//初始化连接数
		cpds.setInitialPoolSize(5);
		return cpds;
	}
	@Test
	public void testName() throws Exception {
		//获取数据源对象
	    //从数据源对象获取Connection对象
		//Connection conn = this.getDS().getConnection();
		//=======================================
		Connection conn = C3P0Util.INSTANCE.getConn();
		String sql = "select * from product";
		PreparedStatement ps = conn.prepareStatement(sql);
		ResultSet rs = ps.executeQuery();
		while (rs.next()){
			Long id = rs.getLong("id");
			String name = rs.getString("productName");
			System.out.println(id +"\t" + name);
		}
		JdbcUtil.INSTANCE.close(conn, ps, rs);
	}

代码中数据连接池的配置信息写死了,不利于维护。
解决方案:把c3p0的连接信息,抽离到配置文件中–>c3p0.properties

注意:必须按照以下规则:
1.文件名称必须叫做:c3p0.properties
2.c3p0.properties存放在classpath的根路径。就是放在sourcefolder文件中
3.c3p0.properties文件中的key必须以c3p0.作为前缀:如:c3p0.jdbcUrl
4.c3p0.properties文件中的key,必须ComboPooledDataSource的属性

因为c3p0在配置的时候有很多约束:
约束存放的位置:CLASSPATH根路径
约束文件的名称:c3p0.properties
就决定了c3p0内部会自动的去找classpath的跟路径去寻找c3p0.properties文件。

//jdbc的操作工具类
public enum C3P0Util {

	INSTANCE;

	private static DataSource dataSource;

	//只需要注册一次驱动即可,没必要每次都注册,放到jdbcutil类的静态代码块中(当字节码被加载进jvm,就会执行)
	static {
		Properties p = new Properties();
		try {
			DataSource ds_unpooled = DataSources.unpooledDataSource();
			dataSource = DataSources.pooledDataSource( ds_unpooled );
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 创建connection对象
	 * @return
	 */
	public Connection getConn() {
		try {
			//从dataSource中获取一个connection对象
			return dataSource.getConnection();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return null;
	}

	public void close(Connection conn, Statement st, ResultSet rs) {
		try {
			if (rs != null) {
				rs.close();
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (st != null) {
					st.close();
				}
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				try {
					if (conn != null) {
						conn.close();
					}

				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
	}

c3p0.properties文件内容:

c3p0.driverClass=com.mysql.jdbc.Driver
c3p0.jdbcUrl=jdbc:mysql:///jdbcdemo?userSSL=false
c3p0.user=root
c3p0.password=111111
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值