---->六步实现java程序对数据库的操作
---->为了简化六步,出现JDBCUtils
---->为了提高并发访问效率,出现连接池Druid/c3p0,可以直接从连接池获得Connection,
并且这个时候对Connection的进行了装饰,返回的Connection自带连接池引用,
close()方法自动归还连接到连接池,
----->由于连接池技术的出现,它本身也封装了创建连接的步骤,所有我们可以利用这一点,在JDBCUtils中加以利用,这样就有了
利用连接池,改写JDBCUtils类,使JDBCUtils更加强大;
---->为了简化对结果集ResultSet的数据封装,出现了DBUtils,它直接对Connection /或者DataSource 操作;
DBUtils核心类QueryRunner,用于sql操作,ResultSetHandler(结果集处理器)用于对数据进行封装;
4.DataSource:连接池技术:
a)数据库的连接是非常稀缺的, 每次操作数据库,都需要有连接,而之前的时候是 每次使用的使用新创建,然后用,用完了之后又 真正的销毁了.
以上的这种做法,效率比较低. 如果一个网站的访问量很大, 1天有 100万个用户登录,假设一个 连接的创建 0.001秒, 0.001*1000000 = ?
也是很长的时间... 在这个过程中,频繁的创建 连接,销毁连接, 数据库也 受不了...怎么办呢?这个时候引入 连接池技术. 连接池核心思想:
一次性批量的创建多个连接, 放到一个容器中, 需要使用的时候从容器中取出来使用,用完了之后, 再 还回去, 这样就避免的 不断的创建新的连接
并且销毁连接的事情,从而大大 的提高数据库访问性能.
市面上就有组织已经 写好了 功能非常完善的连接池, 我们只需要去学习一下它们,就可以快速的引入到我们的代码中, 变成你自己的了.
阿里的 Druid --- 德鲁伊
DBCP
C3P0 连接池
b) 阿里的 Druid --- 德鲁伊 核心代码:
try {
//创建properties集合来读取配置文件
Properties prop = new Properties();
prop.load(new FileInputStream("src/druid.properties"));
//使用工厂创建连接池,需要传入一个properties集合,这个集合读取了配置文件
DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);
//从连接池获得连接
conn = dataSource.getConnection();
//获得连接以后,代码就都跟之前相同了:
//...
//...
}
c) C3P0 连接池 核心代码:
try {
/*创建连接池,在创建的时候,程序自动会到src目录下去找一个c3p0-config.xml的配置文件,
* 拿到里边的配置信息,完成连接池的创建,相比之下,它的封装性比Druid更强;
*/
ComboPooledDataSource cpds = new ComboPooledDataSource();
//从连接池获得连接
conn = cpds.getConnection();
//获得连接以后,代码就都跟之前相同了:
//...
//...
}
================================以下个人总结=========================================
个人总结:
连接池是为了减少连接的不断创建与销毁导致效率低下而创建的,所以它做了一件事就是:它封装了JDBC协议中规定的创建连接的部分
然后将连接放在一个容器中,当我们使用连接时直接 getConnection(); 就可以了,当我们使用完毕要归还连接;
那么问题来了,对于不同的连接池,我们归还连接的方法可能无法保证方法名一致,这就会导致用不一样的连接池,我们要用不同的归还
连接的方法,这无疑是增加了程序员的记忆负担,为了解决这个问题,我们规定所有的连接池归还连接都用close()方法,然后各自通过装饰模式
将连接归还到各自的连接池;
不同连接池创建对象的方法对比:
阿里的 Druid --- 德鲁伊 是通过工厂模式获得连接:
//使用工厂创建连接池,需要传入一个properties集合,这个集合读取了配置文件
DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);
C3P0 连接池 是通过规范配置文件的存放位置,以及配置文件名字,来达到在创建对象时自动读取配置文件:
/*创建连接池,在创建的时候,程序自动会到src目录下去找一个c3p0-config.xml的配置文件,
拿到里边的配置信息,完成连接池的创建,相比之下,它的封装性比Druid更强;*/
ComboPooledDataSource cpds = new ComboPooledDataSource();
========================以下为个人写的Druid配置文件==========================
driveClassName =com.mysql.jdbc.Driver
url = jdbc:mysql://localhost:3306/db2
user = root
password = 123
========================以下为个人写的Druid代码==========================
package com.itheima.database;
import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Properties;
import javax.sql.DataSource;
import org.junit.Test;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import com.itheima.utils.JDBCUtils;
/**
* 开源连接池Druid的使用
*/
public class DruidDemo {
@Test
public void test1() {
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
// 创建properties集合来读取配置文件
Properties prop = new Properties();
prop.load(new FileInputStream("src/druid.properties"));
// 使用工厂创建连接池,需要传入一个properties集合,这个集合读取了配置文件
DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);
// 从连接池获得连接
conn = dataSource.getConnection();
// 获得连接以后,代码就都跟之前相同了:
// ...
// ...
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
} finally {
/*
* 释放资源 ,使用连接池获取的连接,当调用它的close()方法, 它不会讲连接销毁,而是将连接归还到连接池 ,因为在连接池内部,
* 都对连接进行了装饰,它们的close()方法都被增强了;
*/
JDBCUtils.release(rs, pstmt, conn);
}
}
}
=================以下为个人写的C3P0配置文件(必须放在src目录下边)================
<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
<default-config>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/db2</property>
<property name="user">root</property>
<property name="password">123</property>
<property name="initialPoolSize">5</property>
<property name="minPoolSize">5</property>
<property name="maxPoolSize">20</property>
</default-config>
<!-- This app is massive! -->
<!-- <named-config name="oracle">
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql:///web_test4</property>
<property name="user">root</property>
<property name="password">abc</property>
</named-config> -->
</c3p0-config>
========================以下为个人写的C3P0代码==========================
package com.itheima.database;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import org.junit.Test;
import com.itheima.utils.JDBCUtils;
import com.mchange.v2.c3p0.ComboPooledDataSource;
/**
* 开源连接池Druid的使用
*/
public class C3p0Demo {
@Test
public void test1() {
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
/*
* 创建连接池,在创建的时候,程序自动会到src目录下去找一个c3p0-config.xml的配置文件,
* 拿到里边的配置信息,完成连接池的创建,相比之下,它的封装性比Druid更强;
*/
ComboPooledDataSource cpds = new ComboPooledDataSource();
// 从连接池获得连接
conn = cpds.getConnection();
// 获得连接以后,代码就都跟之前相同了:
// ...
// ...
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
} finally {
/*
* 释放资源 ,使用连接池获取的连接,当调用它的close()方法, 它不会讲连接销毁,而是将连接归还到连接池 ,因为在连接池内部,
* 都对连接进行了装饰,它们的close()方法都被增强了;
*/
JDBCUtils.release(rs, pstmt, conn);
}
}
}