连接池

连接池的基本原理

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

连接池同时负责定期检查连接的可用性,并保证最大空闲时间。

连接池的作用

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

连接池

在一次查询操作中,60%以上的时间是用于创建数据库连接上了,为了提高执行效率,可以考虑减少创建数据库连接的时间。

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

编码简单实现

package com.user.util;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class 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;; //连接池的相关参数,实际上还有其他的数据,例如最小连接池、最大空闲时间等

// 实际上还应该有守护线程定期检查连接对象的可用性,如果连接对象不可用则需要释放连接
	private JdbcUtil() {}

	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/studentsystem?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/studentsystem?serverTimezone=UTC", "root",
					"123456");
		return conn;
	}

	public void realseConnection(Connection conn) throws SQLException {
		if (conn != null)
			if (pool.size() < MAX_SIZE)
				pool.add(conn);
			else
				conn.close();
	}

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

	public static PreparedStatement createPreparedStatement(Connection conn, String sql, Object... objects)
			throws SQLException {
		PreparedStatement ps = conn.prepareStatement(sql);
		if (objects != null && objects.length > 0)
			for (int i = 0; i < objects.length; i++)
				ps.setObject(i + 1, objects[i]);
		return ps;
	}

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值