All Products
Search
Document Center

ApsaraDB RDS:Use the Druid connection pool to connect to a database

Last Updated:Mar 30, 2026

If your Java application frequently opens short-lived connections to ApsaraDB RDS for MySQL, or hits the instance's maximum connection limit, Druid keeps a pool of reusable connections so your application doesn't pay the cost of a full TCP handshake on every request.

Prerequisites

Before you begin, ensure that you have:

  • Java Development Kit (JDK) 1.8 or later installed on your application server

  • The server's IP address added to the RDS instance's IP address whitelist. See Configure an IP address whitelist

If your application runs on an Elastic Compute Service (ECS) instance in the same region and virtual private cloud (VPC) as the RDS instance, no whitelist configuration is required.

Set up the project

The following steps use an Apache Maven project as an example. A Maven project stores Java source files under src/main/java and resource files under src/main/resources. The pom.xml file manages project dependencies.

Add Druid as a dependency

Add the following to the dependencies section in pom.xml. Use Druid 1.2.13 or later.

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

If you use `druid-spring-boot-starter`, exclude the transitive Druid dependency it brings in, then re-add Druid explicitly so the version is controlled:

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.2.19</version>
    <exclusions>
        <exclusion>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.2.19</version>
</dependency>

Connect to an RDS instance

Step 1: Create the connection pool configuration file

Create druid.properties in src/main/resources with the following content.

To find your RDS instance's endpoint and port, see View and manage instance endpoints and ports.
# Driver class — do not modify
driverClassName=com.mysql.jdbc.Driver

# Replace with your RDS endpoint, database name, username, and password
url=jdbc:mysql://rm-bp**************.mysql.rds.aliyuncs.com:3306/database
username=****
password=****

# Connection pool sizing
initialSize=20
minIdle=20
maxActive=100

# Connection lifecycle
phyTimeoutMillis=3600000

# Wait and timeout settings
maxWait=5000
connectTimeout=20000
socketTimeout=60000

# Idle connection validation
testWhileIdle=true
testOnBorrow=false
testOnReturn=false

# PreparedStatement cache
poolPreparedStatements=true
maxPoolPreparedStatementPerConnectionSize=100

Step 2: Initialize the connection pool and access the database

In src/main/java, create the DruidPoolDemo class. It loads druid.properties from the classpath, initializes the pool with DruidDataSourceFactory, and exposes a DataSource for subsequent database operations.

package com.aliyun.rdsfinops.collector.impl;

import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;

public class DruidPoolDemo {
    private static DataSource dataSource = null;
    String tableName = "sql_table_test";

    // Load druid.properties and initialize the connection pool at class load time
    static {
        Properties properties = new Properties();
        InputStream inputStream = DruidPoolDemo.class.getClassLoader()
                .getResourceAsStream("druid.properties");
        try {
            properties.load(inputStream);
            dataSource = DruidDataSourceFactory.createDataSource(properties);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /*
      Database operations are defined in the following methods:
        Create a table: public void createTable()
        Insert data:    public void insertData()
        Query data:     public void selectData()
        Delete data:    public void deleteData()
    */
}

Connection pool parameters

Run a full performance test against your production workload before changing parameter values on a live system.

Recommended parameters

These parameters have non-obvious defaults or incorrect default values that can silently degrade stability. Review and set them explicitly.

Parameter Default Recommended Description
initialSize 0 20–80 Connections established at startup. Set to 60–80% of your average concurrent connection count so the pool is ready to handle load immediately after the application starts.
minIdle 0 20–80 Minimum idle connections kept in reserve for burst traffic. Match this to initialSize or to the connection count the Java Virtual Machine (JVM) holds during low-load periods.
maxActive 8 100 Maximum active connections. Set this to the peak concurrent connection count your database can handle, with some headroom for traffic spikes.
phyTimeoutMillis -1 (no limit) 3,600,000–28,800,000 Maximum time (ms) a physical connection can stay alive before Druid forcibly closes and recreates it. The default value -1 specifies that connections are always available for reuse. Configure this parameter based on your business requirements. This parameter is used to prevent long-lived idle connections and save resources.
maxWait -1 (wait forever) 5,000 Maximum time (ms) to wait for a connection when the pool is exhausted. Never set this to -1 (threads block indefinitely) or 0 (requests fail immediately). In normal conditions, acquiring a connection takes 10–30 ms; 5,000 ms gives ample buffer.
connectTimeout 10,000 3,000 TCP connection timeout (ms) when establishing a new connection to the RDS server. Adjust based on network latency between your application and the instance.
socketTimeout 10,000 10,000–60,000 Time (ms) to wait for the database to respond after sending a SQL statement. Do not set this too low — if a query legitimately runs longer, the connection will be abandoned. Investigate slow queries before reducing this value.
testWhileIdle false true We recommend that you set this parameter to true. The connection pool periodically checks the status of idle connections.

Optional parameters

Parameter Default Recommended Description
poolPreparedStatements true true Caches PreparedStatement objects per connection. Reduces SQL compilation overhead when the same statements run repeatedly, and helps prevent SQL injection. Disable if your queries vary significantly or involve large result sets that would consume excessive JVM memory.
maxPoolPreparedStatementPerConnectionSize 10 100 Maximum cached PreparedStatement objects per connection. Increase if your application runs many distinct parameterized queries. Avoid very large values to prevent memory pressure.

Default parameters

These parameters work well at their defaults for most use cases. Modify them only if you have a specific requirement.

Parameter Default Description
failFast false When false, connection requests wait up to maxWait before failing. Set to true in error-sensitive, high-concurrency scenarios where you want immediate failure instead of waiting — typically used together with maxWaitThreadCount.
timeBetweenEvictionRunsMillis 60,000 Interval (ms) at which the pool checks idle connections against minEvictableIdleTimeMillis. The default is suitable for most workloads.

Database operations

Add these methods to the DruidPoolDemo class to perform common database operations on the sql_table_test table.

Create a table

String tableName = "sql_table_test";

public void createTable() throws SQLException {
    try (Connection connection = dataSource.getConnection()) {
        try (Statement statement = connection.createStatement()) {
            String sql = "create table if not exists " + tableName
                    + "(id VARCHAR(255), name VARCHAR(255), PRIMARY KEY (id))";
            int ret = statement.executeUpdate(sql);
            System.out.println(ret);
        }
    }
}

Insert data

public void insertData() {
    try (Connection connection = dataSource.getConnection()) {
        String sql = "insert into " + tableName + "(id,name) values(?,?)";
        try (PreparedStatement ps = connection.prepareStatement(sql)) {
            ps.setString(1, "aa");
            ps.setString(2, "bb");
            int ret = ps.executeUpdate();
            System.out.println(ret);
        }
    } catch (SQLException e) {
        e.printStackTrace();
    }
}

Query data

public void selectData() throws SQLException {
    try (Connection connection = dataSource.getConnection()) {
        String sql = "select * from " + tableName + " where id=?";
        try (PreparedStatement ps = connection.prepareStatement(sql)) {
            ps.setString(1, "aa");
            ResultSet rs = ps.executeQuery();
            while (rs.next()) {
                String id = rs.getString(1);
                String name = rs.getString(2);
                System.out.println("id=" + id);
                System.out.println("name=" + name);
            }
        }
    }
}

Delete data

public void deleteData() {
    try (Connection connection = dataSource.getConnection()) {
        String sql = "delete from " + tableName + " where id=?";
        try (PreparedStatement ps = connection.prepareStatement(sql)) {
            ps.setString(1, "aa");
            ps.executeUpdate();
        }
    } catch (SQLException e) {
        e.printStackTrace();
    }
}

What's next

References