数据库连接池
德鲁伊
/**
*
* 数据库连接池 - Druid德鲁伊
* 1.引入相关jar包 druid-1.1.10.jar
* 2.druid.properties文件 文件可以与当前类在同包路径下
* 3.DruidDataSourceFactory的API中static DataSource createDataSource(Properties properties)
* 4.获取连接对象,按照JDBC的步骤正常使用
* 5.归还连接对象,调用DruidPooledConnection的close()归还
*/
public class DruidDemo {
public static void main(String[] args) throws IOException {
//1.获取与当前类同级目录下的流对象
InputStream is = DruidDemo.class.getResourceAsStream("druid.properties");
//2.加载properties文件
Properties properties = new Properties();
properties.load(is);
DruidPooledConnection connection = null;
DruidPooledConnection connection1 = null;
PreparedStatement ppst = null;
try {
//3.获取Druid数据源 DruidDataSource
DruidDataSource dataSource = (DruidDataSource)DruidDataSourceFactory.createDataSource(properties);
//4.获取连接对象
connection = dataSource.getConnection();
//connection = com.mysql.jdbc.JDBC4Connection@5f8ed237
System.out.println("connection = "+connection);
//5.获得语句对象
String sql = "delete from girl where name=?";
ppst = connection.prepareStatement(sql);
ppst.setString(1,"小兰");
//6.执行SQL
int i = ppst.executeUpdate();
System.out.println(i>0?"删除成功":"删除失败");
//测试情况二:上方已获取连接,且归还连接,连接池中只有一个连接,现在再次获取连接,查看情况
//出现情况:下方可以正常获取连接对象,且是同一个连接对象 connection = com.mysql.jdbc.JDBC4Connection@5f8ed237
//此时不是物理上的关闭,而是回收至连接池中
/*if(connection!=null){
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}*/
//测试情况一:上方已获取连接,且未归还连接,连接池中只有一个连接,现在再次获取连接,查看情况
//出现报错情况:GetConnectionTimeoutException: wait millis 1000, active 1, maxActive 1, creating 0
/*connection1 = dataSource.getConnection();
System.out.println("connection1 = "+connection1);*/
} catch (Exception e) {
e.printStackTrace();
} finally {
//DruidPooledConnection重写的close(),并不是物理上的关闭,而是回收至连接池中
if(connection!=null){
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(ppst!=null){
try {
ppst.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
C3P0
/**
*
* 数据库连接池 - C3P0数据源
* 1.引入jar包 c3p0-0.9.1.2.jar
* 2.核心类 ComboPooledDataSource类中的构造方法,指定xml中的config-name来创建数据源对象
* 3.获取连接对象,按照JDBC的步骤正常使用
* 4.释放连接对象,归还至连接池中(语句对象、结果集对象都会同步释放资源)
*/
public class C3P0Demo {
public static void main(String[] args){
//1.创建数据源 无参构造方法,使用的是xml中default-config ; 若是有参构造方法,则使用与xml对应的named-config
ComboPooledDataSource pool = new ComboPooledDataSource("mysql");
//2.获得连接对象
Connection connection = null;
Connection connection1 = null;
PreparedStatement ppst = null;
ResultSet rs = null;
try {
connection = pool.getConnection();
//com.mchange.v2.c3p0.impl.NewProxyConnection@2437c6dc
System.out.println("connection = "+connection);
//3.获得语句对象,执行SQL
String sql = "select name from girl where id = ?";
ppst = connection.prepareStatement(sql);
ppst.setInt(1,10);
rs = ppst.executeQuery();
while (rs.next()){
String name = rs.getString(1);
System.out.println("name = "+name);
}
/*//测试二:上方已获取连接,且xml配置文件中只允许获取一个连接,此时归还连接后,再次尝试获取连接,将出现结果
//在归还连接至池子中后,可以再次获取连接对象进行使用的
//释放连接,将连接归还至连接池中(关闭结果集、关闭语句对象)
if(connection!=null){
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
//测试一:上方已获取连接,且xml配置文件中只允许获取一个连接,再次尝试获取连接,将出现结果
//报出异常信息:An attempt by a client to checkout a Connection has timed out.
connection1 = pool.getConnection();
System.out.println("connection1 = "+connection1);*/
} catch (SQLException e) {
e.printStackTrace();
} finally {
//释放连接,将连接归还至连接池中(关闭结果集、关闭语句对象)
if(connection!=null){
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
自定义连接池
/**
* 自定义连接池
*
* 连接池的特点:
* 1.预定义一些连接,放入连接池中
* 2.关闭连接,并不是真正释放连接,将连接归还到池子中
*
* 自定义连接池:
* 1.首先定义一个容器,放置连接对象,即"池子"
* 2.重写获得连接的方法,每次拿取池子中的第一个连接
* 3.重写释放连接的方法,每次关闭连接,相当于给池子中放回连接
*/
public class MyDataSource implements DataSource {
//自定义的连接池
private LinkedList<Connection> pool;
public MyDataSource(){
pool = new LinkedList<>();
//预先放置连接对象
for (int i = 0; i < 5; i++) {
pool.add(JDBCUtils.getConn());
}
}
//获取连接
@Override
public Connection getConnection() throws SQLException {
Connection connection = pool.removeFirst();
return connection;
}
//释放连接:并不是真正释放连接,将连接归还到池子中
public void close(Connection conn){
pool.addLast(conn);
}
@Override
public Connection getConnection(String username, String password) throws SQLException {
return null;
}
@Override
public <T> T unwrap(Class<T> iface) throws SQLException {
return null;
}
@Override
public boolean isWrapperFor(Class<?> iface) throws SQLException {
return false;
}
@Override
public PrintWriter getLogWriter() throws SQLException {
return null;
}
@Override
public void setLogWriter(PrintWriter out) throws SQLException {
}
@Override
public void setLoginTimeout(int seconds) throws SQLException {
}
@Override
public int getLoginTimeout() throws SQLException {
return 0;
}
@Override
public Logger getParentLogger() throws SQLFeatureNotSupportedException {
return null;
}
}
**
* 测试自定义的连接池
*/
public class MyDataSourceTest {
public static void main(String[] args) throws SQLException {
//创建数据源
MyDataSource dataSource = new MyDataSource();
Connection connection1 = dataSource.getConnection();
System.out.println(connection1);
Connection connection2 = dataSource.getConnection();
System.out.println(connection2);
Connection connection3 = dataSource.getConnection();
System.out.println(connection3);
Connection connection4 = dataSource.getConnection();
System.out.println(connection4);
Connection connection5 = dataSource.getConnection();
System.out.println(connection5);
try {
//从连接池中获取连接对象
//Connection connection = dataSource.getConnection();
String sql = "delete from girl where name = ?";
//预编译SQL
PreparedStatement ppst = connection1.prepareStatement(sql);
//给?占位符传值
ppst.setString(1,"小小");
//执行
int i = ppst.executeUpdate();
System.out.println(i>0?"删除成功":"删除失败");
//将连接归还到池子中
dataSource.close(connection1);
} catch (SQLException e) {
e.printStackTrace();
}
Connection connection6 = dataSource.getConnection();
System.out.println(connection6);
}
}