跳到主要内容

Tomcat 连接池连接 seekdb 示例程序

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

点击下载 tomcat-mysql-client 示例工程

前提条件

  • 您已安装 seekdb。

  • 您已安装 JDK 1.8 和 Maven。

  • 您已安装 IntelliJ IDEA。

    信息

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

操作步骤

信息

本文中给出的操作步骤是基于 Windows 环境生成。如果您使用的是其他操作系统环境或编译器,那么操作步骤可能会略有不同。

  1. 导入 tomcat-mysql-client 项目到 IDEA 中。
  2. 获取 seekdb 连接信息。
  3. 修改 tomcat-mysql-client 项目中的数据库连接信息。
  4. 搭建 tomcat-mysql-client 项目的 Tomcat 运行环境。
  5. 运行 tomcat-mysql-client 项目。

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

  1. 打开 IntelliJ IDEA,选择 File > Open... 选项。

    file

  2. 在弹出的 Open File or Project 窗口中,选择对应的项目文件,单击 OK 完成项目文件导入。

  3. IntelliJ IDEA 将会自动识别项目中的各类文件,并在 Project 工具窗口中,可以查看项目的目录结构、文件列表、模块列表、依赖关系等信息。Project 工具窗口通常位于 IntelliJ IDEA 界面的最左侧,默认情况下是打开的。如果 Project 工具窗口被关闭了,可以通过点击菜单栏中的 View > Tool Windows > Project 或者使用快捷键 Alt + 1 来重新打开它。

    信息

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

  4. 查看项目情况。

    tomcat

步骤二:获取 seekdb 连接信息

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

    mysql -hxx.xx.xx.xx -P2881 -uroot -p**** -A
  2. 根据已部署的 seekdb 填写下面 URL 的对应信息。

    信息

    application.properties 文件中需要这里的 URL 信息。

    jdbc:oceanbase://host:port/schema_name?user=$user_name&password=$password&characterEncoding=UTF-8

    参数说明:

    • host:提供 seekdb 的连接 IP。使用实际的 IP 替换,也可以使用本地 IP 及 127.0.0.1。
    • port:提供 seekdb 接端口。使用实际的端口替换,默认是 2881,在部署 seekdb 时可自定义。
    • schema_name:需要访问的 Schema 名称。
    • user_name:通过 -u 参数指定,格式为 用户。默认用户为 root
    • password:提供账户密码。
    • characterEncoding:支持数据库 URL 选项的字符编码。默认值:utf8

更多 URL 参数说明信息,请参见 数据库 URL

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

根据 步骤二:获取 seekdb 连接信息 中的信息修改 application.properties 文件中的数据库连接信息。

示例如下:

  • 数据库驱动的名称为:com.oceanbase.jdbc.Driver
  • seekdb 的 IP 地址为 10.10.10.1
  • 访问端口使用的是 2881。
  • 需要访问的 Schema 名称为 TEST
  • 连接账户是 root
  • 密码是 ******

示例代码如下:

#Apache Commons DBCP2 Connection Pool
#Database Connection Pool Driver Class Name
db.app.pool.driverClassName=com.oceanbase.jdbc.Driver
#Database URL
db.app.pool.url=jdbc:oceanbase://10.10.10.1/TEST?characterEncoding=UTF-8
#Database username
db.app.pool.username=root@xymysqll
#Database password
db.app.pool.password=******
#Initial size of connection pool
db.app.pool.initialSize=3
#Maximum number of connections in the connection pool
db.app.pool.maxTotal=10
#Maximum number of idle connections in the connection pool
db.app.pool.maxIdle=20
#Minimum number of idle connections in the connection pool
db.app.pool.minIdle=5
#Maximum wait time for obtaining connections (in milliseconds)
db.app.pool.maxWaitMillis=5000
#Verify the connection's query statement
db.app.pool.validationQuery=select 1 from dual

步骤四:搭建 tomcat-mysql-client 项目的 Tomcat 运行环境

  1. 下载 Tomcat 8.5.95 版本。

    Apache Tomcat 官网下载 Tomcat 8.5.95 版本的压缩包。解压下载的压缩包到您想要安装 Tomcat 的目录。

  2. 在 IDEA 中配置 Tomcat。

    打开 IntelliJ IDEA,进入 File 菜单,选择 Settings > Plugins。在 Settings 窗口中间的搜索框中搜索 Smart Tomcat,下载后选择 Apply,此时 Settings 窗口左侧最下方跳出 Tomcat Server 页签,进入 Tomcat Server 页签,单击右侧的 + 按钮,选择您解压缩的 Tomcat 目录,单击 Apply 后单击 OK,完成配置。

    Tomcat server

  3. 创建 Tomcat 运行配置。

    在 IDEA 的顶部工具栏中,选择 Run > Edit Configurations。在 Run/Debug Configurations 窗口中,单击 + 按钮,选择 Tomcat Server,填写运行服务器名称 Name,在 Configuration 选择框中选择 Tomcat sever 为您安装的版本,修改 Context path 值为 /,填写 SSL port 值为 8080。在 Before launch 选择框中,单击 +,选择 Launch Web Browser。单击 Edit 填写 URL 为 http://localhost:8080/hello/getData。单击 Apply 后单击 OK,完成配置。

    apache tomcat8.5.95

  4. 运行 Tomcat 服务器。

    在 IDEA 的顶部工具栏中,选择您刚刚创建的 Tomcat 运行配置。点击运行按钮绿色三角形启动 Tomcat 服务器。您可以在 IDEA 的 Run 窗口中查看 Tomcat 服务器的启动日志。

