Proxool 连接池连接 OceanBase 数据库示例程序

本文将介绍如何使用 Proxool 连接池、MySQL Connector/J 和 OceanBase 数据库构建一个应用程序,实现基本的数据库操作,包括创建表、插入、删除、更新和查询数据等。

image.png点击下载 proxool-mysql-client 示例工程

前提条件

  • 您已安装 OceanBase 数据库并且创建了 MySQL 模式租户。

  • 您已安装 JDK 1.8 和 Maven。

  • 您已安装 IntelliJ IDEA。

    说明

    本文档运行代码使用的工具是 IntelliJ IDEA Community Edition 2021.3.2 版本,您也可以根据个人喜好选择适合自己的工具运行的示例代码。

操作步骤

说明

本文中给出的操作步骤是在 Windows 环境下使用 IntelliJ IDEA Community Edition 2021.3.2 编译和运行该项目的步骤。如果您使用的是其他操作系统环境或编译器,那么操作步骤可能会略有不同。

  1. proxool-mysql-client项目导入到 IntelliJ IDEA 中。

  2. 获取 OceanBase 数据库 URL。

  3. 修改proxool-mysql-client项目中的数据库连接信息。

  4. 运行proxool-mysql-client项目。

步骤一:将 proxool-mysql-client 项目导入到 IntelliJ IDEA 中

  1. 打开 IntelliJ IDEA。

  2. 在欢迎界面上,点击 Open 选项,导航到您的项目目录,选择项目的根目录,点击 OK

    image.png

  3. IntelliJ IDEA 会自动检测项目类型并加载项目。

    说明

    当使用 IntelliJ IDEA 导入 Maven 项目时,IntelliJ IDEA 会自动检测项目中的pom.xml文件,并根据文件中描述的依赖关系自动下载所需的依赖库,并将它们添加到项目中。

    image.png

  4. (可选)手动导入未解析的依赖项。

    如果pom.xml文件中对应的依赖项都自动导入到了项目中,请忽略此步骤。

    通过 IntelliJ IDEA 的 Sync 窗口的提示,可以发现proxool-cglibproxool依赖项未解析。proxool-mysql-client项目根目录下的lib的文件夹中有proxool-cglibproxooljar文件,将其添加到项目,步骤如下:

    1. 在 IntelliJ IDEA 中,点击 File->Project Structure 进入项目结构设置。

    2. 在左侧面板中,选择 Modules

    3. 在右侧的模块列表中,选择 Dependencies 选项卡,点击此页面上的+图标,选择 JARs or directories

    4. 在弹出的对话框中,导航到存放jar文件的lib目录,选中jar文件,点击 OK

    5. Dependencies 选项卡下,会看到新加入的jar文件出现在列表中。

    6. 点击 Apply OK 保存更改。

    image.png

步骤二:获取 OceanBase 数据库 URL

  1. 联系 OceanBase 数据库部署人员或者管理员获取相应的数据库连接串。

    示例如下:

    obclient -hxxx.xxx.xxx.xxx -P3306 -utest_user001 -p****** -Dtest -A

    更多连接串的信息,请参见 获取连接参数

  2. 根据 OceanBase 数据库连接串信息填写下面 URL 的对应信息。

    jdbc:mysql://$host:$port/$database_name?user=$user_name&password=$password

    参数说明:

    • $hostOceanBase 数据库连接的域名。

    • $port:OceanBase 数据库连接端口,MySQL 模式租户默认是 3306。

    • $database_name:需要访问的数据库名称。

    • $user_name:租户的连接账号。

    • $password:提供账户密码。

    更多有关 MySQL Connector/J 连接属性信息,请参见 Configuration Properties

    示例如下:

    jdbc:mysql://xxx.xxx.xxx.xxx:3306/test?user=test_user001&password=******

步骤三:修改 proxool-mysql-client 项目中的数据库连接信息

根据 步骤二:获取 OceanBase 数据库 URL 中获取的信息修改文件proxool-mysql-client/src/main/resources/db.properties中的数据库连接信息。

示例如下:

  • OBServer 节点的 IP 地址为xxx.xxx.xxx.xxx

  • 访问端口使用的是 3306。

  • 需要访问的数据库名称为test

  • 租户的连接账户是test_user001

  • 密码是******

代码如下:

