为什么要用数据库连接池?
mysql连接资源非常宝贵,创建连接和关闭连接花费的时间比较长,使用数据库连接池可以提高我们开发效率,用户从连接池获取连接使用用完了后,需要把连接归还给连接池,所以我们需要用LinkedList链表存储连接
编写数据库连接池
public class MyDataSource implements DataSource {
//准备连接池集合
private LinkedList<Connection> conns=new LinkedList<>();
public MyDataSource(){
//初始化连接池 提前创建好连接,放入集合中
try {
//1.读取properties配置文件
//1.1创建properties集合
Properties properties=new Properties();
//1.2创建字节输入流,读取properties文件的内容
FileInputStream in = new FileInputStream("E:\\code\\code\\src\\datasource.properties");
//1.3把InputStream中的内容保存到Properties集合中
properties.load(in);
//2.注册驱动
Class.forName(properties.getProperty("jdbc.driverClassName"));
//3.获取连接
for(int i=0;i<Integer.valueOf(properties.getProperty("jdbc.init"));i++){
//获取连接
Connection conn = DriverManager.getConnection(properties.getProperty("jdbc.url"),
properties.getProperty("jdbc.username"), properties.getProperty("jdbc.password"));
//把连接放入集合
conns.add(conn);
}
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("创建数据库连接池失败!");
}
}
/**
* 获取链接
* @return
* @throws SQLException
*/
@Override
public Connection getConnection() throws SQLException {
//移除并且返回一个连接
Connection connection = conns.removeFirst();
return connection;
}
@Override
public Connection getConnection(String username, String password) throws SQLException {
return null;
}
@Override
public <T> T unwrap(Class<T> iface) throws SQLException {
return null;
}
@Override
public boolean isWrapperFor(Class<?> iface) throws SQLException {
return false;
}
@Override
public PrintWriter getLogWriter() throws SQLException {
return null;
}
@Override
public void setLogWriter(PrintWriter out) throws SQLException {
}
@Override
public void setLoginTimeout(int seconds) throws SQLException {
}
@Override
public int getLoginTimeout() throws SQLException {
return 0;
}
@Override
public Logger getParentLogger() throws SQLFeatureNotSupportedException {
return null;
}
}
因为我们使用完连接后,不是关闭连接而是把链接还给linklist集合,所以我们需要重写close方法,这里用到了包装设计模式,也可以用代理设计模式
包装设计模式:
//1.编写一个类,实现Connection接口 考虑的数据库太多了
//2.继承ConnectionImpl,重写close方法
//3.装饰设计模式(包装设计模式)
// 3.1 编写一个类,实现与被增强对象相同的接口
// 3.2 定义一个变量,记住被增强对象
// 3.3 定义一个构造方法接收被增强对象
// 3.4 覆盖想覆盖的方法
// 3.5 对于不想覆盖的方法直接调用被增强对象的方法来实现
public class MyDataSource implements DataSource {
//准备连接池集合
private LinkedList<Connection> conns=new LinkedList<>();
public MyDataSource(){
//初始化连接池 提前创建好连接,放入集合中
try {
//1.读取properties配置文件
//1.1创建properties集合
Properties properties=new Properties();
//1.2创建字节输入流,读取properties文件的内容
FileInputStream in = new FileInputStream("E:\\code\\code\\src\\datasource.properties");
//1.3把InputStream中的内容保存到Properties集合中
properties.load(in);
//2.注册驱动
Class.forName(properties.getProperty("jdbc.driverClassName"));
//3.获取连接
for(int i=0;i<Integer.valueOf(properties.getProperty("jdbc.init"));i++){
//获取连接
Connection conn = DriverManager.getConnection(properties.getProperty("jdbc.url"),
properties.getProperty("jdbc.username"), properties.getProperty("jdbc.password"));
//把连接放入集合
conns.add(conn);
}
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("创建数据库连接池失败!");
}
}
/**
* 获取链接
* @return
* @throws SQLException
*/
@Override
public Connection getConnection() throws SQLException {
//1.获取被增强对象 真正的连接
Connection connection = conns.removeFirst();
//2.包装设计模式(装饰)
return new MyConnection(connection);
}
//1.编写一个类,实现Connection接口 考虑的数据库太多了
//2.继承ConnectionImpl,重写close方法
//3.装饰设计模式(包装设计模式)
// 3.1 编写一个类,实现与被增强对象相同的接口
// 3.2 定义一个变量,记住被增强对象
// 3.3 定义一个构造方法接收被增强对象
// 3.4 覆盖想覆盖的方法
// 3.5 对于不想覆盖的方法直接调用被增强对象的方法来实现
// 动态代理
//1.编写一个类,实现与被增强对象相同的接口
class MyConnection implements Connection{
//2.定义一个变量,记住被增强对象
private Connection conn;
//3.定义一个构造方法接收被增强对象
public MyConnection(Connection conn){
this.conn=conn;
}
//4.覆盖想覆盖的方法
@Override
public void close() throws SQLException {
//还连接
conns.add(conn);
}
//5.对于不想覆盖的方法直接调用被增强对象的方法来实现
//不想覆盖的方法此次省略。。。
使用第三方数据库连接池
public class TestDataSource {
public static void main(String[] args) throws Exception {
//1.创建连接池
ComboPooledDataSource dataSource=new ComboPooledDataSource();
//2.通过set方法设置相关连接信息
dataSource.setDriverClass("com.mysql.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/jdbc");
dataSource.setUser("root");
dataSource.setPassword("root");
dataSource.setMinPoolSize(5);
dataSource.setMaxPoolSize(9);;
//3.获取连接
Connection connection = dataSource.getConnection();
System.out.println(connection);
}
}
druid
public class TestDataSource {
public static void main(String[] args) throws Exception {
//1.创建连接池
DruidDataSource dataSource=new DruidDataSource();
//2.通过set方法设置相关连接信息
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://127.0.0.1:3306/jdbc");
dataSource.setUsername("root");
dataSource.setPassword("root");
dataSource.setMinIdle(5);
dataSource.setMaxActive(9);
//3.获取连接
Connection connection = dataSource.getConnection();
System.out.println(connection);
}
}