开源数据库连接池的使用

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 开源数据库连接池的使用

上篇博客刚刚说完如何去自定义一个数据库连接池,当然,这个自定义的数据库连接池是十分简易的,凭借自己的能力也无法写出优秀的连接池。但是,不用担心,我们可以使用开源的数据库连接池,开源的优势体现于此。

在Java中有三种开源数据库连接池提供了数据源的独立实现:

  • DBCP 数据库连接池
  • C3P0 数据库连接池
  • Apache Tomcat内置的连接池(apache dbcp)
1、DBCP数据库连接池

DBCP是Apache软件基金组织下的开源连接池实现,使用DBCP数据源,应用程序应在系统中增加如下两个jar文件:

  • commons-dbcp.jar
  • commons-pool.jar

很多小伙伴因为没有积分,导致很多在CSDN上的资源都无法下载,以后,我都会把资源通过百度网盘分享给大家,大家有需要都可以免费下载。今天的jar包资源我也放在了网盘上。链接:https://pan.baidu.com/s/1-Rj4TQLI_5DGLdfb45N62g
提取码:ba3a
复制这段内容后打开百度网盘手机App,操作更方便哦
jar包准备好了,那么我们来使用一下。
新建一个Java项目。
然后新建测试类DBCPTest,编写测试代码

@Test
public void demo1(){
    //首先使用BasicDataSource创建连接池
    BasicDataSource basicDataSource = new BasicDataSource();
    try {
        //从连接池中获取连接
        Connection connection = basicDataSource.getConnection();
        String sql = "select * from account";
        PreparedStatement stmt = connection.prepareStatement(sql);
        ResultSet set = stmt.executeQuery();
        while(set.next()){
            System.out.println(set.getString("name"));
        }
        //释放资源
        JDBCUtils.release(stmt, connection);
    } catch (SQLException e) {
        e.printStackTrace();
    }
}

现在运行测试代码,能查询出表数据吗?
很显然,连数据库参数都没给,这段测试代码肯定会报错。
那现在就来设置一下参数,修改测试代码

@Test
public void demo1(){
    //首先使用BasicDataSource创建连接池
    BasicDataSource basicDataSource = new BasicDataSource();
    //创建连接需要四个参数
    basicDataSource.setDriverClassName("com.mysql.jdbc.Driver");
    basicDataSource.setUrl("jdbc:mysql:///test");
    basicDataSource.setUsername("root");
    basicDataSource.setPassword("123456");
    try {
        //从连接池中获取连接
        Connection connection = basicDataSource.getConnection();
        String sql = "select * from account";
        PreparedStatement stmt = connection.prepareStatement(sql);
        ResultSet set = stmt.executeQuery();
        while(set.next()){
            System.out.println(set.getString("name"));
        }
        //释放资源
        JDBCUtils.release(stmt, connection);
    } catch (SQLException e) {
        e.printStackTrace();
    }
}

现在运行测试代码
在这里插入图片描述
成功查询到表数据。但是这样写具有局限性,应该把数据库参数写成配置文件,以适应灵活多变的用户需求。
在src目录下新建配置文件dbcp.properties

driverClassName = com.mysql.jdbc.Driver
url = jdbc:mysql:///test
username = root
password =123456

编写测试代码

@Test
public void demo2() throws Exception{
    //读取dbcp.properties
    Properties properties = new Properties();
    properties.load(new FileInputStream(this.getClass().getResource("/dbcp.properties").getFile()));
    DataSource dataSource = BasicDataSourceFactory.createDataSource(properties);
    //从连接池中获取连接
    Connection connection = dataSource.getConnection();
    String sql = "select * from account";
    PreparedStatement stmt = connection.prepareStatement(sql);
    ResultSet set = stmt.executeQuery();
    while(set.next()){
        System.out.println(set.getString("name"));
    }
    //释放资源
    JDBCUtils.release(stmt, connection);
}

然后运行
在这里插入图片描述
运行成功。
附上一个比较全面的配置文件。

#连接设置
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/jdbc
username=root
password=

#<!-- 初始化连接 -->
initialSize=10

#最大连接数量
maxActive=50

#<!-- 最大空闲连接 -->
maxIdle=20

#<!-- 最小空闲连接 -->
minIdle=5

#<!-- 超时等待时间以毫秒为单位 6000毫秒/1000等于60秒 -->
maxWait=60000


#JDBC驱动建立连接时附带的连接属性属性的格式必须为这样:[属性名=property;] 
#注意:"user" 与 "password" 两个属性会被明确地传递,因此这里不需要包含他们。
connectionProperties=useUnicode=true;characterEncoding=gbk

