【Java面试题】数据库连接池Java代码实现

来源:互联网 发布:js获取flv的帧图片 编辑:程序博客网 时间:2024/06/06 10:05

今天复习一下数据库连接池的实现


优秀博客:http://blog.csdn.net/mlc1218559742/article/details/54955965

http://www.cnblogs.com/xdp-gacl/p/4002804.html


代码

/** * 自定义连接池, 管理连接 * 代码实现:1.  MyPool.java  连接池类,   2.  指定全局参数:  初始化数目、最大连接数、当前连接、   连接池集合3.  构造函数:循环创建3个连接4.  写一个创建连接的方法5.  获取连接------>  判断: 池中有连接, 直接拿 ------>                池中没有连接,------>                 判断,是否达到最大连接数; 达到,抛出异常;没有达到最大连接数,创建新的连接6. 释放连接 ------->  连接放回集合中(..) * */public class MyPool {private int init_count = 3;// 初始化连接数目private int max_count = 6;// 最大连接数private int current_count = 0;  // 记录当前使用连接数// 连接池 (存放所有的初始化连接)private LinkedList<Connection> pool = new LinkedList<Connection>();//1.  构造函数中,初始化连接放入连接池public MyPool() {// 初始化连接for (int i=0; i<init_count; i++){// 记录当前连接数目current_count++;// 创建原始的连接对象Connection con = createConnection();// 把连接加入连接池pool.addLast(con);}}//2. 创建一个新的连接的方法private Connection createConnection(){try {Class.forName("com.mysql.jdbc.Driver");// 原始的目标对象final Connection con = DriverManager.getConnection("jdbc:mysql:///jdbc_demo", "root", "root");/**********对con对象代理**************/// 对con创建其代理对象Connection proxy = (Connection) Proxy.newProxyInstance(con.getClass().getClassLoader(),    // 类加载器//con.getClass().getInterfaces(),   // 当目标对象是一个具体的类的时候,但是这里con是一个接口new Class[]{Connection.class},      // 目标对象实现的接口new InvocationHandler() {// 当调用con对象方法的时候, 自动触发事务处理器@Overridepublic Object invoke(Object proxy, Method method, Object[] args)throws Throwable {// 方法返回值Object result = null;// 当前执行的方法的方法名String methodName = method.getName();// 判断当执行了close方法的时候,把连接放入连接池if ("close".equals(methodName)) {System.out.println("begin:当前执行close方法开始!");// 连接放入连接池pool.addLast(con);System.out.println("end: 当前连接已经放入连接池了!");} else {// 调用目标对象方法result = method.invoke(con, args);}return result;}});return proxy;} catch (Exception e) {throw new RuntimeException(e);}}//3. 获取连接public Connection getConnection(){// 3.1 判断连接池中是否有连接, 如果有连接,就直接从连接池取出if (pool.size() > 0){return pool.removeFirst();}// 3.2 连接池中没有连接: 判断,如果没有达到最大连接数,创建;if (current_count < max_count) {// 记录当前使用的连接数current_count++;// 创建连接return createConnection();}// 3.3 如果当前已经达到最大连接数,抛出异常throw new RuntimeException("当前连接已经达到最大连接数目 !");}//4. 释放连接public void realeaseConnection(Connection con) {// 4.1 判断: 池的数目如果小于初始化连接,就放入池中if (pool.size() < init_count){pool.addLast(con);} else {try {// 4.2 关闭 current_count--;con.close();} catch (SQLException e) {throw new RuntimeException(e);}}}public static void main(String[] args) throws SQLException {MyPool pool = new MyPool();System.out.println("当前连接: " + pool.current_count);  // 3// 使用连接pool.getConnection();pool.getConnection();Connection con4 = pool.getConnection();Connection con3 = pool.getConnection();Connection con2 = pool.getConnection();Connection con1 = pool.getConnection();// 释放连接, 连接放回连接池//pool.realeaseConnection(con1);/* * 希望:当关闭连接的时候,要把连接放入连接池!【当调用Connection接口的close方法时候,希望触发pool.addLast(con);操作】 * 把连接放入连接池 * 解决1:实现Connection接口,重写close方法 * 解决2:动态代理 */con1.close();// 再获取pool.getConnection();System.out.println("连接池:" + pool.pool.size());      // 0System.out.println("当前连接: " + pool.current_count);  // 3}}