jdbc连接池

1.1.1 什么是连接池

  • 连接池是创建和管理一个连接的缓冲池的技术,这些连接准备好被任何需要它们的线程使用。
  • 连接池是装有连接的容器,使用连接的话,可以从连接池中进行获取,使用完成之后将连接归还给连接池。

1.1.2为什么使用连接池

  • 连接对象创建和销毁是需要耗费时间的,在服务器初始化的时候就初始化一些连接。把这些连接放入到内存中,使用的时候可以从内存中获取,使用完成之后将连接放入连接池中。从内存中获取和归还的效率要远远高于创建和销毁的效率。(提升性能)。

1.1.3 连接池的工作原理

jdbc连接池_第1张图片

1.1.4自定义连接池的实现步骤(DataSource连接池的接口)

  • 1)编写一个类实现DataSource接口
  • 2)重写getConnection方法
  • 3)初始化多个连接在内存中
  • 4)编写归还连接的方法
  • 5)自定义连接池的代码实现
    jdbc连接池_第2张图片

连接池的代码:
jdbc连接池_第3张图片
代码:


package com.xk.jdbc.datasource;

import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;

import javax.sql.DataSource;

import com.xk.jdbc.utils.JDBCUtil;

/**
* @author: XuKe
* @time :2018年11月17日 下午9:17:22
* 
*/
public class MyDataSource implements DataSource {
	//将一些连接存入内存中,可以定义一个集合,用于存储连接对象。
	private List connList = new ArrayList();
	
	//在初始化的时候提供一些连接方法
	public MyDataSource() {
		//初始化连接
		for(int i= 0;i <=3;i++) {
			connList.add(JDBCUtil.getConn());
			
		}
	}
	
	//从连接池中获得一些连接的方法
	@Override
	public Connection getConnection() throws SQLException {
		Connection conn = connList.remove(0);
		return conn;
	}
	//自己写的归还连接对象的方法
	public void addBack(Connection conn) {
		connList.add(conn);
	}
	
	
	@Override
	public PrintWriter getLogWriter() throws SQLException {
		// 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 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  T unwrap(Class iface) throws SQLException {
		// TODO Auto-generated method stub
		return null;
	}

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

	

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

}

工具类的抽取:

package com.xk.jdbc.utils;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;

import java.sql.Statement;
import java.util.Properties;



/**
* @author: XuKe
* @time :2018年11月16日 下午3:38:00
* 
*/
public class JDBCUtil {
	
	static String driverClass;
	static String url;
	static String name;
	static String password;
	
	
	static {
		
		try {
			Properties properties = new Properties();
			/*InputStream is = JDBCUtil.class.getClassLoader().getResourceAsStream("jdbc.properties");
			pro.load(is);*/
			properties.load(new FileInputStream("src/jdbc.properties"));
			
			driverClass = properties.getProperty("driverClass");
			url = properties.getProperty("url");
			name = properties.getProperty("name");
			password = properties .getProperty("password");
		} catch (IOException e) {
			System.out.println("读取配置文件失败");
		}
		
	}
	
	/**
	* @Title: getConn
	* @Description: TODO(创建一个连接对象)
	* @return
	* @return Connection    
	*/
	public static Connection getConn() {
		Connection conn = null;
		try {
			Class.forName(driverClass);
			 conn = DriverManager.getConnection(url, name, password);
		} catch (SQLException e) {
			System.out.println("创建连接对象失败");
		} catch (ClassNotFoundException e) {
			System.out.println("注册失败");
		}
		
		return conn;
	}
	
	/**
	* @Title: release
	* @Description: TODO(关闭增删改的对象)
	* @param stmt
	* @param conn
	* @return void    
	*/
	
	public static void release(Statement stmt,Connection conn) {
		
		closeStmt(stmt);
		closeConn(conn);
		
	}
	
	/**
	* @Title: release
	* @Description: TODO(关闭查找的对象)
	* @param rs
	* @param stmt
	* @param conn
	* @return void    
	*/
	
	public static void release(ResultSet rs,Statement stmt,Connection conn) {
		closeRs(rs);
		closeStmt(stmt);
		closeConn(conn);
	}
	
	
	/**
	* @Title: release
	* @Description: TODO(释放并归还连接对象)
	* @param stmt
	* @return void    
	*/
	
	public static void release(Statement stmt) {
		
		closeStmt(stmt);
	}
	/**
	* @Title: release
	* @Description: TODO(释放并归还连接对象)
	* @param rs
	* @param stmt
	* @return void    
	*/
	
	public static void release(ResultSet rs,Statement stmt) {
		closeRs(rs);
		closeStmt(stmt);
	}
	