步骤五:运行 tomcat-mysql-client 项目

  1. 运行路径。

    在 IDEA 的顶部工具栏中,选择您刚刚创建的 Tomcat 运行配置。点击运行按钮绿色三角形启动 Tomcat 服务器。在谷歌或 IE 浏览器中打开路径 http://localhost:8080/hello/getData,查看运行结果。

  2. 运行结果。

    在 IDEA 的控制台窗口中来查看项目的日志信息和输出结果。

    • 插入数据后的结果。

      tomcat 连接池测试0
      tomcat 连接池测试1
      tomcat 连接池测试2
      tomcat 连接池测试3
      tomcat 连接池测试4
      tomcat 连接池测试5
      tomcat 连接池测试6
      tomcat 连接池测试7
      tomcat 连接池测试8
      tomcat 连接池测试9
    • 修改数据后的结果。

      -----修改后-----
      POOl 连接池测试0
      POOl 连接池测试1
      POOl 连接池测试2
      POOl 连接池测试3
      POOl 连接池测试4
      POOl 连接池测试5
      POOl 连接池测试6
      POOl 连接池测试7
      POOl 连接池测试8
      POOl 连接池测试9
    • 返回给 Web 界面的结果。

      Web

项目代码介绍

点击 tomcat-mysql-client 下载项目代码,这是一个名为 tomcat-mysql-client 的压缩包。

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

│--pom.xml

├─.idea

├─src
│ ├─main
│ │ ├─java
│ │ │ └─com
│ │ │ └─oceanbase
│ │ │ └─testtomcat
│ │ │ ├─config
│ │ │ │ └─UserConfig.java
│ │ │ │
│ │ │ ├─controller
│ │ │ │ └─UserController.java
│ │ │ │
│ │ │ └─pojo
│ │ │ └─User.java
│ │ │
│ │ ├─resources
│ │ │ └─application.properties
│ │ │
│ │ └─webapp
│ │ └─WEB-INF
│ │ └─web.xml
│ │
│ │
│ │
│ └─test
│ └─java


└─target

文件说明:

  • pom.xml:Maven 项目的配置文件,包含了项目的依赖、插件、构建等信息。
  • .idea:IDE(集成开发环境)中使用的目录,用于存储项目相关的配置信息。
  • src:通常用于表示项目中存放源代码的目录。
  • main: 存放主要的源代码和资源文件的目录。
  • java: 存放 Java 源代码的目录。
  • com: 存放 Java 包的根目录。
  • oceanbase: 存放项目的根目录。
  • testtomcat:存放 JFinal 框架的相关代码。
  • config:配置文件目录,包含应用程序的配置类文件。
  • UserConfig.java:用户配置类文件。
  • controller:控制器目录,包含应用程序的控制器类文件。
  • UserController.java:用户控制器类文件。
  • pojo: 存放 JavaBean 或实体类。
  • User.java:存放用户实体类。
  • resources: 存放资源文件的目录,如配置文件、SQL 文件等。
  • application.properties: 存放数据库连接信息的配置文件。
  • webapp:Web 应用程序目录,包含 Web 应用程序的静态资源和配置文件。
  • WEB-INF:Web 应用程序的 WEB-INF 目录,用于存放配置文件和其他受保护的资源文件。
  • web.xml:Web 应用程序的部署描述符文件。
  • test: 存放测试代码和资源文件的目录。
  • target: 存放编译后的 Class 文件、Jar 包等文件的目录。

pom.xml 代码介绍

信息

如果您只是想验证示例,那么请使用默认代码,无需修改。您也可以按照以下讲解,根据自己的需求修改 pom.xml 文件。

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.oceanbase
    2. 通过 <artifactId> 指定项目依赖为 tomcat-mysql-client
    3. 通过 <version> 指定项目的版本号为 1.0-SNAPSHOT
    4. 通过 <packaging> 指定项目的打包方式为 WAR 文件(Web 应用程序归档文件)。

    代码如下:

     <groupId>com.oceanbase</groupId>
    <artifactId>tomcat-mysql-client</artifactId>
    <version>1.0-SNAPSHOT</version>
    <!-- Packaging method (default to jar) -->
    <packaging>war</packaging>
  4. 配置 MAVEN 版本。

    通过 <maven.compiler.source><maven.compiler.target> 指定了编译器的源代码版本和目标代码版本都为 Java 8。

    代码如下:

     <properties>
    <maven.compiler.source>8</maven.compiler.source>
    <maven.compiler.target>8</maven.compiler.target>
    </properties>
  5. 配置核心依赖。

    1. 指定依赖项所属的组织为 com.jfinal,名称为 jfinal,版本号为 5.0.6,通过该依赖可以使用 JFinal 框架的功能。

      代码如下:

      <dependency>
      <groupId>com.jfinal</groupId>
      <artifactId>jfinal</artifactId>
      <version>5.0.6</version>
      </dependency>
    2. 指定依赖项所属的组织为 com.alibaba,名称为 druid,版本号为 1.2.8,通过该依赖可以使用 Druid 库,用于管理和优化数据库连接的获取和释放。

      代码如下:

      <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>druid</artifactId>
      <version>1.2.8</version>
      </dependency>
    3. 指定依赖项所属的组织为 org.apache.commons,名称为 commons-dbcp2,版本号为 2.9.0,通过该依赖可以使用 Apache Commons DBCP2 库,用于管理和优化数据库连接的获取和释放。

      代码如下:

      <dependency>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-dbcp2</artifactId>
      <version>2.9.0</version>
      </dependency>
    4. 指定依赖项所属的组织为 mysql,名称为 mysql-connector-java,版本号为 5.1.40,通过该依赖可以使用 seekdb 提供的客户端功能,如连接、查询、事务等。

      代码如下:

      <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.40</version>
      </dependency>