...
jdbc-1.proxool.driver-url=jdbc:mysql://xxx.xxx.xxx.xxx:3306/test?useSSL=false
jdbc-1.user=test_user
jdbc-1.password=******
...

步骤四:运行 proxool-mysql-client 项目

  1. 在项目导航栏中,找到并展开 src/main/java/com.example 目录。

  2. 右键点击 Main 文件,选择 Run 'Main.main()'

  3. IntelliJ IDEA 会自动编译和运行该项目,并在运行面板中显示输出结果。

    image.png

  4. 也可以在 OceanBase 客户端(OBClient)中执行以下 SQL 语句查看结果。

    obclient [(none)]> SELECT * FROM test.test_proxool;

    返回结果如下:

    +------+---------------+
    | c1   | c2            |
    +------+---------------+
    |    6 | test_update   |
    |    7 | test_insert7  |
    |    8 | test_insert8  |
    |    9 | test_insert9  |
    |   10 | test_insert10 |
    +------+---------------+
    5 rows in set

项目代码介绍

点击 proxool-mysql-client 下载项目代码,是一个名称为proxool-mysql-client.zip的压缩包。

解压后,得到一个名为proxool-mysql-client的文件夹。目录结构如下所示:

proxool-mysql-client
├── lib
│    ├── proxool-0.9.1.jar
│    └── proxool-cglib.jar
├── src
│   └── main
│       ├── java
│       │   └── com
│       │       └── example
│       │           └── Main.java
│       └── resources
│           └── db.properties
└── pom.xml

文件说明:

  • lib:存放项目所需的依赖库文件。

  • proxool-0.9.1.jar:Proxool 连接池库文件。

  • proxool-cglib.jar:用于支持 Proxool 连接池的 CGLib 库文件。

  • src:源代码根目录。

  • main:主代码目录,包含应用程序的主要逻辑。

  • java:Java 源代码目录。

  • com:Java 包目录。

  • example:示例项目的包目录。

  • Main.java:主类程序示例文件,包含创建表、插入、删除、更新和查询数据等逻辑。

  • resources:资源文件目录,包含配置文件等。

  • db.properties:连接池的配置文件,包含了数据库连接的相关参数。

  • pom.xml:Maven 项目的配置文件,用于管理项目的依赖和构建设置。

pom.xml 代码介绍

pom.xml文件是 Maven 项目的配置文件,定义了项目的依赖项、插件和构建规则等信息。Maven 是一个 Java 项目管理工具,可以自动下载依赖项、编译和打包项目等操作。

