This topic describes how to build an application that uses a Tomcat connection pool and OceanBase Connector/J to connect to an OceanBase database. The application performs basic database operations, such as creating tables and inserting, deleting, updating, and querying data.
Download the tomcat-mysql-client sample project
Prerequisites
OceanBase Database is installed.
JDK 1.8 and Maven are installed.
IntelliJ IDEA is installed.
The code in this topic is run using IntelliJ IDEA 2021.3.2 (Community Edition). You can also use other tools to run the sample code.
Procedure
The steps in this topic are based on a Windows environment. The steps may vary slightly if you use a different operating system or compiler.
Import the
tomcat-mysql-clientproject into IDEA.Obtain the OceanBase Database connection information.
Modify the database connection information in the
tomcat-mysql-clientproject.Set up the Tomcat runtime environment for the
tomcat-mysql-clientproject.Run the
tomcat-mysql-clientproject.
Step 1: Import the tomcat-mysql-client project into IDEA
Open IntelliJ IDEA and choose File > Open....
In the Open File or Project window, select the project file and click OK to import it.
IntelliJ IDEA automatically detects the files in the project. You can view the project's directory structure, file list, module list, and dependencies in the Project tool window. This window is typically located on the far left of the IntelliJ IDEA interface and is open by default. If the Project tool window is closed, you can reopen it by choosing View > Tool Windows > Project or using the Alt + 1 keyboard shortcut.
NoteWhen you import a project into IntelliJ IDEA, it automatically detects the pom.xml file. IntelliJ IDEA then downloads the required dependency libraries based on the dependencies described in the file and adds them to the project.
View the project status.

