前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >delphi 数据库连接池-c3p0,DBCP,Druid(德鲁伊)数据库连接池

delphi 数据库连接池-c3p0,DBCP,Druid(德鲁伊)数据库连接池

作者头像
囍楽云
发布2022-12-29 11:32:38
7920
发布2022-12-29 11:32:38
举报
文章被收录于专栏:囍楽云博客

  c3p0,DBCP,Druid(德鲁伊)数据库连接池

  文章目录

  1. JDBC数据库连接池的必要性

  传统方式的连接数据库,存在的问题:

  普通的 JDBC 数据库连接使用 来获取到连接的,每次向数据库请求建立连接的时候,都要将 加载到内存中,再验证用户名和密码(需要花费0.05s ~ 1s的时间 ) 。需要数据库连接的时候,就向数据库要求一个,执行完成后再断开连接,这样的方式,将会消耗大量的资源和时间。数据库的连接资源并没有得到一个很好的重复利用 ,如果同时有 几百人甚至 几千人 在线,频繁的进行数据库连接操作将占用很多的系统资源,严重的甚至会造成服务器的崩溃。本博客后面会作相应的演示,请大家继续往后看下去。对于每一次数据库连接,使用完后都得断开。否则,如果程序出现异常而未能关闭,将会导致数据库系统中的内存泄漏,最终将导致重启数据库。 何为Java的内存泄漏这种开发不能控制被创建的连接对象数,不能很好的管理连接的资源信息,系统资源会被毫无顾忌的分配出去,如连接过多,也可能导致内存泄漏,服务器崩溃。 1.2 JDBC 连接数据库

  这里我们演示使用传统的数据库连接池,将向 Mysql数据库请求 5000 次的连接,看看会发生什么事情 ???

  包如下错误: java.sql.: Data source of , from server: "Too many "

   package Blogs.blogs04;

