jdbc连接池原理,自定义jdbc连接池

我们通常用jdbc连接数据库,频繁的建立建立连接,关闭资源是非常耗费资源,因此我们就想到了建立一个连接池,先在池中预存一些连接,我们需要时就从连接池中取用,用完之后不是关闭资源连接,而是放回去。

首先是大体项目结构,这里我没有在dao包中写SQL操作,为了方便我写在了测试类中,实际开发是需要提取出来的。

自定义连接池:

创建ConfigManager类,这个类是专门用来读取配置文件信息的。因为配置文件读取一次就行了,因此就将该类设计为单例模式,里面定义了两个方法,整个类是这样写的:

public class ConfigManager {
	//这个类就是读取配置文件的
	Properties prop=new Properties();
	private static ConfigManager configManager;
	private ConfigManager(){
		//读配置文件,用流的方式
		InputStream is = ConfigManager.class.getClassLoader().getResourceAsStream("database.properties");
		try {
			prop.load(is);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	public static ConfigManager getInstance(){
		if (configManager==null) {
			configManager=new ConfigManager();
		}
		return configManager;
	}
	public String getValue(String key){
		return prop.getProperty(key);
	}
}

创建JDBCUtil类,该类可以获得连接

public class JDBCUtil {
	//获取连接
	public  static Connection getConnection() throws ClassNotFoundException, SQLException{
		ConfigManager it = ConfigManager.getInstance();
		String driver = it.getValue("driver");
		String url=it.getValue("url");
		String username = it.getValue("username");
		String password = it.getValue("password");	
		Class.forName(driver);
		Connection conn=DriverManager.getConnection(url,username,password);
		return conn;
	}	
}

创建连接池类MyconnectionPool,将池子的初始容量设为5,每次三个三个的扩容。

public class MyConnectionPool {
	//模拟连接池
	public static LinkedList<Connection>list=new LinkedList<Connection>();
	//初始化连接池,往连接池里放五个连接
	static {
		for (int i = 0; i < 5; i++) {			
					Connection conn;
					try {
						conn = JDBCUtil.getConnection();
						list.add(conn);
					} catch (ClassNotFoundException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (SQLException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					
							
		}
	}
	//从连接池中取出连接
	public static Connection getConnection() throws ClassNotFoundException, SQLException{
		if (list.isEmpty()) {
			for (int i = 0; i < 3; i++) {
				Connection conn = JDBCUtil.getConnection();
				list.add(conn);
			}			
		}
		return list.removeFirst();
	}
	//关闭,以前我们是关闭资源,现在我们需要把资源(连接)放回连接池中
	public void addback(Connection conn){
		list.addFirst(conn);
	}
}

准备工作已经完成,编写测试类测试,

public class Test {

	@org.junit.Test
	public void test() {
		//测试自定义连接池
		Connection conn=null;
		try {
			conn = MyConnectionPool.getConnection();
			String sql="select * from news_user where id=?";
			PreparedStatement prpt = conn.prepareStatement(sql);
			prpt.setInt(1, 2);
			ResultSet rs = prpt.executeQuery();
			if (rs.next()) {
				String str=rs.getString("username");
				System.out.println(str);
			}
		
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
			System.out.println("前"+MyConnectionPool.list.size());
			MyConnectionPool.addback(conn);
			System.out.println("后"+MyConnectionPool.list.size());
		
	}
}

 运行结果如下,通过输出连接池长度我们可以看出,我们确实可以从自定义的连接池中取出连接,并且可以将连接归还到池中。

 最后,这里还有一个问题,就是我们自定义了一个addback方法用于归还连接,我们习惯用Connection接口的close方法关闭资源,自定义方法会增加程序员的记忆量,因此我们想到能不能调用close方法就能实现归还连接而不是原本的关闭资源呢?

这里使用装饰者模式实现,笔者就不再赘述了。

猜你喜欢

转载自blog.csdn.net/anewmonkey/article/details/82530295
今日推荐