Step 2: Obtain the OceanBase Database connection information
Contact the OceanBase Database deployment personnel or administrator to obtain the database connection string.
obclient -hxx.xx.xx.xx -P3306 -uroot -p**** -AUse your OceanBase Database information to fill in the following URL.
NoteThe URL information is required in the
application.propertiesfile.jdbc:oceanbase://host:port/schema_name?user=$user_name&password=$password&characterEncoding=UTF-8Parameter description:
host: The domain name for the OceanBase Database connection.port: The connection port of the OceanBase database. The default port for a MySQL-mode tenant is 3306.schema_name: The name of the schema to access.user_name: The username of the tenant connection account.password: The account password.characterEncoding: The character encoding supported by the database URL. The default value isutf8.
For more information about URL parameters, see Database URL.
Step 3: Modify the tomcat-mysql-client project's database connection information
Modify the database connection information in the application.properties file based on the information that you obtained in Step 2: Obtain the OceanBase Database connection information.
Example:
The database driver name is
com.oceanbase.jdbc.Driver.The IP address of the OBServer node is
xxx.xxx.xxx.xxx.The access port is 3306.
The name of the schema to access is
TEST.The username of the tenant connection account is
root.The password is
******.
Example:
#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://xxx.xxx.xxx.xxx/TEST?characterEncoding=UTF-8
#Database username
db.app.pool.username=root
#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
Step 4: Set up the Tomcat runtime environment for the tomcat-mysql-client project
Download Tomcat 8.5.95.
Download the compressed package for Tomcat 8.5.95 from the Apache Tomcat official website . Decompress the downloaded package to your preferred Tomcat installation directory.
Configure Tomcat in IDEA.
In IntelliJ IDEA, go to the File menu and choose Settings > Plugins. In the Settings window, search for Smart Tomcat and install it. After the installation is complete, click Apply. The Tomcat Server tab appears in the navigation pane on the left of the Settings window. Go to the Tomcat Server tab, click the + button, select the directory where you decompressed Tomcat, click Apply, and then click OK.
Create a Tomcat run configuration.
On the top toolbar of IDEA, choose Run > Edit Configurations. In the Run/Debug Configurations window, click the + button and select Tomcat Server. In the Name field, enter a server name. From the Tomcat sever drop-down list, select the version that you installed. Set Context path to
/and SSL port to8080. In the Before launch section, click + and select Launch Web Browser. Click Edit and enter the URLhttp://localhost:8080/hello/getData. Click Apply and then click OK to save the configuration.Run the Tomcat server.
On the top toolbar of IDEA, select the Tomcat run configuration that you just created. Click the run button (green triangle) to start the Tomcat server. You can view the startup logs of the Tomcat server in the Run window in IDEA.
Step 5: Run the tomcat-mysql-client project
Execution path.
On the top toolbar of IDEA, select the Tomcat run configuration that you just created. Click the run button (green triangle) to start the Tomcat server. Open
http://localhost:8080/hello/getDatain a browser, such as Google Chrome or Internet Explorer, to view the result.Result.
You can view the project's log information and output in the console window in IDEA.
Result after data insertion.
Tomcat connection pool test 0 Tomcat connection pool test 1 Tomcat connection pool test 2 Tomcat connection pool test 3 Tomcat connection pool test 4 Tomcat connection pool test 5 Tomcat connection pool test 6 Tomcat connection pool test 7 Tomcat connection pool test 8 Tomcat connection pool test 9Result after data modification.
-----After modification----- POOL connection pool test 0 POOL connection pool test 1 POOL connection pool test 2 POOL connection pool test 3 POOL connection pool test 4 POOL connection pool test 5 POOL connection pool test 6 POOL connection pool test 7 POOL connection pool test 8 POOL connection pool test 9Result returned on the web page.
Project code introduction
Click tomcat-mysql-client to download the project code. The code is in a compressed package named tomcat-mysql-client.
After you decompress the package, a folder named tomcat-mysql-client is created. The directory structure is as follows:
│--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
File description:
pom.xml: The configuration file for the Maven project. It contains information about the project's dependencies, plugins, and build..idea: A directory used by the integrated development environment (IDE) to store project-related configuration information.src: The directory that stores the source code of the project.main: The directory that stores the main source code and resource files.java: The directory that stores the Java source code.com: The root directory for Java packages.oceanbase: The root directory of the project.testtomcat: Contains the code related to the JFinal framework.config: The configuration directory, which contains the configuration class files for the application.UserConfig.java: The user configuration class file.controller: The controller directory, which contains the controller class files for the application.UserController.java: The user controller class file.pojo: Contains JavaBeans or entity classes.User.java: Contains the user entity class.resources: The directory that contains resource files, such as configuration files and SQL files.application.properties: The configuration file that contains database connection information.webapp: The web application directory. It contains static resources and configuration files for the web application.WEB-INF: The `WEB-INF` directory of the web application, which is used to store configuration files and other protected resource files.web.xml: The deployment descriptor file for the web application.test: The directory that contains test code and resource files.target: The directory that contains compiled class files, JAR packages, and other build artifacts.
pom.xml code introduction
If you only want to verify the example, you can use the default code without modification. You can also modify the pom.xml file as needed based on the following explanation.
The pom.xml configuration file contains the following sections:
File declaration
This section declares that the file is an XML file, the XML version is
1.0, and the character encoding isUTF-8.Code:
<?xml version="1.0" encoding="UTF-8"?>POM namespace and model version configuration
The
xmlnsattribute specifies the POM namespace ashttp://maven.apache.org/POM/4.0.0.The
xmlns:xsiattribute specifies the XML namespace ashttp://www.w3.org/2001/XMLSchema-instance.The
xsi:schemaLocationattribute specifies the POM namespace ashttp://maven.apache.org/POM/4.0.0and the location of the POM's XSD file ashttp://maven.apache.org/xsd/maven-4.0.0.xsd.The
<modelVersion>element specifies that the POM model version used by this POM file is4.0.0.
Code:
<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>Configure the basic information.
The
<groupId>element specifies the project ID ascom.oceanbase.The
<artifactId>element specifies the project artifact astomcat-mysql-client.The
<version>element specifies the project version as1.0-SNAPSHOT.The
<packaging>element specifies that the project is packaged as a Web Application Archive (WAR) file.
Code:
<groupId>com.oceanbase</groupId> <artifactId>tomcat-mysql-client</artifactId> <version>1.0-SNAPSHOT</version> <!-- Packaging method (default to jar) --> <packaging>war</packaging>You can configure the Maven version.
The <maven.compiler.source> and <maven.compiler.target> elements specify that both the source code and the object code for the compiler use Java 8.
Code:
<properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> </properties>Core dependencies
This dependency adds the JFinal framework, which lets you use its features.
Code:
<dependency> <groupId>com.jfinal</groupId> <artifactId>jfinal</artifactId> <version>5.0.6</version> </dependency>This dependency adds the Druid library, which is used to manage and optimize the retrieval and release of database connections.
Code:
<dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.2.8</version> </dependency>This dependency adds the Apache Commons DBCP2 library, which is used to manage and optimize the retrieval and release of database connections.
Code:
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-dbcp2</artifactId> <version>2.9.0</version> </dependency>You can specify the dependency with the organization
mysql, namemysql-connector-java, and version number5.1.40. This dependency lets you use client features provided by OceanBase, such as connections, queries, and transactions.Code:
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.40</version> </dependency>
application.properties file introduction
The application.properties file configures the information for connecting to the OceanBase database. This information includes the class name of the database driver, the connection URL, the username, the password, and connection pool settings. These configuration items are used to retrieve and manage database connections in the application for database operations.
The
db.app.pool.driverClassNameproperty specifies the database driver ascom.mysql.jdbc.Driver, which is used to establish a connection with the OceanBase database.The
db.app.pool.urlproperty specifies the URL for connecting to the database.The
db.app.pool.usernameproperty specifies the username for connecting to the database.The
db.app.pool.passwordproperty specifies the password for connecting to the database.The
db.app.pool.initialSizeproperty sets the initial size of the connection pool to3. This means that three database connections are created during initialization.The
db.app.pool.maxTotalproperty sets the maximum number of connections in the connection pool to10. This means that a maximum of 10 database connections can be created in the pool.The
db.app.pool.maxIdleproperty sets the maximum number of idle connections in the connection pool to20.The
db.app.pool.minIdleproperty sets the minimum number of idle connections in the connection pool to5.The
db.app.pool.maxWaitMillisproperty sets the timeout for a database connection to5000ms. This means that if a connection is not obtained within 5000 ms, a timeout exception is thrown.The
db.app.pool.validationQueryproperty specifies the SQL query statement for validating a database connection asselect 1. When a connection is retrieved from the pool, this query is executed to verify its validity.Code:
#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
Common configuration items for the built-in Tomcat DBCP connection pool:
The specific property (parameter) configuration depends on the project requirements and database characteristics. You can adjust and configure them as needed.
Property |
Default value |
Description |
username |
N/A |
Specifies the username for connecting to the database. |
password |
N/A |
Specifies the password for connecting to the database. |
url |
N/A |
Specifies the connection URL for the database. |
driverClassName |
N/A |
Specifies the standard Java class name of the database driver. |
connectionProperties |
N/A |
Specifies the connection properties sent to the JDBC driver when establishing a new connection. The format is |
defaultAutoCommit |
driver default |
Specifies the default autocommit state for connections created by the connection pool. If not set, the setAutoCommit method is not called. |
defaultReadOnly |
driver default |
Specifies the default read-only state for connections created by the connection pool. If not set, the setReadOnly method is not called. |
defaultTransactionIsolation |
driver default |
Specifies the default transaction isolation level for connections created by the connection pool. |
defaultCatalog |
N/A |
Specifies the default catalog for connections created by the connection pool. |
cacheState |
true |
Specifies whether to cache the readOnly and autoCommit settings of a connection. If true, the current readOnly and autoCommit settings are cached on the first read or write and on all subsequent writes. This eliminates the need for extra database queries for any further calls to the |
defaultQueryTimeout |
null |
Sets the query timeout for connection creation statements in the connection pool. If this Integer property is not NULL, its value determines the query timeout used for connection creation statements managed by the pool. If NULL, the driver's default value is used. |
enableAutoCommitOnReturn |
true |
Specifies whether to check and configure the autocommit of a returned connection when it is returned to the pool. |
rollbackOnReturn |
true |
Specifies whether to roll back non-read-only connections with autocommit disabled when they are returned to the pool. If true, the connection is rolled back when returned to the pool if autocommit is disabled and the connection is not read-only. |
initialSize |
0 |
Sets the initial number of connections created when the connection pool starts. |
maxTotal |
8 |
Sets the maximum number of active connections that can be allocated from the connection pool. |
maxIdle |
8 |
Sets the maximum number of idle connections to keep in the connection pool. Extra connections are not released. A negative value means no limit. |
minIdle |
0 |
Sets the minimum number of idle connections to keep in the connection pool. Extra connections are not created. A value of 0 means none are created. |
maxWaitMillis |
indefinitely |
Sets the maximum number of milliseconds that the pool will wait for a connection to be returned before throwing an exception when no connection is available. A value of -1 means to wait indefinitely. |
validationQuery |
N/A |
Specifies the SQL query statement for validating a connection. If specified, this must be a SQL SELECT statement that returns at least one row. If not specified, the connection is validated by calling the |
validationQueryTimeout |
no timeout |
Sets the timeout in seconds before a connection validation query fails. If set to a positive value, this value is passed to the driver's Statement via the setQueryTimeout method used to execute the validation query. |
testOnCreate |
false |
Specifies whether to validate an object after it is created. If the object fails validation, the borrow attempt that triggered its creation will fail. |
testOnBorrow |
true |
Indicates whether an object will be validated before it is borrowed from the connection pool. If the object fails validation, it is removed from the pool, and an attempt is made to borrow another one. |
testOnReturn |
false |
Indicates whether an object is validated before being returned to the pool. |
testWhileIdle |
false |
Indicates whether an object will be validated by the idle object evictor, if any. If an object fails validation, it is removed from the pool. |
timeBetweenEvictionRunsMillis |
-1 |
Sets the number of milliseconds to sleep between runs of the idle object evictor thread. If non-positive, no idle object evictor thread will be run. |
numTestsPerEvictionRun |
3 |
Sets the number of objects to examine during each run of the idle object evictor thread. |
minEvictableIdleTimeMillis |
1000 * 60 * 30 |
Sets the minimum time an object can be idle in the connection pool. |
softMinEvictableIdleTimeMillis |
-1 |
Sets the minimum time a connection can be idle in the pool, including the MinIdle constraint. |
maxConnLifetimeMillis |
-1 |
Sets the maximum lifetime of a connection in milliseconds. After this time, the connection will fail the next activation, passivation, or validation test. A value of 0 or less means the connection has an infinite lifetime. |
logExpiredConnections |
true |
Specifies whether to log connections that are closed by the pool because they have exceeded their maximum lifetime. A value of false disables logging of expired connections. |
connectionInitSqls |
null |
Specifies a collection of SQL statements to initialize a physical connection when it is first created. These statements are executed only when a connection is created by the configured connection factory. |
lifo |
true |
Specifies whether the borrowObject method returns the most recently used connection in the pool. A value of true means borrowObject returns the most recently used ( |
poolPreparedStatements |
false |
Specifies whether to enable the prepared statement pool. |
maxOpenPreparedStatements |
unlimited |
Sets the maximum number of open statements that can be allocated from the connection pool. A negative value means no limit. |
accessToUnderlyingConnectionAllowed |
false |
Specifies whether access to the underlying connection is allowed. |
removeAbandonedOnMaintenance |
false |
Specifies whether to remove abandoned connections during a connection pool maintenance cycle. If true, abandoned connections are removed during the maintenance cycle (at the end of eviction). This property has no effect unless maintenance is enabled by setting timeBetweenEvictionRunsMillis to a positive value. |
removeAbandonedOnBorrow |
false |
Specifies whether to remove abandoned connections when a connection is borrowed from the pool. If true, abandoned connections are removed each time a connection is borrowed from the pool, with the following additional requirements:
|
removeAbandonedTimeout |
300 |
Sets the timeout in seconds before an abandoned connection is removed. This parameter specifies the maximum idle time before a connection is considered abandoned and can be removed. |
logAbandoned |
false |
Specifies whether to log the stack trace of the application code for abandoned connections. Logging abandoned statements and connections adds overhead for each connection opening or new statement because a stack trace must be generated. |
abandonedUsageTracking |
false |
Specifies whether to log the stack trace of abandoned connections. If true, the connection pool records a stack trace every time a method is called on a pooled connection and retains the most recent stack trace to help debug abandoned connections. Setting this to true adds significant overhead. |
fastFailValidation |
false |
Specifies whether validation should fail fast for connections that throw a fatal SQLException. If true, a request to validate a disconnected connection fails immediately, without calling the driver's isValid method or attempting to execute a validation query. The SQL_STATE codes that are considered fatal error signals are by default:
To override this default set of disconnect codes, set the disconnectionSqlCodes property. |
disconnectionSqlCodes |
null |
Specifies a comma-separated list of SQL_STATE codes that are considered to signal a fatal disconnection error. The disconnectionSqlCodes property only takes effect when the fastFailValidation parameter is set to true. |
jmxName |
N/A |
Specifies the data source object that can be operated on and monitored. The data source is registered as a JMX MBean under the specified name. The name must conform to JMX object name syntax (see javadoc). |
web.xml code introduction
The web.xml file is used to configure filters for the web application.
The web.xml configuration file contains the following sections:
File declaration
This declares that the file is an XML file, the XML version is
1.0, and the character encoding isUTF-8.Code:
<?xml version="1.0" encoding="UTF-8"?>XML namespace and XML model version configuration
The
xmlns:xsiattribute specifies the XML namespace ashttp://www.w3.org/2001/XMLSchema-instance.The
xmlnsattribute specifies the XML namespace ashttp://java.sun.com/xml/ns/javaee.The
xsi:schemaLocationattribute specifies the XML namespace ashttp://java.sun.com/xml/ns/javaeeand the location of the XML's XSD file ashttp://java.sun.com/xml/ns/javaee/web-app_3_0.xsd.The
<id>and<version>elements specify the web application ID asWebApp_IDand the version as3.0.
Code:
<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">JFinal filter configuration
This section configures a filter named
jfinalfor using the JFinal framework in the web application. The filter class is specified ascom.jfinal.core.JFinalFilter. TheconfigClassinit-param specifies the location of the JFinal framework's configuration class ascom.oceanbase.testtomcat.config.UserConfig. The JFinal filter uses this configuration class to configure the behavior of the JFinal framework.Code:
<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>JFinal filter mapping configuration
This section applies the
jfinalfilter to all request paths, which means that the filter is applied to all requests in the application.Code:
<filter-mapping> <filter-name>jfinal</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
UserConfig.java file introduction
The UserConfig.java file is used to configure the application's routing, plugins, database connections, and other related information.
The code in the UserConfig.java file includes the following parts:
Imported classes and interfaces
This section declares the interfaces and classes that the file uses:
StatFilterclass: Used for collecting statistics on database access performance.JdbcConstantsclass: Used for defining constants for database types.WallFilterclass: Used for preventing SQL injection attacks.PropKitclass: Used for reading configuration files.ActiveRecordPluginclass: Used for operating on the database.Dbclass: Used for performing database operations.MysqlDialectclass: Used for specifying the database dialect.DruidPluginclass: Used for connecting to the database.Engineclass: Used for configuring the template engine.UserControllerclass: Used for handling user-related requests.Userclass: Used for passing and storing user data.
Code:
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;`UserConfig` class definition
By overriding the methods of the
JFinalConfigclass, you can configure constants, routes, plugins, database connections, and other settings.Define the
configConstantmethod.This method configures constants for the JFinal framework. It uses
PropKitto read configurations from the properties file.Code:
@Override public void configConstant(Constants constants) { PropKit.use("application.properties"); }Define the
configRoutemethod.This method configures route mappings. It uses the
routes.addmethod to map the"/hello"path to the default access page of theUserControllerclass.Code:
@Override public void configRoute(Routes routes) { routes.add("/hello", UserController.class, "/"); }Define the
configEnginemethod.This method configures the template engine.
Code:
@Override public void configEngine(Engine engine) { }Define the
configPluginmethod.This method configures the application's plugins. It calls the
initmethod to initialize the database connection and table schema. It createsDruidPluginandActiveRecordPluginplugins and adds them to thepluginslist. It also calls theaddMappingmethod ofactiveRecordPluginto map theTEST_USERdatabase table to theUserentity class.Code:
@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); }Define the
createDruidPluginmethod.This method creates the
DruidPluginplugin and configures related parameters, including the connection pool size, SQL firewall, and connection error handling.It calls the
getmethod ofPropKitto retrieve the database connection properties from the configuration file, including the URL, username, password, and driver class. It then creates aDruidPluginobject and initializes it with these properties.It calls the
addFiltermethod to add aStatFilterinstance to theDruidPluginfor database access performance statistics. It creates aWallFilterinstance, sets the database type to OceanBase using thesetDbTypemethod, and adds it to theDruidPluginto provide SQL firewall filtering.It calls the
setInitialSizemethod to set the initial size of the connection pool, thesetMaxPoolPreparedStatementPerConnectionSizemethod to set the maximum number of prepared statements per connection, thesetTimeBetweenConnectErrorMillismethod to set the time interval between connection errors, and thesetValidationQuerymethod to set the connection validation query. Finally, it returns the createdDruidPlugininstance.Code:
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; }
Define the
initmethod.This method initializes the database connection and creates the database table. It calls the
initDbConnectionmethod to initialize the database connection and returns anActiveRecordPlugininstance. Then, it executes an SQL statement to check if theTOMCAT_TESTuser table exists. If theTOMCAT_TESTtable exists, the method executes theDROP TABLE TOMCAT_TESTSQL statement to delete the table. It then executes aCREATE TABLEstatement to create a database table namedTOMCAT_TESTwithIDandUSERNAMEfields. Finally, it closes theActiveRecordPluginplugin's connection to release the database connection.Code:
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(); }Define the
initDbConnectionmethod.This method initializes the database connection. First, it calls the
createDruidPluginmethod to create aDruidPluginobject and assigns it to the variabledruidPlugin. This method is responsible for creating and configuringDruidPluginfor connection pool management. Second, it calls thecreateActiveRecordPluginmethod to create anActiveRecordPluginobject, passing theDruidPluginobject as a parameter. This method is responsible for creating and configuringActiveRecordPluginfor database operation management. Then, it calls thedruidPlugin.startmethod to start theDruidPluginand initialize the database connection pool. Finally, it calls theactiveRecordPlugin.startmethod to start theActiveRecordPlugin, which initializes the database operation settings based on the configuration.Code:
private ActiveRecordPlugin initDbConnection() { DruidPlugin druidPlugin = createDruidPlugin(); ActiveRecordPlugin activeRecordPlugin = createActiveRecordPlugin(druidPlugin); druidPlugin.start(); activeRecordPlugin.start(); return activeRecordPlugin; }Define the
ConfigInterceptorandConfigHandlermethods.These methods are used for global configuration during system initialization.
Code:
@Override public void configInterceptor(Interceptors interceptors) { } @Override public void configHandler(Handlers handlers) { }
UserController.java file introduction
The UserController.java file uses the getData method to insert data into and query data from the database. It returns the query results to the client in JSON format. It uses the Db class provided by the JFinal framework to perform database operations and the custom User class for data mapping. This implements the database operations and data return functions.
The code in the UserController.java file includes the following parts:
Imported classes and interfaces
This file declares the following interfaces and classes:
Controllerclass: Used for handling requests and responses.Dbclass: Used for performing database operations.Recordclass: Used for database operations, such as querying, inserting, updating, and deleting data.ArrayListclass: Used for creating an empty list.Userclass: Used for mapping database tables.Listinterface: Used for operating on query result collections.
Code:
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;`UserController` class definition
This provides a controller for the JFinal framework. The
getDatamethod is used to insert and query data in the database.Insert data: This section creates a
dataListlist that contains 10Recordobjects. EachRecordobject has differentIDandUSERNAMEfield values. Then, theDb.batchSavemethod is used to save the records from thedataListlist to theTOMCAT_TESTdatabase table in batches.Code:
for (int i = 0; i < 10; i++) { Record record = new Record().set("ID", i).set("USERNAME", "Tomcat connection pool test" + i); dataList.add(record); } Db.batchSave("TOMCAT_TEST", dataList, dataList.size());Query data: The
Db.findmethod executes an SQL query and stores the result in theresultListlist. An enhancedforloop traverses eachRecordobject in theresultListlist. ThegetStrmethod retrieves the value of the specified field from theRecordobject, and theSystem.out.printlnmethod prints the output.Code:
List<Record> resultList = Db.find("SELECT * FROM TOMCAT_TEST"); for (Record result : resultList) { System.out.println(result.getStr("USERNAME")); }Modify data: A loop iterates 10 times and executes an update statement in each iteration. The update statement uses the
Db.updatemethod to update records in theTOMCAT_TESTdatabase table based on a condition.Code:
for (int i = 0; i < 10; i++) { Db.update("UPDATE TOMCAT_TEST SET USERNAME = 'POOL connection pool test" + i + "' WHERE ID = " + i); }Query the modified data: This section queries the
TOMCAT_TESTdatabase table and saves the result inmodifiedList. It prints the message-----After modification-----. It then traversesmodifiedListand prints theUSERNAMEfield value for each record. TherenderJsonmethod renders theData retrieved successfullyresponse message into JSON format and returns it to the client.Code:
List<Record> modifiedList = Db.find("SELECT * FROM TOMCAT_TEST"); System.out.println("-----After modification-----"); for (Record modified : modifiedList) { System.out.println(modified.getStr("USERNAME")); } renderJson("Data retrieved successfully");
User.java file introduction
The User.java file is used to map database tables to Java objects.
The code in the User.java file includes the following parts:
You can reference the
Modelclass.The
Modelclass is used for mapping database tables and operating on data.`User` class definition
The
Userclass performs database operations through methods inherited from theModelclass.Code:
import com.jfinal.plugin.activerecord.Model; public class User extends Model<User> { public static final User dao = new User(); }
Complete code
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<>();
// Insert data
for (int i = 0; i < 10; i++) {
Record record = new Record().set("ID", i).set("USERNAME", "Tomcat connection pool test" + i);
dataList.add(record);
}
Db.batchSave("TOMCAT_TEST", dataList, dataList.size());
// Query data
List<Record> resultList = Db.find("SELECT * FROM TOMCAT_TEST");
for (Record result : resultList) {
System.out.println(result.getStr("USERNAME"));
}
// Modify data
for (int i = 0; i < 10; i++) {
Db.update("UPDATE TOMCAT_TEST SET USERNAME = 'POOL connection pool test" + i + "' WHERE ID = " + i);
}
// Query the modified data
List<Record> modifiedList = Db.find("SELECT * FROM TOMCAT_TEST");
System.out.println("-----After modification-----");
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();
}
References
For more information about OceanBase Connector/J, see OceanBase JDBC driver.