连接池

连接池

在这里插入图片描述
在一次查询操作中,60%以上的时间是用于创建数据库连接上了,为了提高执行效率,可以考虑减少创建数据库连接的时间
因为没有办法降低一次创建连接所用时长,所以考虑采用共享的方式降低平均使用成本。典型应用有线程池。
数据库连接池的基本思想是:为数据库连接建立一个“缓冲池”,预先在池中放入一定数量的数据库连接管道,需要时,从池子中取出管道进行使用,操作完毕后,在将管道放入池子中,从而避免了频繁的向数据库申请资源,释放资源带来的性能损耗。同时一般会有一个守护线程定期检查空闲连接是否可用,如果连接已经不稳定则释放连接对象.

public class JdbcService {
//使用单例保证连接池只有一个
	private JdbcUtil() { 	}
	private static JdbcUtil ju = new JdbcUtil();
	public static JdbcUtil getInstance() {
		return ju;
	}

	private static List<Connection> pool;   //具体的连接池容器,集合的最佳选择可以考虑使用阻塞队列
	private static final int MAX_SIZE = 10;  //连接池的相关参数,实际上还有其他的数据,例如最小连接池、最大空闲时间等
// 实际上还应该有守护线程定期检查连接对象的可用性,如果连接对象不可用则需要释放连接
	static {   //使用静态块,所以没有线程安全问题
		pool = Collections.synchronizedList(new ArrayList<>());  //初始化连接池
		try {
			Class.forName("com.mysql.cj.jdbc.Driver");  
			for (int i = 0; i < 3; i++) {
				Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test?serverTimezone=UTC",
						"root", "123456");
				pool.add(conn);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public Connection getConnection() throws SQLException {
		Connection conn = null;
		if (pool.size() > 0)  //如果池中包含连接对象,则直接获取,而不是新建
			conn = pool.remove(pool.size() - 1);
		else   //如果池中没有连接【而且没有到达连接数上限】,则新建对象
			conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test?serverTimezone=UTC", "root", "123456");
		// 如果创建个数大于上限,则应该阻塞当前线程或者使用自旋锁再来获取连接
		return conn;
	}
// 连接使用完毕不是关闭连接,而是释放连接到连接池中。具体开发中可以考虑使用代理模式【JavaSE中23种设计模式之一】
	public void realseConnection(Connection conn) throws SQLException {
		if (conn != null)
			if (pool.size() < MAX_SIZE)  //如果连接池中的连接对象没有到达上限,则归还连接到连接池中。如果到达上限则关闭连接
				pool.add(conn);
			else
				conn.close();
	}

	public void close(ResultSet rs, PreparedStatement ps, Connection conn) throws Exception {
		try {
			if (rs != null) {
				rs.close();
			}
		} finally {
			try {
				if (ps != null) {
					ps.close();
				}
			} finally {
				if (conn != null) {
					realseConnection(conn);
				}
			}
		}
	}

	public PreparedStatement createPreparedStatement(Connection conn, String sql, Object... params) throws Exception {

		PreparedStatement ps = conn.prepareStatement(sql);
		if (params != null && params.length > 0) {
			for (int i = 0; i < params.length; i++) {
				ps.setObject(i + 1, params[i]); // 不确定数据类型
			}
		}
		return ps;
	}

	public int executeUpdate(Connection conn, String sql, Object... params) throws Exception {
		PreparedStatement ps = createPreparedStatement(conn, sql, params);
		return ps.executeUpdate();
	}

	public ResultSet executeQuery(Connection conn, String sql, Object... params) throws Exception {
		PreparedStatement ps = createPreparedStatement(conn, sql, params);
		return ps.executeQuery();
	}

}

连接池的基本原理

在内部对象池中,维护一定数量的数据库连接,并对外暴露数据库连接的获取和返回方法。如外部使用者可通过getConnection方法获取数据库连接,使用完毕后再通过releaseConnection方法将连接返回,注意此时的连接并没有关闭,而是由连接池管理器回收,并为下一次使用做好准备。
连接池同时负责定期检查连接的可用性,并保证最大空闲时间。

连接池的作用

1、资源重用
2、更快的系统响应速度
3、新的资源分配手段
4、统一的连接管理,避免数据库连接泄露

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值