	/**
	* @Title: closeRs
	* @Description: TODO(关闭结果集)
	* @param rs
	* @return void    
	*/
	private static void closeRs(ResultSet rs) {
		try {
			if(rs!=null) {
				rs.close();	
			}
			
		} catch (SQLException e) {
			e.printStackTrace();
		}finally {
			rs = null;
		}	
	}
	
	/**
	* @Title: closeStmt
	* @Description: TODO(关闭stmt)
	* @param stmt
	* @return void    
	*/
	private static void closeStmt(Statement stmt) {
		try {
			if(stmt != null) {
				stmt.close();
			}
			
		} catch (SQLException e) {
			
			e.printStackTrace();
		}finally {
			stmt = null;
		}
	}
	/**
	* @Title: closeConn
	* @Description: TODO(关闭连接对象)
	* @param conn
	* @return void    
	*/
	private static void closeConn(Connection conn) {

		try {
			if(conn != null) {
				conn.close();
			}
			
		} catch (SQLException e) {
		    e.printStackTrace();
		}finally {
			conn = null;
		}
	}

}

测试:

package com.xk.jdbc.datasource;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import com.xk.jdbc.utils.JDBCUtil;

/**
* @author: XuKe
* @time :2018年11月18日 下午4:40:36
* 
*/
public class MyDataSourceTest {
	public static void main(String[] args) {
		Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		MyDataSource myDataSource = null;
		try {
			//1获得连接对象
			//conn= JDBCUtil.getConn();
			
			myDataSource = new MyDataSource();
			conn = myDataSource .getConnection();
			
			String sql = "select * from account";
			pstmt = conn.prepareStatement(sql);
			rs = pstmt.executeQuery();
			while(rs.next()) {
				System.out.println(rs.getInt("id") + " " + rs.getString("name") + " "+ rs.getDouble("money") );
			}
		} catch (SQLException e) {
			System.out.println("预处理错误");
		}finally {
			//释放
			//JDBCUtil.release(rs, pstmt, conn);
			myDataSource.addBack(conn);
			JDBCUtil.closeRs(rs);
			JDBCUtil.closeStmt(pstmt);
		}
	}

}

1.1.5 自定义连接池的问题

1.1.5.1 使用接口的实现类完成的构造

MyDataSource dataSource = new MyDataSource();

1.1.5.2 额外提供了方法归还连接(这种方式增加使用连接池的用户的难度)

// 归还连接:
dataSource.addBack(conn);

1.1.6 自定义连接池的问题解决

如果不提供自定义的方法就可以解决这个问题,但是连接要如何归还到连接池呢?
原来在Connection中是有一个close方法的,colse方法完成了连接的销毁。能不能做一个事情,将原有的连接的close方法改为归还。

  • 现在要做的事情就是将原有的close方法的逻辑改为归还。(增强一个类中的方法)。
  • 如何增强一个类中的方法
    • 一种:采用继承的方式:重写方法加功能(继承这种增强是最简单,但是是有使用条件的:必须能够控制这个类的构造!!!也就是说我们要想增强一个类的方法,我们必须能new出这个类,然后写一个类继承他然后重写要增强的方法,connecction是接口没法创建对象,所以不能用继承来增强的方法)
    class Man{
        public void run(){
    	    System.out.println(“跑…”);
        }
    }
    class SuperMan extends Man{
         public void run(){
    	   System.out.println(“飞…”);
         
         }
    }
    
    
    • 二种:采用装饰者模式:( 装饰者模式使用条件)
      • 1、增强的类和被增强的类实现相同的接口
      • 2、在增强的类中获得被增强的类的引用
        jdbc连接池_第4张图片 代码:
interface Waiter{
	public void server();
}

public class Waitress implements Waiter{
	public void server(){
		System.out.println(“服务中…”);
    }
}

public class WaitressWrapper implements Waiter{
	private Waiter waiter;
	public WaitressWrapper(Waiter waiter){//用于接收 Waitress的对象
		this.waiter = waiter;
}

	public void server(){
		System.out.println(“微笑…”)
		waiter.server();
   }
}

1.2.1 使用装饰者模式增强Connection中的close方法

为了简化编程,提供一个模板类(模板类原封不动的将接口中的所有方法都实现,但是都没有增强)。编写一个装饰类继承模板类。在装饰类中只需要增强某一个方法即可。

模板类:
jdbc连接池_第5张图片

增强类 的实现代码实现

jdbc连接池_第6张图片
连接池代码:
jdbc连接池_第7张图片

测试;
jdbc连接池_第8张图片

你可能感兴趣的:(JDBC)