application.properties 文件介绍

application.properties 文件配置连接到 seekdb 的数据库连接信息。包括数据库驱动程序的类名、连接 URL、用户名、密码,以及连接池的相关配置。这些配置项用于在应用程序中获取和管理数据库连接,以便进行数据库操作。

  • 通过 db.app.pool.driverClassName 指定数据库驱动程序为 com.mysql.jdbc.Driver,用于与 seekdb 建立连接。

  • 通过 db.app.pool.url 指定连接数据库的 URL。

  • 通过 db.app.pool.username 指定连接数据库的用户名。

  • 通过 db.app.pool.password 指定连接数据库的密码。

  • 通过 db.app.pool.initialSize 指定连接池的初始大小为 3,即初始时创建 3 个数据库连接。

  • 通过 db.app.pool.maxTotal 指定连接池的最大为 10,即连接池中最多可以创建 10 个数据库连接。

  • 通过 db.app.pool.maxIdle 指定连接池空闲连接数最大为 20

  • 通过 db.app.pool.minIdle 指定连接池空闲连接数最小为 5

  • 通过 db.app.pool.maxWaitMillis 指定数据库连接的超时时间为 5000ms,即在获取数据库连接时,如果超过 5000ms 仍未获取到连接,则抛出超时异常。

  • 通过 db.app.pool.validationQuery 指定用于验证数据库连接的 SQL 查询语句为 select 1,即在从连接池中获取连接时,会执行这个查询语句来验证连接的有效性。

    代码如下:

      #Apache Commons DBCP2 Connection Pool
    #Database Connection Pool Driver Class Name
    db.app.pool.driverClassName=com.mysql.jdbc.Driver
    #Database URL
    db.app.pool.url=jdbc:mysql:////host:port/schema_name?characterEncoding=UTF-8
    #Database username
    db.app.pool.username=user_name
    #Database password
    db.app.pool.password=******
    #Initial size of connection pool
    db.app.pool.initialSize=3
    #Maximum number of connections in the connection pool
    db.app.pool.maxTotal=10
    #Maximum number of idle connections in the connection pool
    db.app.pool.maxIdle=20
    #Minimum number of idle connections in the connection pool
    db.app.pool.minIdle=5
    #Maximum wait time for obtaining connections (in milliseconds)
    db.app.pool.maxWaitMillis=5000
    #Verify the connection's query statement
    db.app.pool.validationQuery=select 1

Tomcat 内置连接池 DBCP 常用配置项:

提示

具体的属性(参数)配置取决于项目需求和数据库的特点,建议您根据实际情况进行调整和配置。

