JDBC连接池

在使用JDBC时我们可以自己去创建一个工具类(JDBCUtils),每次来调用它的方法来获取连接或者来释放连接,具体该类的实现如下:

package JDBCUtils;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ResourceBundle;

//获取连接和释放资源的方法

public class JDBCUtils {
	private static String driver;
	private static String url;
	private static String username;
	private static String password;
	//静态代码块
	
	static {
		//读取配置文件
		ResourceBundle bundle=ResourceBundle.getBundle("db");
		//获取文件中的数据
		driver=bundle.getString("driver");
		url=bundle.getString("url");
		username=bundle.getString("username");
		password=bundle.getString("password");
	}
	//获取连接
	public static Connection getConnection() {
		Connection conn = null;
		try {
			Class.forName(driver);
			conn=DriverManager.getConnection(url, username, password);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return conn;
	}
	
	//释放资源
	public static  void  release(Connection  conn,PreparedStatement pstmt,ResultSet rs){
		if(rs!=null)
			try {
				rs.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		if(pstmt!=null)
			try {
				rs.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		if(conn!=null)
			try {
				rs.close();
			} catch (SQLException e){ 
				e.printStackTrace();
			}
	}
}

在这里我们使用配置文件来存储链接数据库所需要的信息,配置文件名为db.properties

这个类中有两个方法,一是来获取数据库的连接,二是来释放资源

但是,如果反复的创建资源释放资源,这会造成很大的浪费,所以,我们可以使用jdbc连接池来存放,在连接池中我们可以存放多个已经事先创建好的连接,每次使用时只需要取出来,使用完后再放回去,这样做提高了效率。

package DataSource;

import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.ArrayList;
import java.util.logging.Logger;

import javax.sql.DataSource;

import JDBCUtils.JDBCUtils;

public class MyDataSource implements DataSource{
	//创建集合用来存储conn
	private static ArrayList<Connection> pool=new ArrayList<>();
	
	//使用静态代码块创建5个连接放到连接池中
	static {
		Connection conn=null;
		for(int i=0;i<5;i++) {
			conn=JDBCUtils.getConnection();
			pool.add(conn);
		}
	}
	
	//写返回类
	@Override
	public Connection getConnection() throws SQLException {
		Connection conn=null;
		//判断是否为空
		if(pool==null) {
			for(int i=0;i<5;i++) {
				conn=JDBCUtils.getConnection();
				pool.add(conn);
			}
		}
		//删除第一个
		conn=pool.remove(0);
		return conn;
	}
	
	//写回收方法
	public void backConnection(Connection conn){
		pool.add(conn);
	}

    //!!!!.....此处省略了很多需要写上的类

}

创建连接池的大概思路就是,我们先创建一个集合(池),然后通过静态代码块创建多个(上段代码创建了5个)连接,然后将他们全部放到集合中,如果每次要获得连接,直接从集合中取出一个,使用完后再调用这个类中的返回方法将连接归还

这是测试类:

public class TestMyDataSource {

	@Test
	public void Test() {
		Connection conn=null;
		PreparedStatement pstmt=null;
		MyDataSource datasource=new MyDataSource();
		
		try {
			//获取连接
			conn=datasource.getConnection();
			String sql="insert into t_user values(null,?,?)";
			pstmt=conn.prepareStatement(sql);
			pstmt.setString(1,"aaa"); 
			pstmt.setString(2,"666");
			int x=pstmt.executeUpdate();
			if(x>0) {
				System.out.println("操作成功");
			}else {
				System.out.println("操作失败");
			}
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			datasource.backConnection(conn);
		}
	}
}

通过测试,成功的将数据填入数据库中。

 

这是一种使用连接池的方法,如果我们要在最后依然习惯性的调用JDBCUtils中的方法release方法,但是这样就会释放连接,我们想让他中的close方法不是释放而是归还,那么我们就需要重写这个方法,首先创建一个Connection类

package DataSource;

import java.sql.Array;
import java.sql.Blob;
import java.sql.CallableStatement;
import java.sql.Clob;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.NClob;
import java.sql.PreparedStatement;
import java.sql.SQLClientInfoException;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.SQLXML;
import java.sql.Savepoint;
import java.sql.Statement;
import java.sql.Struct;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.Executor;

public class MyConnection implements Connection{
	
	private Connection conn;
	private ArrayList<Connection> pool;
	
	public MyConnection(Connection conn,ArrayList<Connection> pool){
		this.conn=conn;
		this.pool=pool;
	}

	@Override
	public PreparedStatement prepareStatement(String sql) throws SQLException {
		return conn.prepareStatement(sql);
	}
	
	@Override
	public void close() throws SQLException {
		pool.add(conn);
	}
	//!!!、、、、、此处省略了许多必须存在的方法
}

这里我们床架一个类,实际这个类就是对conn连接的一个封装,我们再写一个创建连接池的类,和上一个差不多

package DataSource;

import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.ArrayList;
import java.util.logging.Logger;

import javax.sql.DataSource;

import JDBCUtils.JDBCUtils;

public class MyDataSource1 implements DataSource{
	//创建集合用来存储conn
	private static ArrayList<Connection> pool=new ArrayList<>();
	
	//使用静态代码块创建5个连接放到连接池中
	static {
		Connection conn=null;
		for(int i=0;i<5;i++) {
			conn=JDBCUtils.getConnection();
			MyConnection myconn=new MyConnection(conn, pool);
			pool.add(myconn);
		}
	}
	
	//写返回类
	@Override
	public Connection getConnection() throws SQLException {
		Connection conn=null;
		//判断是否为空
		if(pool==null) {
			for(int i=0;i<5;i++) {
				conn=JDBCUtils.getConnection();
			    MyConnection myconn=new MyConnection(conn, pool);
			    pool.add(myconn);
			}
		}
		//删除第一个
		conn=pool.remove(0);
		return conn;
	}

    //此处省略多个必须存在方法

}

实际我们可以看到我们现在通过这个方法所得到的conn连接实际不是Connection了解,而是他的子类MyConnection,是一个封装对象,我们再得到它后,就对它进行使用

        @Test
		public void Test1() {
			Connection myconn=null;
			PreparedStatement pstmt=null;
			MyDataSource1 datasource1=new MyDataSource1();
			
			try {
				//获取连接
				myconn=datasource1.getConnection();
				String sql="insert into t_user values(null,?,?)";
				pstmt=myconn.prepareStatement(sql);
				pstmt.setString(1,"wae1"); 
				pstmt.setString(2,"6661");
				int x=pstmt.executeUpdate();
				if(x>0) {
					System.out.println("操作成功");
				}else {
					System.out.println("操作失败");
				}
			} catch (Exception e) {
				e.printStackTrace();
			}finally {
				JDBCUtils.release(myconn, pstmt, null);
			}
		}

通过测试,成功的添加了信息到数据库中,起始在全部过程中,我们所操作的只是Connection的封装类,并没有操作实际的Connec,最后调用JDBCUtils中的release方法,它中有close方法,再调用MyConnection中的close将连接放回连接池中。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值