在这之前,我们使用的都是JDBCUtil工具类来获取数据库的连接,但是实际上是每次执行方法都新建一条连接(一般的方法流程是建立连接,执行sql,释放连接)。频繁的创建连接,和断开连接不仅麻烦,而且需要消耗的资源也很大。

我们可以使用连接池,来避免每个方法执行时都新建一条连接。连接池中有着多条已经建立好并且不会断开的连接,当方法或者说客户需要数据库连接时,就从连接池中获取一条连接,然后使用,使用完成后调用close方法。这里的close方法的作用不是关闭连接,而是将连接放回连接池,让其他客户使用。

连接池的原理是:

  1. 事先创建一个类似于JDBCUtil一样的工具类,这个工具类里面存放着连接池的信息。这些信息包括一个连接池的实例DataSource,连接池的大小,也就是最多可以存放多少条连接,以及连接数据库的各项信息。最后有一个方法,让外界可以调用这个方法从而获取连接池里面的连接。
  2. 当客户需要数据库连接时,先向连接池进行请求
    (1)连接池中有空闲连接,则分配给客户使用,并将该连接置为“正在使用”状态
    (2)连接池中没有空闲连接,则查看连接池的连接数是否超过最大值
    ————(a)如果没超过,则创建一条新的连接,并返回给客户使用,并将该连接置为“正在使用”状态
    ————(b)如果已经超过,则客户进入等待状态,超出等待时间则返回异常信息
    (3)客户使用连接完毕后,调用close方法,将连接从“正在使用状态”置为“空闲状态”,从而让其他客户使用

使用连接池还有一个好处,如果在使用过程中,mysql数据库突然离线,那么以前的JDBCUtil数据库只会进行一次连接,连接断开也不会重新连接。而客户获取连接池中的连接时,如果连接断开,就会选择另外一条连接,并且尝试重新建立数据库的连接。

首先写一个测试类,来看一下连接池的运行过程

package com.demo.spring.test;
import org.apache.commons.dbcp2.BasicDataSource;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class DBCPTest {
    public static void main(String[] args) throws SQLException {
        // 创建连接池
        BasicDataSource bds = new BasicDataSource();
        // 配置连接池大小,这里数字为5说明连接池中最多有5条连接
        bds.setInitialSize(5);
        //配置连接信息
        bds.setUrl("jdbc:mysql://master:3306/show1");
        bds.setDriverClassName("com.mysql.jdbc.Driver");
        bds.setUsername("root");
        bds.setPassword("123456");

        //获取连接
        Connection connection = bds.getConnection();
        PreparedStatement statement = connection.prepareStatement("select * from userInfo");
        ResultSet resultSet = statement.executeQuery();
        while (resultSet.next()){
            System.out.println(resultSet.getString("username"));
        }
        // 关闭连接 等于重新放回连接池
        connection.close();
    }

}

springboot的mysql最大连接 springboot 数据库连接数_spring boot


结果是正确的,成功获取了userInfo表里面的数据

写一个连接池的工具类,并且用这个工具类来修改Dao层的代码

package com.demo.spring.util;
import org.apache.commons.dbcp2.BasicDataSource;

import java.sql.Connection;
import java.sql.SQLException;
public class DBCPUtil {
    private static BasicDataSource bds;
    static {
        System.out.println("创建连接池");
        bds = new BasicDataSource();
        // 配置连接池大小
        bds.setInitialSize(5);
        //配置连接信息
        bds.setUrl("jdbc:mysql://master:3306/show1");
        bds.setDriverClassName("com.mysql.jdbc.Driver");
        bds.setUsername("root");
        bds.setPassword("123456");
    }

    public static Connection getConn(){
        System.out.println("获取连接");
        try {
            return bds.getConnection();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }
}
package com.demo.spring.mvc.dao;

import com.demo.spring.mvc.bean.User;
import com.demo.spring.util.DBCPUtil;
import com.demo.spring.util.JDBCUtil;

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

public class UserDao {
    public User loginDao(String username){
        User user = null;
        try{
            Connection conn = DBCPUtil.getConn();
            String sql = "select * from userInfo where username=?";
            PreparedStatement ps = conn.prepareStatement(sql);
            ps.setString(1,username);
            ResultSet rs = ps.executeQuery();
            if(rs.next()){
                user=new User();
                user.setId("id");
                user.setUsername(rs.getString("username"));
                user.setPassword(rs.getString("password"));
            }
            rs.close();
            ps.close();
            conn.close();

        }catch (Exception e){
            e.printStackTrace();
        }
        return user;
    }
}

其余部分的代码与之前的博客里面写的一样,这里只需要用连接池改造Dao层的代码即可,

springboot的mysql最大连接 springboot 数据库连接数_数据库_02


可以成功进行登录信息检查之后每一次在浏览器的地址栏修改username和password,都会导致重新获取一次连接池中的连接

springboot的mysql最大连接 springboot 数据库连接数_mysql_03