Updated on 2024-07-16 GMT+08:00

Using JDBC to Connect to a Database

Java Database Connectivity (JDBC) is a Java API for running SQL statements. It provides unified access APIs for different relational databases, based on which applications process data. The GaussDB library supports JDBC 4.2 and requires JDK 1.8 for code compiling. It does not support JDBC-ODBC bridge.

Prerequisites

Java JDK 8 has been installed on the local PC.

JDBC Package

The package name is GaussDB-Kernel_Database version number_OS version number_64bit_Jdbc.tar.gz.

After the decompression, you will obtain the following JDBC packages in JAR format:

  • gaussdbjdbc.jar: The main class name is com.huawei.gaussdb.jdbc.Driver. The URL prefix of the database connection is jdbc:gaussdb. This driver package is recommended. The Java code examples in this section use the gaussdbjdbc.jar package by default.
  • gscejdbc.jar: The main class name is com.huawei.gaussdb.jdbc.Driver. The URL prefix of the database connection is jdbc:gaussdb. This driver package contains the dependent libraries related to encryption and decryption that need to be loaded to the encrypted database. You are advised to use this driver package in encrypted scenarios. Currently, only EulerOS is supported.
  • gaussdbjdbc-JRE7.jar: The main class name is com.huawei.gaussdb.jdbc.Driver. The URL prefix of the database connection is jdbc:gaussdb. The gaussdbjdbc-JRE7.jar package is used in the JDK 1.7 environment.
  • Before using the gscejdbc.jar driver package, you need to set the environment variable LD_LIBRARY_PATH. For details, see section "Setting Encrypted Equality Queries > Using JDBC to Operate an Encrypted Database" in Feature Guide.
  • In JDK 1.8, you are advised to use gaussdbjdbc.jar instead of gaussdbjdbc-JRE7.jar.
  • For details about other JDBC JAR packages, see "Application Development Guide" > "JDBC Compatibility Package" in Developer Guide.

Driver Class

Before establishing a database connection, load the com.huawei.gaussdb.jdbc.Driver database driver class.

  1. GaussDB is compatible with PostgreSQL in the use of JDBC. Therefore, when two JDBC drivers are used in the same process, class names may conflict.
  2. JDBC of this version does not support identity & access management suite (IAM) for authentication.
  3. The GaussDB JDBC driver has the following enhanced features:
    1. The SHA256 encryption mode is supported for login.
    2. The third-party log framework that implements the sf4j API can be connected.
    3. Distributed load balancing at the connection level is supported.
    4. DR failover is supported.

Environment Class

The JDK1.8 must be configured on the client. JDK supports multiple platforms such as Windows and Linux. The following uses Windows as an example to describe how to configure JDK:

  1. Enter java -version in the MS-DOS window (command prompt in Windows) to check the JDK version. Ensure that the JDK version is JDK1.8. If the JDK is not installed, download the installation package and install it.
  2. On the Windows desktop, right-click This PC and choose Properties from the shortcut menu.
  3. In the displayed System window, click Advanced system settings in the navigation tree on the left.
  4. In the System Properties dialog box, click Environment Variables in the lower right corner.
  5. In the System variables area of the Environment Variables dialog box, click New or Edit to configure system variables. For details about the variables, see Table 1.

    Table 1 Variables

    Variable

    Operation

    Variable Value

    JAVA_HOME

    • If the variable exists, click Edit.
    • If the variable does not exist, click New.

    Specifies the Java installation directory.

    Example: C:\Program Files\Java\jdk1.8.0_131.

    Path

    Click Edit.

    • If JAVA_HOME is configured, add %JAVA_HOME%\bin before the variable value.
    • If JAVA_HOME is not configured, add the full Java installation path before the variable value:

      C:\Program Files\Java\jdk1.8.0_131\bin

    CLASSPATH

    Click New.

    %JAVA_HOME%\lib;%JAVA_HOME%\lib\tools.jar

  6. Click OK and close the windows one by one.

Loading the Driver

Load the database driver before creating a database connection.

You can load the driver in the following ways:
  • Implicit loading at any position before a connection is created in the code: Class.forName("com.huawei.gaussdb.jdbc.Driver")
  • Parameter transfer during JVM startup: java -Djdbc.drivers=com.huawei.gaussdb.jdbc.Driver jdbctest

    jdbctest is the name of a test application.

Function Prototype

