JDBC数据库连接池

1、 数据库频繁连接的问题

JDBC技术操作数据库,每次和数据库连接成功,执行SQL语句,释放资源。数据库的连接过程比较消耗资源,消耗的是网络资源,和数据库连接都是TCP协议的,Java程序要和数据库进行三次握手才能确定连接成功。

大数据高并发时代,频繁的连接数据库,必然导致我们开发的软件在运行速度上会变慢。用户体验会非常的差。必须解决数据库频繁连接的问题,提供我们软件运行速度。

2 、数据库连接池的原理

数据库连接池:解决频繁连接带来的性能问题和网络资源消耗问题。

数据库连接池,数据库连接对象的缓冲池。实现原理就是将数据库的连接对象存储在一个容器中(池pool),需要操作数据库,就从池中取出连接对象来使用,数据库操作完成,要将连接对象放回到连接池中。连接对象永远不会被销毁,可以反复的使用,达到提供连接效率的问题。

JDBC数据库连接池_第1张图片

3、Data Source接口

开发中必须要使用连接池,但是我们自己开发连接池很不现实。需要使用第三方的连接池技术。

常见的连接池:德鲁伊连接池,Apache的连接池DBCP,C3P0

连接池产品众多,我们开发人员选择用哪个连接池呢?

如果连接池不统一标准,开发人员将无法切换连接池!!

连接池的技术标准也必须要统一:Sun公司定义了连接池的标准接口:

javax.sql包下的接口
/**
是所有连接池标准
连接池就必须实现此接口
接口的名字是数据源,就是连接池
*/
​
public interface DataSource{
Connection getConnection();// 返回数据库的连接对象
}

任何一个连接池,都必须实现接口:javax.sql.DataSource 重写方法getConnection()

4、德鲁伊连接池的使用

阿里巴巴的德鲁伊连接池:DruidDataSource类实现了Sun公司的接口DataSource

  • 德鲁伊连接池的配置参数

参数配置 参数说明
driverClassName 数据库的驱动类
url 数据库服务器的连接地址
username 连接数据库的用户名
password 连接数据库的密码
initalSize 连接池中初始化的连接个数
maxIdIe 连接池中最大的连接个数

使用德鲁伊连接池,必须要添加jar包!

  • 自定义德鲁伊连接池工具类

/**
创建静态方法,返回数据库的连接对象
数据库的连接对象,交给德鲁伊连接池管理
从池中取出连接来使用
*/
public static Connection getConnection(){
         // 创建连接池接口DataSource的实现类对象
         DruidDataSource dataSource=new DruidDataSource();
         // 配置数据库的驱动类,dataSource对象的set方法设置
         DruidDataSource dataSource=new DruidDataSource();
         dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); //数据库驱动类
         dataSource.setUrl("jdbc:mysql://localhost:3306/school");
         dataSource.setUsername("root");  //连接数据库的用户名
         dataSource.setUsername("renyanlei115");  // 连接数据库的密码
         dataSource.setInitialSize(10);   //  连接池中,初始化的连接个数
         dataSource.setMaxActive(20);   //连接池中,最大的连接个数
         
         // 调用对象的方法 getConnection()获取数据库连接对象
         return dataSource.getConnection();
}
          // 测试代码
          public static void main(){
          Connection con=getConnection();
           System.out.println("con="+con);
           con.close();
}
  • 德鲁伊连接池(properties)

driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/school
username=root
password=renyanlei115
initialSize=10
maxActive=20
  • 配置文件中的键名称不能乱写,因为德鲁伊连接池中的键是固定的。

  • 优化后的德鲁伊连接池工具

package com.rocky.utils;
​
import com.alibaba.druid.pool.DruidDataSourceFactory;
​
import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
​
public class DruidJDBCUtils {
    static DataSource dataSource;
​
    static {
        //1 :加载配置文件
        InputStream resourceAsStream =
                DruidJDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties");
​
        Properties properties = new Properties();
        try {
            properties.load(resourceAsStream);
​
            // druid提供了一个工厂方法来生成dataSource对象
            dataSource = DruidDataSourceFactory.createDataSource(properties);
​
​
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
​
    }
    
      public static DataSource getDataSource(){
        return dataSource;
    }
​
​
    public static Connection getConnection() throws SQLException {
        return dataSource.getConnection();
    }
​
    /**
     * 凡是使用了连接池的JDBC技术,执行Connection对象的close()方法,不是关闭连接,而是回收到连接池中
     *
     */
​
    public static void close(ResultSet resultSet, Statement statement,Connection connection) throws SQLException {
        if(resultSet!=null){
            resultSet.close();
        }
​
        if(statement!=null){
            statement.close();
        }
​
        if(connection!=null){
            connection.close();
        }
​
    }
​
}
  • 数据库连接池中的资源释放问题(连接对象使用完毕要归还连接池)

  • 连接池中使用动态代理技术(改变方法的功能),close()方法的作用就是归还连接池

5、使用连接池使用数据表的查询功能

package com.rocky.view;
​
import com.rocky.utils.DataSourceUtils;
​
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
​
public class DataSourceTest {
​
    public static void main(String[] args) throws SQLException {
        Connection connection=null;
        PreparedStatement preparedStatement=null;
        ResultSet resultSet=null;
        try {
            //德鲁伊连接池工具类,获得数据库的连接对象
            connection= DataSourceUtils.getConnection();
            //拼写SQL语句
            String sql="select * from userinfo";
​
            //sql语句中,没有问号,没有占位符,不需要设置参数
            preparedStatement=connection.prepareStatement(sql);
​
            resultSet=preparedStatement.executeQuery();
            while (resultSet.next()){
                int id=resultSet.getInt("id");
                String name=resultSet.getNString("name");
                String password=resultSet.getString("password");
                System.out.println("id="+id+"name="+name+"password="+password);
            }
​
​
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }finally {
            DataSourceUtils.close(resultSet,preparedStatement,connection);
        }
    }
}

你可能感兴趣的:(JDBC,数据库,oracle)