自己动手写DataSource

       DataSource 对象所表示的物理数据源的连接。作为 DriverManager 工具的替代项。DataSource能提供最高性能的对数据库的并发访问,数据源技术是Java操作数据库的一个很关键技术,流行的持久化框架都离不开数据源的应用。

         数据源提供了一种简单获取数据库连接的方式,并能在内部通过一个池的机制来复用数据库连接,这样就大大减少了创建数据库连接的次数,提高了系统性能。下面,我们自己动手实现个精简的数据源,代码如下:

public class MyDataSource {
	private LinkedList<Connection> connectionPool = new LinkedList<Connection>();

	public MyDataSource() {
		for (int i = 0; i < 10; i++) {
			connectionPool.add(new MyConnection(creatConnection(),this));
		}
	}
	private Connection creatConnection() {
		try {
			return DriverManager.getConnection(
					"jdbc:mysql://localhost:3306/test", "root", "root");
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			throw new ExceptionInInitializerError();
		}
	}
	
	public Connection getConnection(){
		System.out.println(connectionPool.size());
		return connectionPool.removeFirst();
	}
	
	public void freeConnection(Connection conn){
		System.out.println("DataSource Close Connection");
		connectionPool.addLast(conn);
	}
}
 
public class MyConnection  implements Connection{
	private Connection connection;
	private MyDataSource datasource;
	public Connection getConnection() {
		return connection;
	}

	public void setConnection(Connection connection) {
		this.connection = connection;
	}

	public MyConnection(Connection realconnection,MyDataSource datasource){
		this.connection=realconnection;
		this.datasource=datasource;
	}
	
	@Override
	public void close() throws SQLException {
		// TODO Auto-generated method stub
		System.out.println("MyConnection Close");
		datasource.freeConnection(this);
	}
	...
}

        我们通过DataSource获得的Connection是经过包裹后的对象,这里应用到了代理模式。下面我们使用jdk的动态代理来改写MyDataSource:

public class MyDataSource {
	private LinkedList<Connection> connectionPool = new LinkedList<Connection>();

	public MyDataSource() {
		for (int i = 0; i < 10; i++) {
			connectionPool.add(GetProxy(creatConnection()));
		}
	}

	private Connection GetProxy(final Connection connection) {
		// TODO Auto-generated method stub
		return (Connection)Proxy.newProxyInstance(this.getClass().getClassLoader(), new Class[]{Connection.class}, new InvocationHandler(){
			@Override
			public Object invoke(Object proxy, Method method, Object[] args)
					throws Throwable {
				// TODO Auto-generated method stub
				Object value;
				if(method.getName().equalsIgnoreCase("close")){
					connectionPool.addLast((Connection)proxy);
					System.out.println(connectionPool.size());
					return null;
				}else{
					value=method.invoke(connection, args);
				}
				System.out.println(connectionPool.size());
				return value;
			}
			
		});
		
	}

	private Connection creatConnection() {
		try {
			return DriverManager.getConnection(
					"jdbc:mysql://localhost:3306/test", "root", "root");
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			throw new ExceptionInInitializerError();
		}
	}
	
	public Connection getConnection(){
		System.out.println(connectionPool.size());
		return connectionPool.removeFirst();
	}
	
	public void freeConnection(Connection conn){
		System.out.println("DataSource Close Connection");
		connectionPool.addLast(conn);
	}
}

       通过这种方式获得的Connection是通过jdk的动态代理生成的一个代理对象,该代理对象实现了Connection接口。

       以上两种方式实现了我们自己的DataSource,在我们通过DataSource获得的Connection对象的close方法都已经被改写过了。在Connection对象调用close方法时,会将该Connection对象放入到缓存池中,而不是关闭对象。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值