#指定由连接池所创建的连接的自动提交(auto-commit)状态。
defaultAutoCommit=true

#driver default 指定由连接池所创建的连接的事务级别(TransactionIsolation)。
#可用值为下列之一:(详情可见javadoc。)NONE,READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE
defaultTransactionIsolation=READ_UNCOMMITTED
2、C3P0数据库连接池

jar包下载地址:https://sourceforge.net/projects/c3p0/
官网地址:https://www.mchange.com/projects/c3p0/
官网里面也有下载入口,和数据库连接池的使用教程。
官网的文档教程十分详细,所以也就不过多赘述了。
直接上案例。
编写测试代码

@Test
public void demo1() throws Exception{
    //创建一个连接池
    ComboPooledDataSource dataSource = new ComboPooledDataSource();
    //设置四个参数
    dataSource.setDriverClass("com.mysql.jdbc.Driver");
    dataSource.setJdbcUrl("jdbc:mysql:///test");
    dataSource.setUser("root");
    dataSource.setPassword("123456");
    
    Connection connection = dataSource.getConnection();
    String sql = "select * from account";
    PreparedStatement stmt = connection.prepareStatement(sql);
    ResultSet set = stmt.executeQuery();
    while(set.next()){
        System.out.println(set.getString("name"));
    }
    JDBCUtils.release(stmt, connection);
}

需要注意的是,如果运行时报ClassNotFoundExecption异常,说明你的jar包版本是c3p0-0.9.2之后的,该版本之后的版本还需要添加一个辅助包,mchange-commons-java-0.2.3.4.jar。
这是jar包的下载地址。链接:https://pan.baidu.com/s/17o0s92Us-UPQPJFeJjpOzQ
提取码:lt2v
复制这段内容后打开百度网盘手机App,操作更方便哦

同样地,用配置文件实现一下。
在src目录新建文件c3p0-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
    <default-config>
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql:///test</property>
        <property name="user">root</property>
        <property name="password">123456</property>
        
        <property name="automaticTestTable">con_test</property>
        <property name="checkoutTimeout">30000</property>
        <property name="idleConnectionTestPeriod">30</property>
        <property name="initialPoolSize">10</property>
        <property name="maxIdleTime">30</property>
        <property name="maxPoolSize">100</property>
        <property name="minPoolSize">10</property>
        <property name="maxStatements">200</property>

        <user-overrides user="test-user">
            <property name="maxPoolSize">10</property>
            <property name="minPoolSize">1</property>
            <property name="maxStatements">0</property>
        </user-overrides>

    </default-config>

    <!-- This app is massive! -->
    <named-config name="intergalactoApp">
        <property name="acquireIncrement">50</property>
        <property name="initialPoolSize">100</property>
        <property name="minPoolSize">50</property>
        <property name="maxPoolSize">1000</property>

        <!-- intergalactoApp adopts a different approach to configuring statement 
            caching -->
        <property name="maxStatements">0</property>
        <property name="maxStatementsPerConnection">5</property>

        <!-- he's important, but there's only one of him -->
        <user-overrides user="master-of-the-universe">
            <property name="acquireIncrement">1</property>
            <property name="initialPoolSize">1</property>
            <property name="minPoolSize">1</property>
            <property name="maxPoolSize">5</property>
            <property name="maxStatementsPerConnection">50</property>
        </user-overrides>
    </named-config>
</c3p0-config>

这是直接从官方文档上复制下来的。然后加上了数据库配置所需要的四个参数。
然后编写测试代码

@Test
public void demo2() throws Exception{
    //使用c3p0配置文件
    ComboPooledDataSource dataSource = new ComboPooledDataSource();
    Connection connection = dataSource.getConnection();
    String sql = "select * from account";
    PreparedStatement stmt = connection.prepareStatement(sql);
    ResultSet set = stmt.executeQuery();
    while(set.next()){
        System.out.println(set.getString("name"));
    }
    JDBCUtils.release(stmt, connection);
}

注意,c3p0数据库连接池是不需要自己手动加载配置文件的,c3p0非常的人性化,这一步已经被封装好了。创建ComboPooledDataSource对象后直接调用getConnection()方法即可获得连接。前提是你的配置文件名字必须为c3p0-config.xml,且该文件必须放在src目录下。至于其它的一些配置信息,在文档都有讲解,大家可以自行阅读学习。