本文pom.xml文件的代码主要包括以下几个部分:

  1. 文件声明语句。

    声明本文件是一个 XML 文件,使用的 XML 版本是1.0,字符编码方式是UTF-8

    代码如下:

    <?xml version="1.0" encoding="UTF-8"?>
  2. 配置 POM 的命名空间和 POM 模型版本。

    1. 通过xmlns指定 POM 的命名空间为http://maven.apache.org/POM/4.0.0

    2. 通过xmlns:xsi指定 XML 命名空间http://www.w3.org/2001/XMLSchema-instance

    3. 通过xsi:schemaLocation指定 POM 的命名空间为http://maven.apache.org/POM/4.0.0和 POM 的 XSD 文件的位置为http://maven.apache.org/xsd/maven-4.0.0.xsd

    4. 通过<modelVersion>元素指定了该 POM 文件使用的 POM 模型版本为4.0.0

    代码如下:

    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
    
     <!-- 其他配置 -->
    
    </project>
  3. 配置基本信息。

    1. 通过<groupId>指定项目所属组织为com.example

    2. 通过<artifactId>指定项目的名称为proxool-mysql-client

    3. 通过<version>项目的版本号为1.0-SNAPSHOT

    代码如下:

        <groupId>com.example</groupId>
        <artifactId>proxool-mysql-client</artifactId>
        <version>1.0-SNAPSHOT</version>
  4. 配置项目源文件的属性。

    指定 Maven 的编译器插件为maven-compiler-plugin,并设置了源代码和目标 Java 版本都为 8。这意味着项目的源代码使用 Java 8 特性编写,且编译后的字节码也将兼容 Java 8 运行时环境。这样设置可以确保项目在编译和运行时能够正确地处理 Java 8 的语法和特性。

    说明

    Java 1.8 和 Java 8 是同一个版本的不同命名方式。

    代码如下:

        <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <configuration>
                        <source>8</source>
                        <target>8</target>
                    </configuration>
                </plugin>
            </plugins>
        </build>
  5. 配置项目所依赖组件。

    通过<dependency>定义依赖项:

    1. 添加mysql-connector-java库,用于连接和操作数据库:

      1. 通过<groupId>指定依赖项所属的组织为mysql

      2. 通过<artifactId>指定依赖项的名称为mysql-connector-java

      3. 通过<version>指定依赖项的版本号为5.1.47

      代码如下:

              <dependency>
                  <groupId>mysql</groupId>
                  <artifactId>mysql-connector-java</artifactId>
                  <version>5.1.47</version>
              </dependency>
    2. 添加proxool-cglib依赖库,用于支持 Proxool 连接池的 CGLib 库:

      1. 通过<groupId>指定依赖项所属的组织为proxool

      2. 通过<artifactId>指定依赖项的名称为proxool-cglib

      3. 通过<version>指定依赖项的版本号为0.9.1

      代码如下:

              <dependency>
                  <groupId>proxool</groupId>
                  <artifactId>proxool-cglib</artifactId>
                  <version>0.9.1</version>
              </dependency>
    3. 添加proxool依赖库,Proxool 连接池的核心库:

      1. 通过<groupId>指定依赖项所属的组织为proxool

      2. 通过<artifactId>指定依赖项的名称为proxool

      3. 通过<version>指定依赖项的版本号为0.9.1

      代码如下:

              <dependency>
                  <groupId>proxool</groupId>
                  <artifactId>proxool</artifactId>
                  <version>0.9.1</version>
              </dependency>
    4. 添加commons-logging依赖库,用于在应用程序中进行日志记录的通用日志库:

      1. 通过<groupId>指定依赖项所属的组织为commons-logging

      2. 通过<artifactId>指定依赖项的名称为commons-logging

      3. 通过<version>指定依赖项的版本号为1.2

      代码如下:

              <dependency>
                  <groupId>commons-logging</groupId>
                  <artifactId>commons-logging</artifactId>
                  <version>1.2</version>
              </dependency>

db.properties 代码介绍

db.properties是本文示例的连接池配置文件,其中包含了连接池的配置属性。

说明

使用.properties文件配置 Proxool 连接池时,需要遵循以下规则:

  1. jdbc为前缀的自定义名称来标识每个连接池。可以自定义这个名称,用于唯一标识每个连接池。

  2. Proxool 连接池的相关属性应该以proxool.为前缀,这些属性将被用于配置 Proxool 连接池自身的属性。

  3. 没有以jdbc为前缀的属性将会被忽略,不会被 Proxool 使用。

  4. 没有以proxool.为前缀的属性将被传递给实际的数据库连接,即这些属性将被传递给实际的数据库驱动程序。

更多配置 Proxool 连接池的方法,请参见Configuration

本文db.properties文件是一个属性文件的示例,用于配置一个名为jdbc-1的数据源的连接池属性。主要包括以下几个部分:

  1. 设置数据源的别名为TEST

    代码如下:

    jdbc-1.proxool.alias=TEST
  2. 配置数据库连接参数。

    1. 设置驱动程序的类名,这里是 MySQL JDBC 驱动的类名com.mysql.jdbc.Driver

    2. 设置数据库连接的 URL,包括主机 IP、端口号、需要访问的数据库和额外的连接属性。

    3. 设置数据库用户名。

    4. 设置数据库密码。

    代码如下:

    jdbc-1.proxool.driver-class=com.mysql.jdbc.Driver
    jdbc-1.proxool.driver-url=jdbc:mysql://$host:$port/$database_name?useSSL=false
    jdbc-1.user=$user_name
    jdbc-1.password=$password

    参数解释:

    • $hostOceanBase 数据库连接的域名。

    • $port:OceanBase 数据库连接端口,MySQL 模式租户默认是 3306。

    • $database_name:需要访问的数据库名称。

    • $user_name:租户的连接账号。

    • $password:提供账户密码。

  3. 配置其他 Proxool 连接池的参数。

    1. 设置连接池的最大连接数为 8。

    2. 设置连接池的最小连接数为 5。

    3. 设置连接池中可用的连接数量为 4。

    4. 设置连接池的详细模式为开启,即显示更多的日志信息。

    5. 设置连接池的统计信息记录周期为 10 秒、1 分钟和 1 天。

    6. 设置连接池统计信息记录的日志级别为错误级别。

    代码如下:

    jdbc-1.proxool.maximum-connection-count=8
    jdbc-1.proxool.minimum-connection-count=5
    jdbc-1.proxool.prototype-count=4
    jdbc-1.proxool.verbose=true
    jdbc-1.proxool.statistics=10s,1m,1d
    jdbc-1.proxool.statistics-log-level=error
