java旅行--第七站--spring--连接池

这是一个连接池的小例子,连接池需要实现DataSource接口,使用Object.class.getClassLoader().getResourceAsStream("")加载文件,然后new一个Properties的对象来装载输入流,读取所需要的配置信息,使用Collections.synchronizedList来保证线程安全,使用linkedList集合存取连接对象。
总体实现思路:使用DriverManager.getConnection来获得数据库连接,获取自定义的连接个数,然后将这些都add到集合中,然后当需要调用连接对象时,首先判断连接池的个数是不是大于0,是就把集合中连接池对象remove掉,同时把这个remove掉的对象赋给需要调用的程序,如果连接池中所剩的对象为0,则抛出运行时异常。当获得数据库连接对象后,就动态返回,动态返回时,当调用的是数据库的close方法,就把对象重新添加到集合中,否则返回原对象调用的方法,代码如下

package com.freshbin.pool;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;
import java.util.logging.Logger;

import javax.sql.DataSource;

public class JdbcPool implements DataSource {

	// 创建一个集合来保存所有的数据库连接,当程序需要连接数据库时,则从集合中获取,同时调用集合的remove方法
	// 因为集合的remove方法返回的正是你集合中的对象,所有正好可以将从集合中remove的连接对象赋给程序
	// 当关闭数据库时,则调用集合的add方法,将连接返回给集合
	// 使用Collections工具类,使集合是线程安全的
	private static List<Connection> connList = Collections
			.synchronizedList(new LinkedList<Connection>());

	static {
		// 通过java的反射加载配置文件
		InputStream is = JdbcPool.class.getClassLoader().getResourceAsStream(
				"conf/jdbc.properties");

		// 创建一个pro对象,方便从配置文件中读取文件
		Properties pro = new Properties();

		// 加载文件流,读取内容
		try {
			pro.load(is);
			String drive = pro.getProperty("driver");
			String url = pro.getProperty("url");
			String username = pro.getProperty("username");
			String password = pro.getProperty("password");
			int jdbcPoolInitSize = Integer.parseInt(pro
					.getProperty("jdbcPoolInitSize"));
			
			//加载驱动
			Class.forName(drive);
			for (int i = 0; i < jdbcPoolInitSize; i++) {
				Connection conn = DriverManager.getConnection(url, username, password);
				System.out.println("获取到了数据库连接:" + conn);
				//将数据库连接存到集合中
				connList.add(conn);
			}
			System.out.println("数据库连接池的总共个数:" + connList.size());
			System.out.println("----------------------------------------------------");
		} catch (Exception e) {
			throw new ExceptionInInitializerError(e);
		}
	}

	@Override
	public PrintWriter getLogWriter() throws SQLException {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public int getLoginTimeout() throws SQLException {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public Logger getParentLogger() throws SQLFeatureNotSupportedException {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void setLogWriter(PrintWriter out) throws SQLException {
		// TODO Auto-generated method stub

	}

	@Override
	public void setLoginTimeout(int seconds) throws SQLException {
		// TODO Auto-generated method stub

	}

	@Override
	public boolean isWrapperFor(Class<?> arg0) throws SQLException {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public <T> T unwrap(Class<T> arg0) throws SQLException {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Connection getConnection() throws SQLException {
		//首先判断集合中有没有空闲的数据库连接对象,如果没有则直接抛出异常,不再返回
		if(connList.size() > 0) {
			//返回一个连接对象,集合调用remove的同时即可返回一个对象
			final Connection conn = connList.remove(0);
			System.out.println("被拿走了一个连接:" + conn);
			System.out.println("数据库连接池的个数:" + connList.size());

			//使用动态代理返回
			return (Connection) Proxy.newProxyInstance(JdbcPool.class.getClassLoader(), conn.getClass().getInterfaces(), new InvocationHandler() {
				
				@Override
				public Object invoke(Object proxy, Method method, Object[] args)
						throws Throwable {
					//如果调用的是close方法,则将数据库连接对象重新加入到集合中
					if("close".equals(method.getName())) {
						connList.add(conn);
						System.out.println("数据库对象已回收:" + conn);
						System.out.println("连接池的个数:" + connList.size());
						System.out.println("----------------------------------------------------");
						return null;
					} else {
						return method.invoke(conn, args);
					}
				}
			});
		} else {
			throw new RuntimeException("暂时没有空闲的数据库对象可以使用!请等等。。。");
		}
	}

	@Override
	public Connection getConnection(String arg0, String arg1)
			throws SQLException {
		// TODO Auto-generated method stub
		return null;
	}

}

然后工具类兼测试类的代码如下

package com.freshbin.util;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import com.freshbin.pool.JdbcPool;

public class JdbcUtil {
	private static JdbcPool pool = new JdbcPool();

	public static Connection getConnection() throws SQLException {
		return pool.getConnection();
	}

	public static void close(Connection conn, Statement st, ResultSet rs) {
		if (rs != null) {
			try {
				// 关闭存储查询结果的ResultSet对象
				rs.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
			rs = null;
		}
		if (st != null) {
			try {
				// 关闭负责执行SQL命令的Statement对象
				st.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

		if (conn != null) {
			try {
				// 关闭Connection数据库连接对象
				conn.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
	
	public static void main(String[] args) {
		try {
			Connection conn = JdbcUtil.getConnection();
			System.out.println("拿连接:" + conn);
			
			System.out.println("-------------------------------");
			
			conn = JdbcUtil.getConnection();
			System.out.println("拿连接:" + conn);
			System.out.println("-------------------------------");
			
			JdbcUtil.close(conn, null, null);
			
			conn = JdbcUtil.getConnection();
			System.out.println("拿连接:" + conn);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值