创建ComboPooledDataSource 对象有两种方法,调用无参构造使用的是配置文件中默认的配置,而如果调用有参构造,将配置文件中标签的name属性值传入,将会使用该标签内的配置信息。

3、Tomcat内置的连接池

需要知道的是,Tomcat内容连接池就是DBCP。
我们知道,将web工程部署到Tomcat有三种方式:

  • 配置server.xml,添加标签
  • 配置独立的xml文件,添加标签
  • 直接将网站目录复制到Tomcat的webapps目录下

任何工程要能够在Tomcat运行,都需要一个虚拟目录。虚拟目录指的是什么?指的就是Context元素。当我们需要使用连接池时,就需要对Context作如下配置

<Context path="/DBTest" docBase="DBTest"
        debug="5" reloadable="true" crossContext="true">

    <!-- maxActive: Maximum number of dB connections in pool. Make sure you
         configure your mysqld max_connections large enough to handle
         all of your db connections. Set to -1 for no limit.
         -->

    <!-- maxIdle: Maximum number of idle dB connections to retain in pool.
         Set to -1 for no limit.  See also the DBCP documentation on this
         and the minEvictableIdleTimeMillis configuration parameter.
         -->

    <!-- maxWait: Maximum time to wait for a dB connection to become available
         in ms, in this example 10 seconds. An Exception is thrown if
         this timeout is exceeded.  Set to -1 to wait indefinitely.
         -->

    <!-- username and password: MySQL dB username and password for dB connections  -->

    <!-- driverClassName: Class name for the old mm.mysql JDBC driver is
         org.gjt.mm.mysql.Driver - we recommend using Connector/J though.
         Class name for the official MySQL Connector/J driver is com.mysql.jdbc.Driver.
         -->
    
    <!-- url: The JDBC connection url for connecting to your MySQL dB.
         -->

  <Resource name="jdbc/TestDB" auth="Container" type="javax.sql.DataSource"
               maxActive="100" maxIdle="30" maxWait="10000"
               username="javauser" password="javadude" driverClassName="com.mysql.jdbc.Driver"
               url="jdbc:mysql://localhost:3306/javatest"/>

</Context>

这是从官网上复制下来的。
那么该在哪里配置Context元素呢?
配置Context元素的三个位置:

  • Tomcat安装目录/conf/context.xml(如果将连接池配置到了该文件,就会对当前Tomcat内部所有的虚拟主机中的任何工程都有效)
  • Tomcat安装目录/conf/Catalina/虚拟主机目录/context.xml(如果将连接池配置到了该文件,就会对当前虚拟主机的任何工程都有效)
  • web工程的根目录/META-INF/context.xml(如果将连接池配置到了该文件,将只对当前工程有效)

接下来演示一下第三种配置方式
在WebRoot下的META-INF文件夹中新建一个文件context.xml

<?xml version="1.0" encoding="UTF-8"?>
<Context path="/DBTest" docBase="DBTest" debug="5" reloadable="true"
    crossContext="true">

    <Resource name="jdbc/TestDB" auth="Container" type="javax.sql.DataSource"
        maxActive="100" maxIdle="30" maxWait="10000" username="root"
        password="123456" driverClassName="com.mysql.jdbc.Driver"
        url="jdbc:mysql://localhost:3306/test" />

</Context>

context.xml文件编写完成后,在启动Tomcat服务器的时候,Tomcat会去自动加载该文件,并创建数据库连接池,存放在Tomcat容器中。此时我们将可以使用JNDI技术去访问数据库连接池。
不了解JNDI技术的童鞋,我们可以在这里略微提一下

JNDI(Java Naming and Directory Interface),Java命名和目录接口,它对应于J2SE中的javax.naming包,
这套API的主要作用在于:它可以把Java对象放在一个容器中(支持JNDI容器 Tomcat),并为容器中的java对象取一个名称,以后程序想获得Java对象,只需通过名称检索即可。
其核心API为Context,它代表JNDI容器,其lookup方法为检索容器中对应名称的对象。

注意事项:
Tomcat创建连接池,与数据库连接需要数据库驱动,要将mysql.jar复制到Tomcat目录下的lib文件夹中。
Java程序要想通过JNDI访问对象,就必须运行在同一个JNDI容器中。也就是说,该Java程序必须运行在Tomcat内部,所以使用JNDI的程序一般是Servlet或JSP。

演示一下。
在项目中新建一个Servlet文件为TomcatServlet

/**
 * 在该程序中,通过JNDI访问Tomcat内部的连接池
 * @author Administrator
 *
 */