重要

具体的属性(参数)配置取决于项目需求和数据库的特点,建议您根据实际情况进行调整和配置。更多 Proxool 连接池参数的信息,请参见 Properties

常用配置参数说明:

配置

缺省值

说明

alias

N/A

用于设置连接池别名。可以用于标识一个连接池,在多个连接池的情况下很有用。

driver-class

N/A

用于设置数据库驱动程序类名。

driver-url

N/A

用于设置数据库连接 URL,包括主机 IP、端口号、需要访问的 Schema 和可选的数据库驱动参数。

username

N/A

用于设置数据库用户名。

password

N/A

用于设置数据库密码。

maximum-connection-count

15

用于设置连接池的最大连接数。默认值为 15,表示连接池最多可以创建 15 个连接。

minimum-connection-count

5

用于设置连接池的最小连接数。默认值为 5,表示连接池将始终保持至少 5 个连接。

prototype-count

0

用于设置连接池的原型连接数。默认值为 0,表示连接池不会主动创建额外的连接。

minimum-connection-count不同的是,prototype-count这个属性会考虑当前活动连接的数量。如果可用连接数少于设定的prototype-count,连接池会创建更多的连接(前提是未达到最大连接数)。例如,如果有 3 个活动连接和 2 个可用连接,但prototype-count设定为 4,那么连接池将尝试创建另外 2 个连接。

prototype-count的目的是在当前活动连接的基础上维持一定数量的备用连接。这些备用连接可以避免在高负载期间由于连接池中可用连接不足而导致的连接请求被阻塞。通过创建更多的连接,连接池可以更好地应对并发请求,提高应用程序的性能和响应速度。

在调整这个属性时,需要考虑应用程序的并发需求和数据库的配置。如果应用程序预计会有较高的并发请求,可以适当增加prototype-count;如果应用程序的并发请求较少,可以将该属性设置为 0,以减少资源消耗。

verbose

false

用于设置连接池的详细输出模式。默认值为false,即安静模式。

verbose属性设置为true时,连接池将输出更详细的信息,以便开发人员进行调试和监控。这些信息可能包括连接池的状态、连接的创建和释放、连接的使用情况等。

开启verbose模式可以帮助开发人员更好地了解连接池的运行情况,以及检查连接的分配和回收是否正常。这对于排查连接泄漏、性能问题和调优非常有用。

在生产环境中,通常不建议将verbose设置为true,因为它会产生大量的输出信息,可能影响系统的性能和日志文件的大小。通常情况下,建议将verbose设置为false,只在需要时临时开启以进行调试和监控。

statistics

null

用于配置统计信息的采样长度,即连接池使用状况统计。采样长度可以设置为以逗号分隔的时间单位,例如10s,15m表示每 10 秒和每 15 分钟采样一次。可用的单位有s(秒)、m(分钟)、h(小时)和d(天)。默认值为null,表示不采集统计信息。

当设置statistics属性时,连接池将定期采样连接池的统计信息,如活动连接数、空闲连接数、连接请求数等。采样长度决定了统计信息的粒度和采样频率。

statistics-log-level

null

用于设置统计信息的日志级别,即日志统计跟踪类型。可选的日志级别有DEBUGINFOWARNERRORFATAL。默认值为null,表示不记录统计信息日志。

当设置了statistics-log-level属性后,连接池会将产生的统计信息以指定的日志级别记录下来。这些统计信息可以包括连接池的状态、连接的创建和释放、连接的使用情况等。

test-after-use

N/A

用于设置连接在关闭后是否进行测试。如果将该属性设置为true,并且定义了house-keeping-test-sql属性,那么每个连接在关闭(即返回到连接池)后都会进行测试。如果连接测试失败,则该连接会被丢弃。

连接池中的连接在使用完毕后通常会被放回连接池中以供重复使用。test-after-use属性的作用是在连接放回连接池后,对该连接进行测试,以确保连接的可用性和有效性。连接测试通常使用house-keeping-test-sql属性指定的 SQL 语句。