JDBC provides three database connection methods.
  • DriverManager.getConnection(String url)
  • DriverManager.getConnection(String url, Properties info)
  • DriverManager.getConnection(String url, String user, String password)

Parameters

Table 2 Database connection parameters

Parameter

Description

url

gaussdbjdbc.jar database connection descriptor.

If host is set to a server name or an IPv4 address, formats are as follows:

  • jdbc:gaussdb: (If the database name is left empty, the username is used.)
  • jdbc:gaussdb:database
  • jdbc:gaussdb://host/database
  • jdbc:gaussdb://host:port/database
  • jdbc:gaussdb://host:port/database?param1=value1&param2=value2
  • jdbc:gaussdb://host1:port1,host2:port2/database?param1=value1&param2=value2

If host is set to an IPv6 address, formats are as follows:

  • jdbc:gaussdb: (If the database name is left empty, the username is used.)
  • jdbc:gaussdb:database
  • jdbc:gaussdb://host/database or jdbc:gaussdb://[host]/database
  • jdbc:gaussdb://[host]:port/database
  • jdbc:gaussdb://[host]:port/database?param1=value1&param2=value2
  • jdbc:gaussdb://[host1]:port1,[host2]:port2/database?param1=value1&param2=value2
NOTE:
  • database indicates the name of the database to connect.
  • host indicates the name or IP address of the database server. Both IPv4 and IPv6 addresses are supported.

    For security purposes, the database CN forbids access from other nodes in the cluster without authentication. To access the CN from inside the cluster, deploy the JDBC program on the host where the CN is located and set host to 127.0.0.1. Otherwise, the error message "FATAL: Forbid remote connection with trust method!" may be displayed.

    It is recommended that the service system be deployed outside the cluster. If it is deployed inside, database performance may be affected.

    By default, the local host is used to connect to the server.

  • port indicates the port number of the database server.

    By default, the database on port 5432 of the local host is connected.

  • If host is set to an IPv6 address and the port number is specified in the URL, use square brackets ([]) to enclose the IP address. The format is [IP address]:Port number.
  • param indicates a database connection attribute.

    The parameter can be configured in the URL. The URL starts with a question mark (?), uses an equal sign (=) to assign a value to the parameter, and uses an ampersand (&) to separate parameters. You can also use the attributes of the info object for configuration. For details, see Examples.

  • value indicates the database connection attribute values.
  • The connectTimeout and socketTimeout parameters must be set for connection. If they are not set, the default value 0 is used, indicating that the connection will not time out. When the network between the DN and client is faulty, the client does not receive the ACK packet from the DN. In this case, the client starts the timeout retransmission mechanism to continuously retransmit packets. A timeout error is reported only when the timeout interval reaches the default value 600s. As a result, the RTO is high.
  • You are advised to ensure the validity of the URL when using the standard JDBC API to establish a connection. An invalid URL may cause an exception, and the exception contains the original URL character string, which may cause sensitive information leakage.

info

For details about common attributes of info, see "Application Development Guide" > "Development Based on JDBC" > "Connecting to a Database" in Developer Guide.

user

Database user.

password

Password of the database user.

After the uppercaseAttributeName parameter is enabled, if the database contains metadata with a mixture of uppercase and lowercase letters, only the metadata in lowercase letters can be queried and output in uppercase letters. Before using the metadata, ensure that the metadata is stored in lowercase letters to prevent data errors.

Examples

Example 1: Connect to a database.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// gaussdbjdbc.jar is used as an example.
// The following code encapsulates database connection operations into an API. The database can then be connected using an authorized username and a password.
public static Connection getConnect(String username, String passwd)
    {
        // Driver class.
        String driver = "com.huawei.gaussdb.jdbc.Driver";
        // Database connection descriptor.
        String sourceURL = "jdbc:gaussdb://$ip:$port/database";
        Connection conn = null;
        
        try
        {
            // Load the driver.
            Class.forName(driver);
        }
        catch( Exception e )
        {
            e.printStackTrace();
            return null;
        }
        
        try
        {
             // Create a connection.
            conn = DriverManager.getConnection(sourceURL, username, passwd);
            System.out.println("Connection succeed!");
        }
        catch(Exception e)
        {
            e.printStackTrace();
            return null;
        }
       
        return conn;
    }