public class TomcatServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        try {
            //创建一个检索的对象
            Context initCtx = new InitialContext();
            //默认查找顶级的Java名称串    这是固定的:java:comp/env
            Context envCtx = (Context) initCtx.lookup("java:comp/env");
            //根据设置名称查找连接池对象
            DataSource ds = (DataSource) envCtx.lookup("jdbc/TestDB");
            //获得连接池中的一个连接
            Connection conn = ds.getConnection();
            String sql = "select * from account";
            PreparedStatement stmt = conn.prepareStatement(sql);
            ResultSet set = stmt.executeQuery();
            while(set.next()){
                System.out.println(set.getString("name"));
            }
            JDBCUtils.release(stmt, conn);
        } catch (NamingException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

}

千万别忘了数据库驱动,将mysql-connector-java-5.1.47-bin.jar复制到Tomcat安装目录下的lib文件夹中,然后在MyEclipse中部署项目并运行。接着在浏览器中访问Servlet程序
在这里插入图片描述
说明查询成功。

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
3月前
|
NoSQL 关系型数据库 MySQL
开源数据库
【8月更文挑战第26天】开源数据库
66 11
|
17天前
|
存储 SQL Apache
Apache Doris 开源最顶级基于MPP架构的高性能实时分析数据库
Apache Doris 是一个基于 MPP 架构的高性能实时分析数据库,以其极高的速度和易用性著称。它支持高并发点查询和复杂分析场景,适用于报表分析、即席查询、数据仓库和数据湖查询加速等。最新发布的 2.0.2 版本在性能、稳定性和多租户支持方面有显著提升。社区活跃,已广泛应用于电商、广告、用户行为分析等领域。
Apache Doris 开源最顶级基于MPP架构的高性能实时分析数据库
|
4月前
|
SQL Linux 数据库
|
24天前
|
存储 关系型数据库 MySQL
MySQL vs. PostgreSQL:选择适合你的开源数据库
在众多开源数据库中,MySQL和PostgreSQL无疑是最受欢迎的两个。它们都有着强大的功能、广泛的社区支持和丰富的生态系统。然而,它们在设计理念、性能特点、功能特性等方面存在着显著的差异。本文将从这三个方面对MySQL和PostgreSQL进行比较,以帮助您选择更适合您需求的开源数据库。
94 4
|
1月前
|
存储 JSON Ubuntu
时序数据库 TDengine 支持集成开源的物联网平台 ThingsBoard
本文介绍了如何结合 Thingsboard 和 TDengine 实现设备管理和数据存储。Thingsboard 中的“设备配置”与 TDengine 中的超级表相对应,每个设备对应一个子表。通过创建设备配置和设备,实现数据的自动存储和管理。具体操作包括创建设备配置、添加设备、写入数据,并展示了车辆实时定位追踪和车队维护预警两个应用场景。
57 3
|
1月前
|
SQL JSON 关系型数据库
MySQL是一个广泛使用的开源关系型数据库管理系统,它有许多不同的版本
【10月更文挑战第3天】MySQL是一个广泛使用的开源关系型数据库管理系统,它有许多不同的版本
133 5
|
1月前
|
关系型数据库 分布式数据库 数据库
PolarDB 开源:推动数据库技术新变革
在数字化时代,数据成为核心资产,数据库的性能和可靠性至关重要。阿里云的PolarDB作为新一代云原生数据库,凭借卓越性能和创新技术脱颖而出。其开源不仅让开发者深入了解内部架构,还促进了数据库生态共建,提升了稳定性与可靠性。PolarDB采用云原生架构,支持快速弹性扩展和高并发访问,具备强大的事务处理能力及数据一致性保证,并且与多种应用无缝兼容。开源PolarDB为国内数据库产业注入新活力,打破国外垄断,推动国产数据库崛起,降低企业成本与风险。未来,PolarDB将在生态建设中持续壮大,助力企业数字化转型。
85 2
|
2月前
|
关系型数据库 分布式数据库 数据库
开源云原生数据库PolarDB PostgreSQL 15兼容版本正式发布
PolarDB进行了深度的内核优化,从而实现以更低的成本提供商业数据库的性能。
|
3月前
|
SQL Oracle 关系型数据库
DBeaver,一款好用的开源数据库管理软件
DBeaver,一款好用的开源数据库管理软件
|
3月前
|
关系型数据库 Linux Shell
跟我一起来学国内排名NO.1的开源数据库安装
跟我一起来学国内排名NO.1的开源数据库安装
37 0
跟我一起来学国内排名NO.1的开源数据库安装