通过开启test-after-use功能,连接池可以及时检测到不可用的连接,并将其从连接池中移除,以避免应用程序获取到无效的连接。这可以提高应用程序的稳定性和可靠性。

需要注意的是,为了使用test-after-use功能,需要预先设置好house-keeping-test-sql属性,该属性用于定义连接测试所使用的 SQL 语句。这样连接池才能根据house-keeping-test-sql定义的规则来对连接进行测试和判断。

house-keeping-test-sql

N/A

用于设置连接池中空闲连接的测试 SQL 语句。当连接池的管家线程发现有空闲连接时,会使用该 SQL 语句对这些连接进行测试。测试 SQL 语句应该是非常快速执行的,例如检查当前日期等操作。如果没有定义该属性,则不进行连接测试。MySQL 模式可用SELECT CURRENT_DATE或者SELECT 1。Oracle 模式可用SELECT sysdate FROM DUAL或者SELECT 1 FROM DUAL

trace

false

用于设置是否记录每个 SQL 调用的日志信息。当设置为true时,每个 SQL 调用将被记录在日志中(DEBUG级别),并显示执行时间。也可以通过注册ConnectionListener(参见ProxoolFacade)来获取这些信息。默认值为false

开启trace功能可能会产生大量的日志输出,特别是在高并发和频繁 SQL 调用的情况下。在生产环境中,建议谨慎使用,以避免产生过多的日志和对系统性能造成不必要的影响。

maximum-connection-lifetime

4 小时

用于设置连接的最大生命周期。即连接在被销毁之前存在的最长时间(单位为毫秒)。默认值为 4 小时。

连接的生命周期是指连接从创建到销毁的时间段。通过设置maximum-connection-lifetime属性,可以限制连接在连接池中存在的最长时间,以避免连接过久未使用或出现资源泄漏的情况。

maximum-active-time

5 分钟

用于设置线程的最大活动时间。当连接池的管家线程发现某个线程的活动时间超过此设置时,它将终止该线程。因此,请确保将此属性设置为大于预期最慢响应时间的值。默认值为 5 分钟。

守护进程会把连接池中多余的可用线程(未用的、超过这个时间的)终止,最终保留的连接数量就是minimum-connection-count规定的数量。守护进程会根据house-keeping-sleep-time参数设置的时间隔定时检查。

maximum-new-connections

N/A

用于设置连接池每次同时建立的最大新连接数。该属性已被弃用(Deprecated)。建议使用simultaneous-build-throttle属性替代。

simultaneous-build-throttle

10

用于设置在任何时刻连接池可以同时建立的最大连接数。也就是说,即将建立但尚未可用的新连接数的上限。因为连接的建立可能使用多个线程(例如按需建立连接时),并且在决定建立连接和连接可用之间需要一定的时间,所以我们需要一种方式来确保不会同时有大量线程决定建立连接。

simultaneous-build-throttle属性的作用是限制连接池同时建立新连接的数量,以控制连接池的并发性。当达到最大并发连接数时,进一步请求新连接的线程将被阻塞,直到有可用的连接或超过指定的超时时间。

通过设置适当的simultaneous-build-throttle属性,可以平衡连接池的并发性和资源消耗。默认值为 10,意味着连接池可以同时建立的最大连接数为 10。

overload-without-refusal-lifetime

60

用于帮助确定连接池的状态。如果在指定的时间阈值内(单位为毫秒)拒绝了连接请求,则表示连接池处于过载状态。默认值为 60 秒。

test-before-use

N/A

用于设置是否在提供连接之前对每个连接进行测试。如果将该属性设置为true,则在向应用程序提供连接之前,每个连接都会通过执行预定义的测试 SQL(由house-keeping-test-sql属性定义)进行测试。如果连接测试失败,则该连接将被丢弃,连接池将选择另一个可用的连接。如果所有连接都测试失败,则会创建一个新的连接。如果新连接测试失败,则会抛出SQLException

需要注意一点,对于 MySQL 数据库还必须在连接参数里加上autoReconnect=true参数,否则即使打开了test-before-use参数,仍然不能重连接。

fatal-sql-exception

null

用于配置 SQL 异常的检测和处理。它是一个逗号分隔的消息片段列表。当发生SQLException时,它的消息会与这些消息片段进行比较。如果它包含任何一个消息片段(区分大小写),则被视为致命的 SQL 异常。这将导致连接被丢弃。无论发生什么情况,异常都会被重新抛出,以便用户了解发生了什么。您还可以选择配置不同的异常被抛出(参见fatal-sql-exception-wrapper-class属性)。默认值为null

