代码实现
// 使用JDBCUtils的工具类
public void testCon() {
long start = System.currentTimeMillis();
System.out.println("开始连接.....");
for (int i = 0; i < 5000; i++) {
//使用传统的jdbc方式,得到连接对象
Connection connection = JDBCUtils.getConnection();
//做一些工作,比如得到 PreparedStatement ,发送 sql
//这里必须连接完后必须要关闭 , 否则连接太多会造成服务器宕机
JDBCUtils.close(null, null, connection);
}
long end = System.currentTimeMillis();
//传统方式 5000 次 耗时=7099
System.out.println("传统方式 5000 次 耗时=" + (end - start));
}
数据库连接池技术
数据库连接池的种类
导入c3p0-0.9.1.2.jar并添加到ClassPath下 ,这个**jar包中的ComboPooledDataSource类实现了javax.sql.DataSource接口 **
方式一: 相关参数,在程序中指定 user, url , password等参数信息
创建连接数据库的配置文件mysql.properties(文件名称和位置不固定 )
user=root
password=hsp
#rewriteBatchedStatements=true表示支持批处理
url=jdbc:mysql://localhost:3306/hsp_db02?rewriteBatchedStatements=true
driver=com.mysql.jdbc.Driver
代码实现
@Test
public void testC3P0_01() throws Exception {
//1. 创建一个数据源对象
ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();
//2. 通过配置文件 mysql.properties 获取相关连接的信息
Properties properties = new Properties();
properties.load(new FileInputStream("src\\mysql.properties"));
//读取相关的属性值
String user = properties.getProperty("user");
String password = properties.getProperty("password");
String url = properties.getProperty("url");
String driver = properties.getProperty("driver");
//给数据源 comboPooledDataSource 设置相关的参数
//注意:连接管理是由 comboPooledDataSource来管理 , 所以连接池一定要知道连上数据库的相关信息
comboPooledDataSource.setDriverClass(driver);
comboPooledDataSource.setJdbcUrl(url);
comboPooledDataSource.setUser(user);
comboPooledDataSource.setPassword(password);
//设置连接池创建的时候的初始化连接对象的个数
comboPooledDataSource.setInitialPoolSize(10);
//最大连接数 ,超过最大连接数 , 就需要进入等待队列
comboPooledDataSource.setMaxPoolSize(50);
//测试连接池的效率, 测试对 mysql 5000 次操作
long start = System.currentTimeMillis();
for (int i = 0; i < 5000; i++) {
//getConnection方法就是 ComboPooledDataSource类 实现 DataSource接口用来获取连接对象的方法
Connection connection = comboPooledDataSource.getConnection();
//这个close方法只是把连接对象放回连接池 , 并不是真正的关闭和数据库连接的通道
connection.close();
}
long end = System.currentTimeMillis();
//使用c3p0的方式连接5000次mysql 耗时=391
System.out.println("c3p0 5000 连接 mysql 耗时=" + (end - start));
}
第二种方式使用配置文件模板来完成 , 创建c3p0-config.xml文件(文件的名称和位置是固定的)
<c3p0-config>
<named-config name="hsp_edu">
<property name="driverClass">com.mysql.jdbc.Driverproperty>
<property name="jdbcUrl">jdbc:mysql://127.0.0.1:3306/hsp_db02property>
<property name="user">rootproperty>
<property name="password">hspproperty>
<property name="acquireIncrement">5property>
<property name="initialPoolSize">10property>
<property name="minPoolSize">5property>
<property name="maxPoolSize">50property>
<property name="maxStatements">5property>
<property name="maxStatementsPerConnection">2property>
named-config>
c3p0-config>
使用C3P0的方式连接数据库
@Test
public void testC3P0_02() throws SQLException {
//根据数据源的名称创建指定的连接池
//程序需要读取配置文件中的数据源的名称 , 根据数据源的参数信息创建连接池 , 就一定要知道文件的名称和位置
ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource("hsp_edu");
//测试 5000 次连接 mysql
long start = System.currentTimeMillis();
System.out.println("开始执行....");
for (int i = 0; i < 500000; i++) {
//因为连接池的参数的相关参数已经设值好了 , 所以可以直接从连接池中拿到连接对象
Connection connection = comboPooledDataSource.getConnection();
connection.close();
}
long end = System.currentTimeMillis();
//使用c3p0连接数据库的第二种方式 耗时=413
System.out.println("c3p0 5000 连接 mysql 耗时=" + (end - start));
}
导入Druid的 jar 包 druid-1.1.10.jar并添加到classpath下 , 这个**jar包中的DataSource类实现了javax.sql.DataSource接口 **
**创建配置文件 druid.properties , 并将该文件放到项目的 src 类路径下 **
#key=value
#驱动类
driverClassName=com.mysql.jdbc.Driver
#url
url=jdbc:mysql://localhost:3306/hsp_db02?rewriteBatchedStatements=true
#用户名
username=root
#密码
password=hsp
#initial connection Size (初始化连接数)
initialSize=10
#min idle connecton size(最小空闲连接对象个数)
minIdle=5
#max active connection size(最大连接对象个数)
maxActive=50
#max wait time (5000 mil seconds)(最大等待时间 , 如果规定时间内等不到就会放弃等下次再来)
maxWait=5000
使用德鲁伊的方式连接数据库
public void testDruid() throws Exception {
//创建 Properties 对象, 读取配置文件
Properties properties = new Properties();
properties.load(new FileInputStream("src\\druid.properties"));
//根据配置文件的相关参数初始化一个数据库连接池, Druid 连接池
DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);
//测试 5000 次连接 mysql
long start = System.currentTimeMillis();
for (int i = 0; i < 500000; i++) {
//从连接池中拿到连接对象
Connection connection = dataSource.getConnection();
connection.close();
}
long end = System.currentTimeMillis();
//druid连接池操作5000次连接, 耗时=412
System.out.println("druid 连接池 操作 500000 耗时=" + (end - start));
}
将 JDBCUtils 工具类改成 由Druid(德鲁伊)数据库连接池获取连接对象
public class JDBCUtilsByDruid {
private static DataSource;
//在静态代码块完成数据源(连接池)的初始化
static {
Properties properties = new Properties();
try {
properties.load(new FileInputStream("src\\druid.properties"));
//创建连接池
ds = DruidDataSourceFactory.createDataSource(properties);
} catch (Exception e) {
e.printStackTrace();
}
}
//编写 getConnection 方法
public static Connection getConnection() throws SQLException {
return ds.getConnection();
}
//关闭连接, 在数据库连接池技术中,close 不是真的断掉连接而是把使用的 Connection 对象放回连接池
//由连接池创建的连接对象的close方法是把连接对象放回连接池 , 由数据库厂商创建的Connectio对象的close方法是真正关闭程序和数据库的连接通道
public static void close(ResultSet resultSet, Statement statement, Connection connection)
try {
if (resultSet != null) {
resultSet.close();
}
if (statement != null) {
statement.close();
}
if (connection != null) {
connection.close();
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
测试封装的工具类
@Test
public void testSelect() {
//1. 得到连接
Connection connection = null;
//2. 组织一个 sql
String sql = "select * from actor where id >= ?";
PreparedStatement preparedStatement = null;
ResultSet set = null;
//3. 创建 PreparedStatement 对象
try {
connection = JDBCUtilsByDruid.getConnection();
//德鲁伊实现DataSource后拿到的Connection对象的运行类型com.alibaba.druid.pool.DruidPooledConnection
//不使用数据库连接池获得的Connection对象的运行类型com.mysql.jdbc.JDBCConnection
System.out.println(connection.getClass());
preparedStatement = connection.prepareStatement(sql);
//给?号赋值
preparedStatement.setInt(1, 1);
//执行, 得到结果集
set = preparedStatement.executeQuery();
//遍历该结果集
while (set.next()) {
int id = set.getInt("id");
String name = set.getString("name");//getName()
String sex = set.getString("sex");//getSex()
Date borndate = set.getDate("borndate");
String phone = set.getString("phone");
System.out.println(id + "\t" + name + "\t" + sex + "\t" + borndate + "\t" + phone);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
//关闭资源
JDBCUtilsByDruid.close(set, preparedStatement, connection);
}
}