属性默认值描述
usernameN/A用于指定连接数据库的用户名。
passwordN/A用于指定连接数据库的密码。
urlN/A用于指定数据库的连接 URL。
driverClassNameN/A用于指定数据库驱动程序的标准 Java 类名。
connectionPropertiesN/A用于指定建立新连接时发送到 JDBC 驱动程序的连接属性,格式为 [propertyName=property;]
defaultAutoCommitdriver default用于指定连接池创建连接的默认自动提交状态。如果未设置,则不会调用 setAutoCommit 方法。
defaultReadOnlydriver default用于指定连接池创建连接的默认只读状态。如果未设置,则不会调用 setReadOnly 方法。
defaultTransactionIsolationdriver default用于指定连接池创建连接的默认事务隔离级别。
defaultCatalogN/A用于指定连接池创建的默认连接目录。
cacheStatetrue用于指定是否缓存连接的 readOnly 和 autoCommit 设置。如果为 True,则将在第一次读取或写入以及所有后续写入时缓存当前的 readOnly 和 autoCommit 设置。这消除了对 getter 的任何进一步调用的额外数据库查询的需要。
defaultQueryTimeoutnull用于设置连接池中连接创建语句的查询超时时间。如果为非 NULL,则此 Integer 属性的值确定将用于从池管理连接创建语句的查询超时;如果为 NULL,意味着将使用驱动程序默认值。
enableAutoCommitOnReturntrue用于指定连接返回池时是否检查并配置返回连接的自动提交。
rollbackOnReturntrue用于指定连接返回池时是否回滚未启用自动提交的、非只读的连接。如果为 True,表示未启用自动提交且连接不是只读的,则连接将在返回池时回滚。
initialSize0用于设置连接池启动时创建的初始连接数。
maxTotal8用于设置从连接池中分配的最大活动连接数。
maxIdle8用于设置连接池中保持空闲的最大连接数,不会释放额外的连接数。若设置为负数表示没有限制。
minIdle0用于设置连接池中保持空闲的最小连接数,不会创建额外的连接。取值为 0 表示不创建。
maxWaitMillisindefinitely用于设置在抛出异常之前,池等待(当没有可用连接时)连接返回的最大毫秒数,取值为 -1 表示无限期等待。
validationQueryN/A用于指定验证连接的 SQL 查询语句。如果指定该值,则必须是至少返回一行 SQL SELECT 语句;如果未指定该值,则连接将通过调用 isValid 方法进行验证。
validationQueryTimeoutno timeout用于设置连接验证查询失败之前的超时时间,单位为秒。如果设置为正值,则该值通过用于执行验证查询的 setQueryTimeout 方法传递给驱动程序 Statement。
testOnCreatefalse用于指定创建连接后是否验证对象。如果对象无法验证,则触发对象创建的借用尝试将失败。
testOnBorrowtrue用于指定在连接池中借用对象之前是否将对其进行验证的指示。如果对象无法验证,则从连接池中删除该对象,并尝试借用另一个对象。
testOnReturnfalse用于指定对象在返回池之前是否经过验证的指示。
testWhileIdlefalse用于指定对象是否将由空闲对象驱逐器(如果有)验证的指示。如果对象未能通过验证,它将从连接池中删除。
timeBetweenEvictionRunsMillis-1用于设置空闲对象驱逐线程运行间休眠的毫秒数。当取值为非正数时,不会运行空闲对象驱逐线程。
numTestsPerEvictionRun3用于设置在空闲对象驱逐线程的每次运行期间要检查的对象数。
minEvictableIdleTimeMillis1000 * 60 * 30用于设置对象在连接池中闲置的最短时间。
softMinEvictableIdleTimeMillis-1用于设置连接在池中处于空闲状态的最短时间,包括 MinIdle 约束。
maxConnLifetimeMillis-1用于设置连接的最大生命周期,单位为毫秒。超过此时间后,连接将无法进行下一次激活、钝化或验证测试。取值为 0 或更小,意味着连接具有无限的生命周期。
logExpiredConnectionstrue用于指定是否记录超过最大生命周期而被池关闭的连接。取值为 False 表示禁止启用的过期连接日志记录。
connectionInitSqlsnull用于指定在首次创建物理连接时初始化的 SQL 语句集合。这些语句只在配置的连接工厂创建连接时执行。
lifotrue用于指定 borrowObject 方法是否返回池中最近使用的连接。取值为 True 表示 borrowObject 返回池中最近使用的 last in 连接(如果有空闲连接可用);取值为 False 表示将连接按照返回到池中的顺序从空闲实例池中获取连接(FIFO 队列)。
poolPreparedStatementsfalse用于指定是否启用准备好的语句池。
maxOpenPreparedStatementsunlimited用于设置从连接池中分配的最大打开语句数,取值为负数时表示无限制。
accessToUnderlyingConnectionAllowedfalse用于指定是否允许访问底层连接。
removeAbandonedOnMaintenancefalse用于指定连接池维护周期内是否删除废弃的连接。取值为 True 时会在维护周期(驱逐结束时)删除废弃的连接,除非通过将 timeBetweenEvictionRunsMillis 设置为正值来启用维护,否则此属性无效。
removeAbandonedOnBorrowfalse用于指定从连接池中借用连接时是否删除废弃的连接。取值为 True 时每次从池中借用连接时都会删除废弃的连接,并具有以下附加要求:
  • getNumActive() > getMaxTotal() - 3
  • getNumIdle() < 2
removeAbandonedTimeout300用于设置删除废弃连接之前的超时时间,单位为秒。通过配置这个参数,可以指定连接在被视为废弃并可删除之前的最长空闲时间。
logAbandonedfalse用于指定是否记录废弃连接的应用程序代码的堆栈跟踪。由于必须生成堆栈跟踪,因此记录放弃的语句和连接会增加每个连接打开或新语句的开销。
abandonedUsageTrackingfalse用于指定是否记录废弃连接的堆栈跟踪。取值为 True,表示每次在池连接上调用方法时,连接池都会记录堆栈跟踪,并保留最近的堆栈跟踪以帮助调试废弃的连接,且设置为 True 会增加大量开销。
fastFailValidationfalse用于指定对抛出致命 SQLException 的连接,验证是否快速失败。取值为 True 时,验证断开连接的请求会立即失败,不会调用驱动程序的 isValid 方法或尝试执行验证查询。被认为是致命错误信号的 SQL_STATE 代码默认如下:
  • 57P01(管理员关机)
  • 57P02(崩溃关闭)
  • 57P03(现在无法连接)
  • 01002(SQL92 断开连接错误)
  • JZ0C0(Sybase 断开连接错误)
  • JZ0C1(Sybase 断开连接错误)
  • 任何以 08 开头的 SQL_STATE 代码