需要注意的是,如果设置了fatal-sql-exception-wrapper-class属性,可以配置一个替代的异常类来抛出。这样可以自定义处理 SQL 异常的方式。

fatal-sql-exception-wrapper-class

null

用于配置致命 SQL 异常的异常包装。当配置了fatal-sql-exception属性时,默认行为是丢弃导致致命SQLException的异常,并将原始异常直接抛给用户。使用该属性,您可以将SQLException包装在另一个异常中。这个异常可以是任何您想要的,只要它继承自SQLExceptionRuntimeException。Proxool 提供了两个类供您使用,如果您不想自己构建异常类的话:FatalSQLExceptionFatalRuntimeException。要使用这些类,您应该根据需要将该属性设置为org.logicalcobwebs.proxool.FatalSQLExceptionorg.logicalcobwebs.proxool.FatalRuntimeException。默认值为null,表示不包装致命SQLException。默认值为 null。

需要注意的是,异常包装类必须是SQLExceptionRuntimeException的子类。

house-keeping-sleep-time

30秒

用于设置连接池的维护线程(house keeping thread)的休眠时间。维护线程负责检查所有连接的状态,判断是否需要销毁或创建连接。默认值为 30 秒,意味着维护线程将每隔 30 秒执行一次维护任务。

injectable-connection-interface

N/A

用于允许 Proxool 实现委托 Connection 对象中定义的方法。

injectable-statement-interface

N/A

用于允许 Proxool 实现委托 Statement 对象中定义的方法。

injectable-prepared-statement-interface

N/A

用于允许 Proxool 实现委托 PreparedStatement 对象中定义的方法。

injectable-callable-statement-interface

N/A

用于允许 Proxool 实现委托 CallableStatement 对象中定义的方法。

jndi-name

N/A

用于指定连接池在 JNDI (Java Naming and Directory Interface) 中注册的名称。

Main.java 代码介绍

Main.java文件是示例程序的一部分,用于演示通过 Proxool 连接池获取数据库连接,并执行一系列数据库操作,包括创建表、插入数据、删除数据、更新数据、查询数据,并将查询结果打印出来。