Example 2: Use the Properties object as a parameter to create a connection.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
// The following code uses the Properties object as a parameter to establish a connection:
public static Connection getConnectUseProp(String username, String passwd)
    {
        // Driver class.
        String driver = "com.huawei.gaussdb.jdbc.Driver";
        // Database connection descriptor.
        String sourceURL = "jdbc:gaussdb://$ip:$port/database?autoBalance=true";
        Connection conn = null;
        Properties info = new Properties();
        
        try
        {
            // Load the driver.
            Class.forName(driver);
        }
        catch( Exception e )
        {
            e.printStackTrace();
            return null;
        }
        
        try
        {
             info.setProperty("user", username);
             info.setProperty("password", passwd);
             // Create a connection.
             conn = DriverManager.getConnection(sourceURL, info);
             System.out.println("Connection succeed!");
        }
        catch(Exception e)
        {
            e.printStackTrace();
            return null;
        }
        
        return conn;
    }

For details about common parameters, see "Application Development Guide" > "Development Based on JDBC" > "Common JDBC Parameters" in Developer Guide.

Example 3: Use the streaming read function.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
// There will be security risks if the username and password used for authentication are directly written into code. It is recommended that the username and password be stored in the configuration file or environment variables (the password must be stored in ciphertext and decrypted when being used) to ensure security.
// In this example, the username and password are stored in environment variables. Before running this example, set environment variables EXAMPLE_USERNAME_ENV and EXAMPLE_PASSWORD_ENV in the local environment (set the environment variable names based on the actual situation).
// Establish a connection.
public static Connection getConnection(String username, String passwd) {
    String driver = "com.huawei.gaussdb.jdbc.Driver";
    String sourceURL = "jdbc:gaussdb://$ip:$port/database?enableStreamingQuery=true";
    Connection conn = null;
    try {
        // Load the driver.
        Class.forName(driver);
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    }
    try {
        // Create a connection.
        conn = DriverManager.getConnection(sourceURL, username, passwd);
        System.out.println("Connection succeed!");
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    }
    return conn;
}

// Execute common SQL statements to create table t_user.
public static void CreateTable(Connection conn) {
    Statement stmt = null;
    try {
        stmt = conn.createStatement();

        // Execute common SQL statements.
        stmt.executeUpdate("DROP TABLE IF EXISTS t_user");
        stmt.executeUpdate("CREATE TABLE t_user(id int, name VARCHAR(20));");
        stmt.close();
    } catch (SQLException e) {
        if (stmt != null) {
            try {
                stmt.close();
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
        }
        e.printStackTrace();
    }
}

// Execute a prepared statement to insert data in batches.
public static void BatchInsertData(Connection conn) {
    PreparedStatement pst = null;

    try {
        // Generate a prepared statement.
        pst = conn.prepareStatement("INSERT INTO t_user VALUES (?,?)");
        for (int i = 0; i < 20; i++) {
            // Add parameters.
            pst.setInt(1, i + 1);
            pst.setString(2, "name " + (i + 1));
            pst.addBatch();
        }
        // Perform batch processing.
        pst.executeBatch();
        pst.close();
    } catch (SQLException e) {
        if (pst != null) {
            try {
                pst.close();
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
        }
        e.printStackTrace();
    }
}

// Enable streaming read and query the content in the t_user table.
public static void StreamingQuery(Connection conn) {
    PreparedStatement pst = null;
    ResultSet resultSet = null;

    try {
        // Query all values in the t_user table.
        pst = conn.prepareStatement("SELECT * FROM t_user");
        pst.setFetchSize(Integer.MIN_VALUE);// Functions the same as ((PgStatement)statement).enableStreamingResults();.
        resultSet = pst.executeQuery();
        while (resultSet.next()) {
            System.out.println(resultSet.getInt(1));
        }
    } catch (SQLException e) {
        throw new RuntimeException(e);
    } finally {
        if (resultSet != null) {
            try {
                resultSet.close();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }

        if (pst != null) {
            try {
                pst.close();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

public static void main(String[] args) throws Exception {
    String userName = System.getenv("EXAMPLE_USERNAME_ENV");
    String password = System.getenv("EXAMPLE_PASSWORD_ENV");
    Connection conn = getConnection(userName , password);

    CreateTable(conn);

    BatchInsertData(conn);

    StreamingQuery(conn);

    // Close the database connection.
    try {
        conn.close();
    } catch (SQLException e) {
        e.printStackTrace();
    }
}

When the streaming read function is used, you need to perform the resultSet.close() or statement.close() operation after the result set is used. Otherwise, the current connection is unavailable.