代码语言:javascript
复制
    import java.io.IOException;
    import java.io.InputStream;
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.SQLException;
    import java.util.Properties;
    public class JDBCTest {
        public static void main(String[] args) {
            // 读取配置文件信息
            InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("jdbc.properties");  // 默认读取的是src目录下的文件
            try {
                Properties properties = new Properties();   // 创建读取.properties后缀的配置文件的对象
                properties.load(is);  // 以简单的线性格式输入字符读取属性列表(关键字/元素对)
                // 通过对象传入关键字获取到其中的信息
                String driverClass = properties.getProperty("driverClass");
                String url = properties.getProperty("url");
                String user = properties.getProperty("user");
                String password = properties.getProperty("password");
                // 3. 加载/注册驱动
                Class.forName(driverClass);
                // 测试连接 5000 次
                for(int i = 0; i  北京的天安门:

    
      2.1 数据库连接池技术的优点 资源重用

      由于数据库连接得以重用 ,避免了频繁创建,释放连接引起的大量性能开销。在减少系统消耗的基础上,另一方面也增加了系统运行环境的 平稳性 .

      更快的系统反应速度

      数据库连接池在初始化过程中,往往已经创建了若干个数据库连接存放于连接池 中备用。此时连接的初始化工作均已完成。对于业务请求处理而言,直接利用现有可用的连接,避免了数据库连接初始化和释放过程的时间开销,从而减少了系统的响应时间。

      新的资源分配手段

      对于多应用共享同一数据库的系统而言,可在应用层通过数据库连接池的配置,实现某一应用最大可用数据库连接数的限制,避免某一应用独占所有的数据库资源。

      统一的连接管理,避免数据库连接泄漏

      在较为完善的数据库连接池实现中,可根据预先的占用超时设定,强制回收被占用的连接,从而避免了常规数据库连接操作中可能出现的资源的泄漏问题。

      3. 多种开源的数据库连接池

      JDBC 的数据库连接池使用 javax.sql. 来表示, 只是一个接口,该接口通常由服务器(,,Tomcat) 提供实现,也有一些开源组织提供实现了:如下

       通常被称为数据源,是在javax.sql.包下的一个接口。它包含连接池和管理连接池两部分,习惯上也经常把  称为连接池

       用来取代  来获取  连接,获取速度快,同时可以大幅度提高数据库访问速度。

      特别注意:

      数据源(数据库连接池)和数据库连接不同,数据库连接池不需要创建多个,我们可以把它比作是生产数据库连接 的工厂,当我们的连接数量不够时,可以通过配置增加数据库连接池中的存储的连接,因此整个应用只需要一个数据库连接池(数据源)即可 。创建过多的数据库连接池,反而会适得其反。当访问数据库,操作数据库结束后,程序还是像以前一样关闭数据连接:.close(),不过使用数据库连接池不同的是,这里仅仅是把数据库连接 归还 数据库连接池,并不是真正关闭对数据库的连接。这个连接还在。

      虽然它们使用都是 .close() 方法,但是所在的包路径是不同的,因为实现方式是不同的。在’com.mysql.cj.jdbc.’包中的是真正的关闭与数据库的连接,而在``包下是 归还 连接给数据库连接池。

      javax.sql. 包下的  接口的文档:

    
    
      4. C3P0数据库连接池

      C3P0 是第三方的封装的数据库连接池,所以我们需要导入相关的 c3p0-0.9.1.2-jdk1.3.jar 包才可以使用:如下

    
      相关的jar 文件,我已经提交到 Github ,Gitee 当中的了,如有需要的可以自行获取。

      这里我使用的是 IDEA 编辑器,下面为我们的项目中导入 c3p0-0.9.1.2-jdk1.3.jar 包,操作如下:

    
    
    
    
    
    
      这里就导入jar包成功了,后面的 DBCP,Druid 同样也是需要这样导入相关的 jar 包也是这样操作。

      至于如何创建 c3p0 数据库连接池以及 获取其中的连接,我们可以打开我们下载到的 c3p0 文档中路径为 c3p0\c3p0-0.9.1.2 下找了一个名为 index.html 的帮助文档,打开它,里面有相关的 c3p0 的使用

    
      打开显示如下效果:

    
    
    
      import com.mchange.v2.c3p0.*;
        
    ...
        
    ComboPooledDataSource cpds = new ComboPooledDataSource();
    cpds.setDriverClass( "org.postgresql.Driver" ); //loads the jdbc driver            
    cpds.setJdbcUrl( "jdbc:postgresql://localhost/testdb" );
    cpds.setUser("dbuser");                                  
    cpds.setPassword("dbpassword");  

  我们按照上面的创建 c3p0 的案例演示,创建 c3p0 数据库连接池并获取其中连接池中的连接          package Blogs.blogs04;    import com.mchange.v2.c3p0.ComboPooledDataSource;
    import java.beans.PropertyVetoException;
    import java.sql.Connection;
    import java.sql.SQLException;
    public class C3P0Test {
        public static void main(String[] args) {
            try {
                // 通过传入配置参数,创建 c3p0 数据库连接池
                ComboPooledDataSource cpds = new ComboPooledDataSource();
                cpds.setDriverClass( "com.mysql.cj.jdbc.Driver" );   // 注册数据库驱动信息
                cpds.setJdbcUrl( "jdbc:mysql://localhost:3306/test");  // 实际连接的数据库的url在网络中所在的位置
                cpds.setUser("root");  // 用户名
                cpds.setPassword("MySQL123");  // 密码
                // 从c3p0 数据库连接池中获取连接数据库的对象
                Connection connection = cpds.getConnection();
                System.out.println(connection); // 打印连接的地址
                System.out.println(connection.getClass()); // 打印显示实现该类的所在包路径
            } catch (PropertyVetoException e) {
                throw new RuntimeException(e);   // 将编译异常转换为运行异常抛出
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
    }


  关于如何编写 c3p0 的配置文件,同样查看其 index.html 的文档,如下:      
      
        con_test
        30000
        30
        10
        30
        100
        10
        200
        
          10
          1
          0
        
      
      
       
        50
        100
        50
        1000
        
        0 
        5
        
         
          1
          1
          1
          5
          50
        
      
    

  需要注意的是:c3p0 的配置文件名是:c3p0-config.xml 是不可以修改的,默认使用的就是这个文件名.  我们使用的是 IDEA 编译器,下面是如果在 IDEA 中创建 xml 文件,有的 IDEA 中 new 没有 xml,这时候就需要我们自己手动配置了。具体操作如下:  接下来就是仿照上面 index.html 中 c3p0-config.xml 配置文件案例编写配置文件信息了。具体的编写的配置信息如下,大家可以直接复制粘贴上去,就可以直接使用了。不对,大家还要手动修改一下你所对应的 user用户名和  密码,以及 url 实际数据库的网络位置。其他的到没有什么问题了。      
           
            
            root
            MySQL123
            jdbc:mysql://localhost:3306/test?rewriteBatchedStatements=true
            com.mysql.cj.jdbc.Driver
            
            
            5
            
            5
            
            5
            
            10
            
            20
            
            5
        
    

  我们编写好相关的 c3p0-config.xml 配置文件以后,就可以通过访问配置文件中的信息,创建c3p0数据库连接池,以及获取其中的连接了。  具体代码实现如下:          import com.mchange.v2.c3p0.ComboPooledDataSource;    import javax.sql.DataSource;
    import java.beans.PropertyVetoException;
    import java.sql.Connection;
    import java.sql.SQLException;
    public class C3P0Test {
        // 方式二: 通过读取配置文件中的信息,创建c3p0数据库连接池
        public static void main(String[] args) {
            // 创建c3p0数据库连接池
            DataSource dataSource = new ComboPooledDataSource("helloc3p0");
            try {
                // 获取到数据库连接池中的连接
                Connection connection = dataSource.getConnection();
                System.out.println(connection);  // 打印连接地址
                System.out.println(connection.getClass()); // 打印类所在包下的路径
            } catch (SQLException e) {
                throw new RuntimeException(e);  // 将编译异常转换为运行异常抛出
            }
        }
    }


  对 c3p0 数据库连接池进行一个封装,封装到  类当中。  错误演示:          package Blogs.blogs04;    import com.mchange.v2.c3p0.ComboPooledDataSource;
    import java.sql.Connection;
    import java.sql.SQLException;
    public class JDBCUtils {
        public static Connection getConnection() {
            // 通过 c3p0-config.xml 配置文件,创建c3p0数据库连接池
            ComboPooledDataSource cpds = new ComboPooledDataSource("helloc3p0");
            
            Connection connection = null;
            try {
                connection = cpds.getConnection();
            } catch (SQLException e) {
                throw new RuntimeException(e);  // 将编译异常转换为运行异常抛出
            }
            
            return connection;
        }
    }

  错误原因:  我们把创建 c3p0数据库连接池 放到了,调用返回连接中了。  把创建c3p0数据库连接池定义在方法中的后果是:我们每次调用该方法获取连接池,都会创建一个新的 c3p0 数据库连接池,一个连接池的创建的消耗远远比创建一个连接消耗来的大,而我们这么做就是:每创建一个连接就需要创建一个数据库连接池,还不如不用数据库连接池呢。  所以注意:一个应用使用一个数据库连接池就足够了,需要连接时,从数据库连接池中获取,如果数据库连接池中的连接不够了,可以通过配置增加数据库连接池中存有的连接,就把数据库连接池比作是一个生产连接的工厂。  综上所述:我们只要一个数据库连接池,所以我们可以将创建 c3p0 数据库连接池定义成静态 static 的类属性,和类一起加载到内存当中,只定义一次,所有对象共用这个数据库连接池  修改代码如下:          package Blogs.blogs04;    import com.mchange.v2.c3p0.ComboPooledDataSource;
    import java.sql.Connection;
    import java.sql.SQLException;
    public class JDBCUtils {
        // 通过 c3p0-config.xml 配置文件,创建c3p0数据库连接池
        private static ComboPooledDataSource cpds = new ComboPooledDataSource("helloc3p0"); // 作为类属性存在
        public static Connection getC3p0Connection() {
            Connection connection = null;
            try {
                connection = cpds.getConnection();  // static 静态不要使用 this的引用
            } catch (SQLException e) {
                throw new RuntimeException(e);  // 将编译异常转换为运行异常抛出
            }
            return connection;
        }
    }

  比较传统的 JDBC 连接数据库,和 C3P0 使用数据连接池的性能  jdbc 与 c3p0 都与数据库连接 5000 次,比较连接完后所消耗的时间:  传统的 JDBC 连接数据库 5000 次package Blogs.blogs04;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;
public class JDBCTest {
    public static void main(String[] args) {
        // 读取配置文件信息
        InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("jdbc.properties");  // 默认读取的是src目录下的文件
        try {
            Properties properties = new Properties();   // 创建读取.properties后缀的配置文件的对象
            properties.load(is);  // 以简单的线性格式输入字符读取属性列表(关键字/元素对)
            // 通过对象传入关键字获取到其中的信息
            String driverClass = properties.getProperty("driverClass");
            String url = properties.getProperty("url");
            String user = properties.getProperty("user");
            String password = properties.getProperty("password");
            // 3. 加载/注册驱动
            Class.forName(driverClass);
            long start = System.currentTimeMillis();  // 获取到 5000 次连接数据库的前的时间点:单位:毫秒
            // 测试连接 5000 次
            for(int i = 0; i 
[1]: https://xuan.ddwoo.top/index.php/archives/400/
[2]: https://xuan.ddwoo.top/index.php/archives/404/                
        本文共 2860 个字数,平均阅读时长 ≈ 8分钟
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档