本文Main.java文件的代码主要包括以下几个部分:

  1. 导入所需的类和接口。

    定义代码所在的包,并导入 Proxool 和 JDBC 相关的类。这些类用于实现数据库连接池的配置和管理,以及执行 SQL 语句。通过使用 Proxool 连接池,可以提高数据库操作的性能和可靠性。具体步骤如下:

    1. 定义了代码所在的包为com.example,该包用于存放当前 Java 类。

    2. 导入 Proxool 的配置类org.logicalcobwebs.proxool.configuration.PropertyConfigurator

    3. 导入用于读取配置文件的输入流类java.io.InputStream

    4. 导入 JDBC 的 Connection 类java.sql.Connection

    5. 导入 JDBC 的 DriverManager 类java.sql.DriverManager

    6. 导入 JDBC 的 ResultSet 类java.sql.ResultSet

    7. 导入 JDBC 的 Statement 类java.sql.Statement

    8. 导入用于加载配置文件的 Properties 类java.util.Properties

    代码如下:

    package com.example;
    
    import org.logicalcobwebs.proxool.configuration.PropertyConfigurator;
    import java.io.InputStream;
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.ResultSet;
    import java.sql.Statement;
    import java.util.Properties;
  2. 定义类名和方法。

    定义一个 Java 程序的入口方法,其中通过读取配置文件获取数据库连接信息,在使用 Proxool 驱动程序建立数据库连接后,依次调用定义好的方法执行 DDL 语句、DML 语句和查询语句。捕获并打印可能发生的异常信息。这段代码的目的是执行数据库相关的操作,并通过日志记录器进行日志记录。具体步骤如下:

    1. 定义了一个名为 Main 的公共类。

      1. 定义了一个名为DB_PROPERTIES_FILE的私有静态常量,表示数据库配置(属性)文件的路径。这个常量可以在代码中引用,以便加载和读取属性文件。

      2. 定义一个公共静态方法main,作为程序的起始执行点。

        1. 用于捕获可能发生异常的代码块。

          1. 创建一个Properties对象,用于读取配置文件中的属性。

          2. 使用 Main 类的类加载器获取配置文件的输入流。

          3. 使用加载的输入流加载配置文件,将属性加载到Properties对象中。

          4. 使用加载的属性配置连接池。

          5. 动态加载 Proxool 数据库驱动程序。

          6. 使用 Proxool 驱动程序建立数据库连接。

          7. 创建一个Statement对象。

          8. 调用定义好的方法executeDDLStatements(),执行 DDL 语句,是创建表的操作。

          9. 调用定义好的方法executeDMLStatements(),执行 DML 语句,是插入、更新和删除数据的操作。

          10. 调用定义好的方法executeQueryStatements(),执行查询语句,获取数据。

        2. 捕获并打印可能发生的异常信息。

    2. 定义了用于创建表、执行 DML 语句和查询数据的方法。

    代码如下:

    public class Main {
        private static final String DB_PROPERTIES_FILE = "/db.properties";
    
        public static void main(String[] args) {
            try {
                Properties properties = new Properties();
                InputStream is = Main.class.getResourceAsStream(DB_PROPERTIES_FILE);
                properties.load(is);
                PropertyConfigurator.configure(properties);
    
                Class.forName("org.logicalcobwebs.proxool.ProxoolDriver");
                try (Connection conn = DriverManager.getConnection("proxool.TEST");
                    Statement stmt = conn.createStatement()) {
                    executeDDLStatements(stmt);
                    executeDMLStatements(stmt);
                    executeQueryStatements(stmt);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        // 定义用于创建表的方法
        // 定义用于执行 DML 语句的方法
        // 定义用于查询数据的方法
    }
  3. 定义用于创建表的方法。

    定义一个私有静态方法executeDDLStatements(),用于执行 DDL(数据定义语言)语句,包括创建表的语句。具体步骤如下:

    1. 定义一个私有静态方法executeDDLStatements(),它接收一个Statement对象作为参数,并可能抛出Exception异常。

    2. 使用execute()方法执行 SQL 语句,创建一个名为test_proxool的表,该表有两列c1c2,分别为INT类型和VARCHAR(32)类型。

    代码如下:

        private static void executeDDLStatements(Statement stmt) throws Exception {
            stmt.execute("CREATE TABLE test_proxool (c1 INT, c2 VARCHAR(32))");
        }
  4. 定义用于执行 DML 语句的方法。

    定义一个私有静态方法executeDMLStatements(),用于执行 DML(数据操作语言)语句,包括插入数据、删除数据和更新数据的语句。具体步骤如下:

    1. 定义一个私有静态方法executeDMLStatements(),它接收一个Statement对象作为参数,如果在执行过程中出现异常,方法将抛出Exception异常。

    2. 使用for循环,从 1 到 10 进行迭代。在循环中,使用execute()方法执行 SQL 插入语句,将变量i和相关的字符串值插入到test_proxool表中。

    3. 执行 SQL 删除语句,从test_proxool表中删除c1列值小于等于 5 的行。

    4. 执行 SQL 更新语句,将test_proxool表中c1列值为 6 的行的c2列更新为test_update

    代码如下:

        private static void executeDMLStatements(Statement stmt) throws Exception {
            for (int i = 1; i <= 10; i++) {
                stmt.execute("INSERT INTO test_proxool VALUES (" + i + ",'test_insert" + i + "')");
            }
            stmt.execute("DELETE FROM test_proxool WHERE c1 <= 5");
            stmt.execute("UPDATE test_proxool SET c2 = 'test_update' WHERE c1 = 6");
        }
  5. 定义用于查询数据的方法。

    定义一个私有静态方法executeQueryStatements(),用于执行SELECT查询语句并处理结果。具体步骤如下:

    1. 定义一个私有静态方法executeQueryStatements(),它接收一个Statement对象作为参数,如果在执行过程中出现异常,方法将抛出Exception异常。

    2. 使用executeQuery()方法执行SELECT查询语句,并将结果存储在ResultSet对象rs中。在这里,查询返回了test_proxool表中的所有数据。使用try-with-resources语句,确保在使用完ResultSet后自动关闭它。

    3. 使用while循环和next()方法迭代ResultSet对象rs中的每一行数据。在每次迭代中,rs.next()方法将指针移动到结果集的下一行。如果还有下一行数据可用,则该方法返回true,否则返回false。在while循环中,只要rs.next()返回true,就表示还有更多的行数据可用。循环体内的代码将执行,并处理当前行的数据。当所有行的数据都被处理完毕后,rs.next()将返回false,循环结束。

    4. 通过getInt()getString()方法获取当前行中指定列名的值,并将它们打印到控制台。在这里,打印了c1c2列的值。getInt()方法用于获取整数值,getString()方法用于获取字符串值。

    代码如下:

        private static void executeQueryStatements(Statement stmt) throws Exception {
            try (ResultSet rs = stmt.executeQuery("SELECT * FROM test_proxool")) {
                while (rs.next()) {
                    System.out.println(rs.getInt("c1") + "   " + rs.getString("c2"));
                }
            }
        }

完整的代码展示

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.oceanbase</groupId>
    <artifactId>proxool-mysql-client</artifactId>
    <version>1.0-SNAPSHOT</version>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>8</source>
                    <target>8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <dependencies>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>
        <dependency>
            <groupId>proxool</groupId>
            <artifactId>proxool-cglib</artifactId>
            <version>0.9.1</version>
        </dependency>
        <dependency>
            <groupId>proxool</groupId>
            <artifactId>proxool</artifactId>
            <version>0.9.1</version>
        </dependency>
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.2</version>
        </dependency>
    </dependencies>
</project>

db.properties

#alias: the alias of the data source
jdbc-1.proxool.alias=TEST
#driver-class: driver name
jdbc-1.proxool.driver-class=com.mysql.jdbc.Driver
#driver-url: url connection string, username and password must be determined
jdbc-1.proxool.driver-url=jdbc:mysql://$host:$port/$database_name?useSSL=false
jdbc-1.user=$user_name
jdbc-1.password=$password
#The maximum number of database connections. The default is 15
jdbc-1.proxool.maximum-connection-count=8
#The minimum number of database connections, defaults to 5
jdbc-1.proxool.minimum-connection-count=5
#The number of available connections in the Connection pool. If the number of connections in the current Connection pool is less than this value, new connections will be established (assuming that the maximum number of available connections is not exceeded). For example, if we have three active connections and two available connections, and our prototype count is 4, the database Connection pool will try to establish another two connections. This is different from the minimum connection count Minimum connection count also counts active connections. Prototype count is the number of spare connections
jdbc-1.proxool.prototype-count=4
#verbose: detailed information settings. Parameter bool value
jdbc-1.proxool.verbose=true
#statistics: connection pool usage statistics. Parameter "10s, 1m, 1d"
jdbc-1.proxool.statistics=10s,1m,1d
#statistics-log-level:  log statistics tracking type. Parameter 'ERROR' or 'INFO'
jdbc-1.proxool.statistics-log-level=error

Main.java

package com.example;

import org.logicalcobwebs.proxool.configuration.PropertyConfigurator;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Properties;

public class Main {
    private static final String DB_PROPERTIES_FILE = "/db.properties";

    public static void main(String[] args) {
        try {
            Properties properties = new Properties();
            InputStream is = Main.class.getResourceAsStream(DB_PROPERTIES_FILE);
            properties.load(is);
            PropertyConfigurator.configure(properties);

            Class.forName("org.logicalcobwebs.proxool.ProxoolDriver");
            try (Connection conn = DriverManager.getConnection("proxool.TEST");
                Statement stmt = conn.createStatement()) {
                executeDDLStatements(stmt);
                executeDMLStatements(stmt);
                executeQueryStatements(stmt);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void executeDDLStatements(Statement stmt) throws Exception {
        stmt.execute("CREATE TABLE test_proxool (c1 INT, c2 VARCHAR(32))");
    }

    private static void executeDMLStatements(Statement stmt) throws Exception {
        for (int i = 1; i <= 10; i++) {
            stmt.execute("INSERT INTO test_proxool VALUES (" + i + ",'test_insert" + i + "')");
        }
        stmt.execute("DELETE FROM test_proxool WHERE c1 <= 5");
        stmt.execute("UPDATE test_proxool SET c2 = 'test_update' WHERE c1 = 6");
    }

    private static void executeQueryStatements(Statement stmt) throws Exception {
        try (ResultSet rs = stmt.executeQuery("SELECT * FROM test_proxool")) {
            while (rs.next()) {
                System.out.println(rs.getInt("c1") + "   " + rs.getString("c2"));
            }
        }
    }
}

相关文档