要覆盖此默认断开代码集,请设置 disconnectionSqlCodes 属性。
disconnectionSqlCodesnull用于指定一组以逗号分隔的 SQL_STATE 代码列表,这些代码被认为是发出致命断开连接错误的信号。当设置 fastFailValidation 参数为 True 时,设置 disconnectionSqlCodes 属性才会生效。
jmxNameN/A用于指定可操作和监控的数据源对象,将数据源注册为指定名称下的 JMX MBean。该名称必须符合 JMX 对象名称语法(请参见 javadoc)。

web.xml 代码介绍

web.xml 文件用于配置 Web 应用程序的过滤器。

web.xml 配置文件内容如下:

  1. 文件声明语句。

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

    代码如下:

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

    1. 通过 xmlns:xsi 指定 XML 命名空间为 http://www.w3.org/2001/XMLSchema-instance
    2. 通过 xmlns 指定 XML 的命名空间为 http://java.sun.com/xml/ns/javaee
    3. 通过 xsi:schemaLocation 指定 XML 的命名空间为 http://java.sun.com/xml/ns/javaee,并指定 XML 的 XSD 文件的位置为 http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd
    4. 通过 <id><version> 元素指定 Web 应用程序的 ID 为 WebApp_ID,版本号为 3.0

    代码如下:

     <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns="http://java.sun.com/xml/ns/javaee"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    id="WebApp_ID"
    version="3.0">
  3. 配置 JFinal 过滤器。

    配置了一个名为 jfinal 的过滤器,用于在 Web 应用程序中使用 JFinal 框架。指定过滤器的类为 com.jfinal.core.JFinalFilter。通过指定初始化参数 configClass,指定 JFinal 框架的配置类的位置为 com.oceanbase.testtomcat.config.UserConfig。JFinal 过滤器用于在 Web 应用程序中使用 JFinal 框架,并根据指定的配置类来配置 JFinal 框架的行为。

    代码如下:

     <filter>
    <filter-name>jfinal</filter-name>
    <filter-class>com.jfinal.core.JFinalFilter</filter-class>
    <init-param>
    <param-name>configClass</param-name>
    <!-- your jfinal configuration location -->
    <param-value>com.oceanbase.testtomcat.config.UserConfig</param-value>
    </init-param>
    </filter>
  4. 配置 JFinal 过滤器映射。

    jfinal 过滤器应用到所有的请求路径,即该过滤器将应用于应用程序中的所有请求。

    代码如下:

     <filter-mapping>
    <filter-name>jfinal</filter-name>
    <url-pattern>/*</url-pattern>
    </filter-mapping>

UserConfig.java 文件介绍

UserConfig.java 文件用于配置应用程序的路由、插件、数据库连接等相关信息。

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

  1. 引用其他类和接口。

    声明当前文件包含以下接口和类:

    • StatFilter 类:用于统计数据库访问的性能。
    • JdbcConstants 类:用于定义数据库类型的常量。
    • WallFilter 类:用于防止 SQL 注入攻击。
    • PropKit 类:用于读取配置文件。
    • ActiveRecordPlugin 类:用于操作数据库。
    • Db 类:用于执行数据库操作。
    • MysqlDialect 类:用于指定数据库的方言。
    • DruidPlugin 类:用于连接数据库。
    • Engine 类:用于配置模板引擎。
    • UserController 类:用于处理用户相关的请求。
    • User 类:用于传递和存储用户数据。

    代码如下:

    import com.alibaba.druid.filter.stat.StatFilter;
    import com.alibaba.druid.util.JdbcConstants;
    import com.alibaba.druid.wall.WallFilter;
    import com.jfinal.config.*;
    import com.jfinal.kit.PropKit;
    import com.jfinal.plugin.activerecord.ActiveRecordPlugin;
    import com.jfinal.plugin.activerecord.Db;
    import com.jfinal.plugin.activerecord.dialect.MysqlDialect;
    import com.jfinal.plugin.druid.DruidPlugin;
    import com.jfinal.template.Engine;
    import com.oceanbase.testjfinal.controller.UserController;
    import com.oceanbase.testjfinal.pojo.User;
  2. 定义 UserConfig 类。

    通过重写 JFinalConfig 类的各个方法,可以配置常量、路由、插件和数据库连接等信息。

    1. 定义 configConstant 方法。

      用于配置 JFinal 框架的常量,使用 PropKit 读取配置文件中的配置。

      代码如下:

      @Override
      public void configConstant(Constants constants) {
      PropKit.use("application.properties");
      }
    2. 定义 configRoute 方法。

      用于配置路由映射,使用 routes.add 方法将 "/hello" 路径映射到 UserController 类的默认访问页面。

      代码如下:

      @Override
      public void configRoute(Routes routes) {
      routes.add("/hello", UserController.class, "/");
      }
    3. 定义 configEngine 方法。

      用于配置模板引擎。

      代码如下:

      @Override
      public void configEngine(Engine engine) {
      }
    4. 定义 configPlugin 方法。

      用于配置应用程序的插件。通过调用 init 方法进行初始化数据库连接和表结构,创建 DruidPluginActiveRecordPlugin 插件,并将它们添加到 plugins 中。同时,通过调用 activeRecordPluginaddMapping 方法,添加数据库表和实体类的映射关系,将 TEST_USER 表与 User 类进行映射。

      代码如下:

      @Override
      public void configPlugin(Plugins plugins) {
      init();
      DruidPlugin druidPlugin = createDruidPlugin();
      plugins.add(druidPlugin);

      ActiveRecordPlugin activeRecordPlugin = createActiveRecordPlugin(druidPlugin);
      activeRecordPlugin.addMapping("TOMCAT_TEST", User.class);
      plugins.add(activeRecordPlugin);
      }
    5. 定义 createDruidPlugin 方法。

      用于创建 DruidPlugin 插件并配置相关参数,包括连接池大小、SQL 防火墙、连接错误处理等。

      • 通过调用 PropKitget 方法,获取配置文件中的数据库连接相关属性值,包括 URL、用户名、密码和驱动类。然后创建 DruidPlugin 对象,并使用获取到的属性值进行初始化。

      • 通过调用 addFilter 方法,向 DruidPlugin 中添加一个 StatFilter 实例,用于统计数据库访问的性能。创建一个 WallFilter 实例,通过 setDbType 方法设置数据库类型为 OceanBase,并将其添加到 DruidPlugin 中,用于进行 SQL 防火墙过滤。

      • 通过调用 setInitialSize 方法设置连接池的初始大小;setMaxPoolPreparedStatementPerConnectionSize 方法设置每个连接池的最大预处理语句数量;setTimeBetweenConnectErrorMillis 方法设置两次连接错误之间的时间间隔;setValidationQuery 方法设置连接的验证查询语句。最后,返回创建的 DruidPlugin 实例。

        代码如下:

        private DruidPlugin createDruidPlugin() {
        DruidPlugin druidPlugin = new DruidPlugin(
        PropKit.get("db.app.pool.url"),
        PropKit.get("db.app.pool.username"),
        PropKit.get("db.app.pool.password"),
        PropKit.get("db.app.pool.driverClassName")
        );

        druidPlugin.addFilter(new StatFilter());
        WallFilter wallFilter = new WallFilter();
        wallFilter.setDbType(JdbcConstants.OCEANBASE);
        druidPlugin.addFilter(wallFilter);

        druidPlugin.setInitialSize(PropKit.getInt("db.app.pool.initialSize"));
        druidPlugin.setMaxPoolPreparedStatementPerConnectionSize(PropKit.getInt("db.app.pool.maxTotal"));
        druidPlugin.setTimeBetweenConnectErrorMillis(PropKit.getInt("db.app.pool.maxWaitMillis"));
        druidPlugin.setValidationQuery("select 1");

        return druidPlugin;
        }
    6. 定义 init 方法。

      用于初始化数据库连接和创建数据库表。通过调用 initDbConnection 方法初始化数据库连接,并返回一个 ActiveRecordPlugin 实例。其次,通过执行 SQL 语句查询用户表 TOMCAT_TEST 是否存在。如果表 TOMCAT_TEST 存在,则执行 SQL 语句 DROP TABLE TOMCAT_TEST 删除该表。然后执行 CREATE TABLE 语句创建名为 TOMCAT_TEST 的数据库表,该表包含 IDUSERNAME 两个字段。最后关闭 ActiveRecordPlugin 插件的连接,释放数据库连接。

      代码如下:

      public void init() {
      ActiveRecordPlugin arp = initDbConnection();

      // Check if table exists
      boolean tableExists = Db.queryInt("SELECT COUNT(*) FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'TEST' AND TABLE_NAME = 'TOMCAT_TEST'") > 0;

      // Drop table if it exists
      if (tableExists) {
      Db.update("DROP TABLE TOMCAT_TEST");
      }

      // Create table
      String sql = "CREATE TABLE TOMCAT_TEST (ID int, USERNAME varchar(50))";
      Db.update(sql);

      arp.stop();
      }
    7. 定义 initDbConnection 方法。

      用于初始化数据库的连接。首先通过调用 createDruidPlugin 方法创建 DruidPlugin 对象,并将其赋值给变量 druidPlugin,该方法负责创建和配置 DruidPlugin,用于数据库连接池的管理。其次通过调用 createActiveRecordPlugin 方法创建 ActiveRecordPlugin 对象,并将 DruidPlugin 对象作为参数传递到该方法中,该方法负责创建和配置 ActiveRecordPlugin,用于数据库操作的管理。然后调用 druidPlugin.start 方法启动 DruidPlugin 初始化数据库连接池。最后调用 activeRecordPlugin.start 方法启动 ActiveRecordPlugin,该方法会根据配置来初始化数据库操作的相关设置。

      代码如下:

      private ActiveRecordPlugin initDbConnection() {
      DruidPlugin druidPlugin = createDruidPlugin();
      ActiveRecordPlugin activeRecordPlugin = createActiveRecordPlugin(druidPlugin);

      druidPlugin.start();
      activeRecordPlugin.start();

      return activeRecordPlugin;
      }
    8. 定义 ConfigInterceptorConfigHandler 方法。

      用于在系统初始化过程中进行全局配置。

      代码如下:

      @Override
      public void configInterceptor(Interceptors interceptors) {
      }

      @Override
      public void configHandler(Handlers handlers) {
      }

UserController.java 文件介绍

UserController.java 文件通过 getData 方法插入数据到数据库并查询数据,并将查询结果以 JSON 格式返回给客户端。通过使用 JFinal 框架提供的 Db 类执行数据库操作,以及使用自定义的 User 类进行数据映射,实现对数据库的操作和数据返回的功能。

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

  1. 引用其他类和接口。

    声明当前文件包含以下接口和类:

    • Controller 类:用于处理请求和响应。
    • Db 类:用于执行数据库操作。
    • Record 类:用于进行数据库操作,查询、插入、更新和删除数据等。
    • ArrayList 类:用于创建一个空的列表。
    • User 类:用于映射数据库表。
    • List 接口:用于操作查询结果集合。

    代码如下:

    import com.jfinal.core.Controller;
    import com.jfinal.plugin.activerecord.Db;
    import com.jfinal.plugin.activerecord.Record;

    import java.util.ArrayList;
    import java.util.List;
  2. 定义 UserController 类。

    用于给 JFinal 框架提供控制器,使用 getData 方法对数据库进行插入数据和查询数据操作。

    1. 插入数据。创建一个包含 10 个 Record 对象的列表 dataList,每个 Record 对象都具有不同的 IDUSERNAME 字段值。然后,使用 Db.batchSave 方法将 dataList 列表中的记录批量保存到名为 TOMCAT_TEST 的数据库表中。

      代码如下:

              for (int i = 0; i < 10; i++) {
      Record record = new Record().set("ID", i).set("USERNAME", "tomcat 连接池测试" + i);
      dataList.add(record);
      }
      Db.batchSave("TOMCAT_TEST", dataList, dataList.size());
    2. 查询数据。通过 Db.find 方法执行 SQL 查询,将结果存储在 resultList 列表中。使用增强型的 for 循环遍历 resultList 列表中的每个 Record 对象。通过 getStr 方法获取 Record 对象中指定字段的值,并使用 System.out.println 方法打印输出。

      代码如下:

          List<Record> resultList = Db.find("SELECT * FROM TOMCAT_TEST");
      for (Record result : resultList) {
      System.out.println(result.getStr("USERNAME"));
      }
    3. 修改数据。使用循环迭代 10 次,每次迭代都执行一条更新语句。更新语句使用 Db.update 方法执行,将名为 TOMCAT_TEST 的数据库表中的记录根据条件进行更新。

      代码如下:

          for (int i = 0; i < 10; i++) {
      Db.update("UPDATE TOMCAT_TEST SET USERNAME = 'POOl 连接池测试" + i + "' WHERE ID = " + i);
      }
    4. 查询修改后数据。查询名为 TOMCAT_TEST 的数据库表,并将结果保存在 modifiedList 中。打印 -----修改后----- 的提示信息。遍历 modifiedList,打印每个记录的 USERNAME 字段值。使用 renderJson 方法将响应消息 Data retrieved successfully 渲染为 JSON 格式,返回给客户端。

      代码如下:

              List<Record> modifiedList = Db.find("SELECT * FROM TOMCAT_TEST");
      System.out.println("-----修改后-----");
      for (Record modified : modifiedList) {
      System.out.println(modified.getStr("USERNAME"));
      }
      renderJson("Data retrieved successfully");

User.java 文件介绍

User.java 文件用于实现数据库表与 Java 对象的映射。

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

  1. 引用 Model 类。

    Model 类用于映射数据库表和操作数据。

  2. 定义 User 类。

    User 类通过继承的 Model 类提供的方法来进行数据库操作。

    代码如下:

    import com.jfinal.plugin.activerecord.Model;


    public class User extends Model<User> {
    public static final User dao = new User();
    }

完整的代码展示

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>tomcat-mysql-client</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- Packaging method (default to jar) -->
<packaging>war</packaging>

<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>com.jfinal</groupId>
<artifactId>jfinal</artifactId>
<version>5.0.6</version>
</dependency>


<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.8</version>
</dependency>

<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.40</version>
</dependency>

</dependencies>
</project>

application.properties

    #Apache Commons DBCP2 Connection Pool
#Database Connection Pool Driver Class Name
db.app.pool.driverClassName=com.mysql.jdbc.Driver
#Database URL
db.app.pool.url=jdbc:mysql:////host:port/schema_name?characterEncoding=UTF-8
#Database username
db.app.pool.username=user_name
#Database password
db.app.pool.password=******
#Initial size of connection pool
db.app.pool.initialSize=3
#Maximum number of connections in the connection pool
db.app.pool.maxTotal=10
#Maximum number of idle connections in the connection pool
db.app.pool.maxIdle=20
#Minimum number of idle connections in the connection pool
db.app.pool.minIdle=5
#Maximum wait time for obtaining connections (in milliseconds)
db.app.pool.maxWaitMillis=5000
#Verify the connection's query statement
db.app.pool.validationQuery=select 1

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<filter>
<filter-name>jfinal</filter-name>
<filter-class>com.jfinal.core.JFinalFilter</filter-class>
<init-param>
<param-name>configClass</param-name>
<!-- your jfinal configuration location -->
<param-value>com.oceanbase.testjfinal.config.UserConfig</param-value>
</init-param>
</filter>

<filter-mapping>
<filter-name>jfinal</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>

UserConfig.java

package com.oceanbase.testtomcat.config;

import com.alibaba.druid.filter.stat.StatFilter;
import com.alibaba.druid.util.JdbcConstants;
import com.alibaba.druid.wall.WallFilter;
import com.jfinal.config.*;
import com.jfinal.kit.PropKit;
import com.jfinal.plugin.activerecord.ActiveRecordPlugin;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.dialect.MysqlDialect;
import com.jfinal.plugin.druid.DruidPlugin;
import com.jfinal.template.Engine;
import com.oceanbase.testtomcat.controller.UserController;
import com.oceanbase.testtomcat.pojo.User;

public class UserConfig extends JFinalConfig {
@Override
public void configConstant(Constants constants) {
// Read properties configuration
PropKit.use("application.properties");
}

@Override
public void configRoute(Routes routes) {
// Set the default access page for project startup, which does not need to be set in the web.
routes.add("/hello", UserController.class);

}

@Override
public void configEngine(Engine engine) {
}

@Override
public void configPlugin(Plugins plugins) {
init();
DruidPlugin druidPlugin = createDruidPlugin();
plugins.add(druidPlugin);

ActiveRecordPlugin activeRecordPlugin = createActiveRecordPlugin(druidPlugin);
activeRecordPlugin.addMapping("TOMCAT_TEST", User.class);
plugins.add(activeRecordPlugin);
}

private DruidPlugin createDruidPlugin() {
DruidPlugin druidPlugin = new DruidPlugin(
PropKit.get("db.app.pool.url"),
PropKit.get("db.app.pool.username"),
PropKit.get("db.app.pool.password"),
PropKit.get("db.app.pool.driverClassName")
);

druidPlugin.addFilter(new StatFilter());
WallFilter wallFilter = new WallFilter();
wallFilter.setDbType(JdbcConstants.OCEANBASE);
druidPlugin.addFilter(wallFilter);

druidPlugin.setInitialSize(PropKit.getInt("db.app.pool.initialSize"));
druidPlugin.setMaxPoolPreparedStatementPerConnectionSize(PropKit.getInt("db.app.pool.maxTotal"));
druidPlugin.setTimeBetweenConnectErrorMillis(PropKit.getInt("db.app.pool.maxWaitMillis"));
druidPlugin.setValidationQuery("select 1 from dual");

return druidPlugin;
}

private ActiveRecordPlugin createActiveRecordPlugin(DruidPlugin druidPlugin) {
ActiveRecordPlugin activeRecordPlugin = new ActiveRecordPlugin(druidPlugin);
activeRecordPlugin.setDialect(new MysqlDialect());

return activeRecordPlugin;
}

public void init() {
ActiveRecordPlugin arp = initDbConnection();

// Check if table exists
boolean tableExists = Db.queryInt("SELECT COUNT(*) FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'TEST' AND TABLE_NAME = 'TOMCAT_TEST'") > 0;

// Drop table if it exists
if (tableExists) {
Db.update("DROP TABLE TOMCAT_TEST");
}

// Create table
String sql = "CREATE TABLE TOMCAT_TEST (ID int, USERNAME varchar(50))";
Db.update(sql);

arp.stop();
}
private ActiveRecordPlugin initDbConnection() {
DruidPlugin druidPlugin = createDruidPlugin();
ActiveRecordPlugin activeRecordPlugin = createActiveRecordPlugin(druidPlugin);

druidPlugin.start();
activeRecordPlugin.start();

return activeRecordPlugin;
}

@Override
public void configInterceptor(Interceptors interceptors) {
}

@Override
public void configHandler(Handlers handlers) {
}
}

UserController.java

package com.oceanbase.testtomcat.controller;

import com.jfinal.core.Controller;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;

import java.util.ArrayList;
import java.util.List;

public class UserController extends Controller {


public void getData() {
try {
List<Record> dataList = new ArrayList<>();
// 插入数据
for (int i = 0; i < 10; i++) {
Record record = new Record().set("ID", i).set("USERNAME", "tomcat 连接池测试" + i);
dataList.add(record);
}
Db.batchSave("TOMCAT_TEST", dataList, dataList.size());
// 查询数据
List<Record> resultList = Db.find("SELECT * FROM TOMCAT_TEST");
for (Record result : resultList) {
System.out.println(result.getStr("USERNAME"));
}
// 修改数据
for (int i = 0; i < 10; i++) {
Db.update("UPDATE TOMCAT_TEST SET USERNAME = 'POOl 连接池测试" + i + "' WHERE ID = " + i);
}
// 查询修改后的数据
List<Record> modifiedList = Db.find("SELECT * FROM TOMCAT_TEST");
System.out.println("-----修改后-----");
for (Record modified : modifiedList) {
System.out.println(modified.getStr("USERNAME"));
}
renderJson("Data retrieved successfully");
} catch (Exception e) {
e.printStackTrace();
renderJson("Error occurred");
}
}
}

User.java

package com.oceanbase.testtomcat.pojo;

import com.jfinal.plugin.activerecord.Model;


public class User extends Model<User> {
public static final User dao = new User();

}

相关文档

更多 OceanBase Connector/J 的信息,请参见 OceanBase JDBC 驱动程序