以前我们是java通过api(也就是jdbc)然后获取mysql的驱动,直接去连数据库了
现在我们中间又放了一个连接池。这个时候就是用连接池来连接数据库了。
一、数据库连接池概念
数据库连接池:负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个;释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接遗漏。这项技术能明显提高对数据库操作的性能。
数据库连接池在初始化时将创建一定数量的数据库连接放到连接池中,这些数据库连接的数量是由最小数据库连接数制约。无论这些数据库连接是否被使用,连接池都将一直保证至少拥有这么多的连接数量。连接池的最大数据库连接数量限定了这个连接池能占有的最大连接数,当应用程序向连接池请求的连接数超过最大连接数量时,这些请求将被加入到等待队列中。数据库连接池的最小连接数和最大连接数的设置要考虑到下列几个因素:
- 最小连接数
是连接池一直保持的数据库连接,所以如果应用程序对数据库连接的使用量不大,将会有大量的数据库连接资源被浪费。
- 最大连接数
是连接池能申请的最大连接数,如果数据库连接请求超过此数,后面的数据库连接请求将被加入到等待队列中,这会影响之后的数据库操作。
- 最小连接数与最大连接数差距
最小连接数与最大连接数相差太大,那么最先的连接请求将会获利,之后超过最小连接数量的连接请求等价于建立一个新的数据库连接。不过,这些大于最小连接数的数据库连接在使用完不会马上被释放,它将被放到连接池中等待重复使用或是空闲超时后被释放。
五、实现
一般来说,Java应用程序访问数据库的过程:
1、装载数据库驱动程序;
2、通过jdbc创建数据库连接;
3、访问数据库,执行sql语句;
4、关闭数据库连接。
编写连接池需实现java.sql.DataSource接口。DataSource接口中定义了两个重载的getConnection方法:
· Connection getConnection()
· Connection getConnection(String username, String password)
实现DataSource接口,并实现连接池功能的步骤:
- 在DataSource构造函数中批量创建与数据库的连接,并把创建的连接加入LinkedList对象中。
- 实现getConnection方法,让getConnection方法每次调用时,从LinkedList中取一个Connection返回给用户。
- 当用户使用完Connection,调用Connection.close()方法时,Collection对象应保证将自己返回到LinkedList中,而不要把conn还给数据库。Collection保证将自己返回到LinkedList中是此处编程的难点。
package com.example.jdbcConnection;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Liuxd on 2018/8/19.
*/
public class TestC3p0 {
private static Connection conn;
private static ComboPooledDataSource dataSource;
static {
try {
//获得c3p0连接池对象
dataSource = new ComboPooledDataSource();
dataSource.setUser("root");
dataSource.setPassword("root");
dataSource.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/foo?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2b8&useSSL=false");
dataSource.setDriverClass("com.mysql.jdbc.Driver");
dataSource.setInitialPoolSize(2);//初始化池大小
dataSource.setMaxIdleTime(30);//最大空闲时间
dataSource.setMaxPoolSize(20);//最多连接数
dataSource.setMinPoolSize(2);//最少连接数
dataSource.setMaxStatements(50);//每次最多可以执行多少个批处理语句
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 查询
*/
private static List<Object[]> query() {
List<Object[]> list = new ArrayList<Object[]>();
try {
// 获取数据库连接
conn = dataSource.getConnection();
// 查询sql
String sql = "select * from user";
// 读取数据
PreparedStatement preparedStatement = conn.prepareStatement(sql);
//结果集
ResultSet resultSet = preparedStatement.executeQuery();
while (resultSet.next()) {
int uid = resultSet.getInt("uid");
String name = resultSet.getString("name");
Integer age = resultSet.getInt("age");
String phone = resultSet.getString("phone");
String passwd = resultSet.getString("passwd");
Object[] objects = new Object[]{uid, name, age, phone, passwd};
list.add(objects);
}
resultSet.close();
preparedStatement.close();
//Connection连接对象归还数据库连接池
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
return list;
}
/**
* 新增
*/
private static void add(String name, int age, String phone, String passwd) {
try {
// 获取数据库连接
conn = dataSource.getConnection();
String insertSql = "insert into `user` (`name`, `age`, `phone`, `passwd`) values(?,?,?,?)";
PreparedStatement ps = conn.prepareStatement(insertSql);
ps.setString(1, name);
ps.setInt(2, age);
ps.setString(3, phone);
ps.setString(4, passwd);
int row = ps.executeUpdate();
System.out.println("新增结果: " + row);
ps.close();
//Connection连接对象归还数据库连接池
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 修改
*/
private static void update(int uid, String name, int age, String phone, String passwd) {
try {
// 获取数据库连接
conn = dataSource.getConnection();
String updateSql = "UPDATE USER t SET t.name=? ,t.age=?,t.phone=?,t.passwd=? WHERE t.uid=?";
PreparedStatement preparedStatement = conn.prepareStatement(updateSql);
preparedStatement.setString(1, name);
preparedStatement.setInt(2, age);
preparedStatement.setString(3, phone);
preparedStatement.setString(4, passwd);
preparedStatement.setLong(5, uid);
// 执行sql
preparedStatement.executeUpdate();
int row = preparedStatement.executeUpdate();
System.out.println("修改结果: " + row);
//Connection连接对象归还数据库连接池
conn.close();
preparedStatement.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 删除
*/
private static void deleteById(int uid) {
try {
// 获取数据库连接
conn = dataSource.getConnection();
String sql = "delete from USER where uid=?";
PreparedStatement preparedStatement = conn.prepareStatement(sql);
preparedStatement.setInt(1, uid);
int row = preparedStatement.executeUpdate();
System.out.println("删除结果: " + row);
preparedStatement.close();
//Connection连接对象归还数据库连接池
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
/**
* 1、验证连接数
*/
for (int i = 0; i < 10; i++) {
Connection connection = null;
try {
connection = dataSource.getConnection();
System.out.println(connection.toString());
} catch (SQLException e) {
e.printStackTrace();
} finally {
if (null != connection) {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
/**
* 2、查询
*/
List<Object[]> list = query();
if (null != list && list.size() > 0) {
for (int i = 0; i < list.size(); i++) {
Object[] objects = list.get(i);
for (int j = 0; j < objects.length; j++) {
System.out.print(objects[j] + " ");
}
System.out.println();
}
}
/**
* 3、新增
*/
String name = "乐乐";
int age = 17;
String phone = "13800138001";
String passwd = "admin123";
add(name, age, phone, passwd);
/**
* 4、修改
*/
update(12, name, age, phone, passwd);
/**
* 5、删除
*/
deleteById(3);
}
}