创建和配置连接

Java 应用程序必须先创建连接才能与 Vertica 交互。使用 JDBC 连接到 Vertica 与连接到大多数其他数据库相似。

导入 SQL 包

创建连接之前,您必须导入 Java SQL 包。执行此操作的一种简单方法是使用通配符导入整个包:

import java.sql.*;

您可能还需要导入 Properties 类。在将连接实例化时,您可以使用此类的实例来传递连接属性,而不必将所有内容都编码到连接字符串中:

import java.util.Properties;

如果应用程序需要在 Java 5 JVM 中运行,它将使用符合 JDBC 3.0 的较旧版本驱动程序。此驱动程序要求使用 Class.forName() 方法手动加载 Vertica JDBC 驱动程序:

// Only required for old JDBC 3.0 driver
try {
    Class.forName("com.vertica.jdbc.Driver");
} catch (ClassNotFoundException e) {
    // Could not find the driver class. Likely an issue
    // with finding the .jar file.
    System.err.println("Could not find the JDBC driver class.");
    e.printStackTrace();
    return; // Exit. Cannot do anything further.
}

应用程序可能在 Java 6 或更高版本的 JVM 中运行。如果是这样,则 JVM 会自动加载兼容 Vertica JDBC 4.0 的驱动程序,而不要求调用 Class.forName。但是,发出此调用不会对进程产生负面影响。因此,如果您希望应用程序同时与 Java 5 和 Java 6(或更高版本)JVM 兼容,应用程序仍可以调用 Class.forName

打开连接

导入 SQL 包之后,您便已准备好通过调用 DriverManager.getConnection() 方法来创建连接。您至少必须向此方法提供以下信息:

  • 数据库群集中的节点的 IP 地址或主机名。

    您可以提供 IPv4 地址、IPv6 地址或主机名。

    在 IPv4/IPv6 混合网络中,DNS 服务器配置决定了哪个 IP 版本地址最先发送。可使用 PreferredAddressFamily 选项来强制连接使用 IPv4 或 IPv6。

  • 数据库的端口号

  • 数据库的名称

  • 数据库用户帐户的用户名

  • 用户的密码(如果该用户具有密码)

前三个参数始终作为连接字符串的一部分提供,连接字符串是一个 URL,可指示 JDBC 驱动程序从何处查找数据库。连接字符串的格式为:

"jdbc:vertica://VerticaHost:portNumber/databaseName"

此连接字符串的第一部分选择了 Vertica JDBC 驱动程序,后跟数据库的位置。

可以通过以下三种方法之一向 JDBC 驱动程序提供后两个参数(用户名和密码):

  • 作为连接字符串的一部分。将以 URL 参数的相似方式对这两个参数进行编码:

    "jdbc:vertica://VerticaHost:portNumber/databaseName?user=username&password=password"
    
  • 作为单独的参数传递到 DriverManager.getConnection()

    Connection conn = DriverManager.getConnection(
            "jdbc:vertica://VerticaHost:portNumber/databaseName",
            "username", "password");
    
  • Properties 对象中:

    Properties myProp = new Properties();
    myProp.put("user", "username");
    myProp.put("password", "password");
    Connection conn = DriverManager.getConnection(
        "jdbc:vertica://VerticaHost:portNumber/databaseName", myProp);
    

对以上三种方法来说,Properties 对象是最灵活的,因为使用此对象可以轻松地将其他连接属性传递到 getConnection() 方法。有关其他连接属性的详细信息,请参阅连接属性设置和获取连接属性值

如果建立与数据库的连接时出现任何问题,getConnection() 方法将在其子类之一上引发 SQLException。若要防止异常,请将方法包含在 try-catch 块中,如以下有关建立连接的完整示例所示。

import java.sql.*;
import java.util.Properties;

public class VerySimpleVerticaJDBCExample {
    public static void main(String[] args) {
        /*
         * If your client needs to run under a Java 5 JVM, It will use the older
         * JDBC 3.0-compliant driver, which requires you manually load the
         * driver using Class.forname
         */
        /*
         * try { Class.forName("com.vertica.jdbc.Driver"); } catch
         * (ClassNotFoundException e) { // Could not find the driver class.
         * Likely an issue // with finding the .jar file.
         * System.err.println("Could not find the JDBC driver class.");
         * e.printStackTrace(); return; // Bail out. We cannot do anything
         * further. }
         */
        Properties myProp = new Properties();
        myProp.put("user", "dbadmin");
        myProp.put("password", "vertica");
        myProp.put("loginTimeout", "35");
        myProp.put("KeystorePath", "c:/keystore/keystore.jks");
     myProp.put("KeystorePassword", "keypwd");
     myProp.put("TrustStorePath", "c:/truststore/localstore.jks");
     myProp.put("TrustStorePassword", "trustpwd");
        Connection conn;
        try {
            conn = DriverManager.getConnection(
                    "jdbc:vertica://V_vmart_node0001.example.com:5433/vmart", myProp);
            System.out.println("Connected!");
            conn.close();
        } catch (SQLTransientConnectionException connException) {
            // There was a potentially temporary network error
            // Could automatically retry a number of times here, but
            // instead just report error and exit.
            System.out.print("Network connection issue: ");
            System.out.print(connException.getMessage());
            System.out.println(" Try again later!");
            return;
        } catch (SQLInvalidAuthorizationSpecException authException) {
            // Either the username or password was wrong
            System.out.print("Could not log into database: ");
            System.out.print(authException.getMessage());
            System.out.println(" Check the login credentials and try again.");
            return;
        } catch (SQLException e) {
            // Catch-all for other exceptions
            e.printStackTrace();
        }
    }
}

使用密钥库和信任库创建连接

您可以使用密钥库和信任库创建与 JDBC 客户端驱动程序的安全连接。有关 Vertica 中的安全性的详细信息,请参阅安全性和身份验证

有关如何在 Vertica 中生成(或导入外部)证书的示例和说明,请参阅生成 TLS 证书和密钥

要在 Vertica 中查看您的密钥和证书,请参阅CERTIFICATESCRYPTOGRAPHIC_KEYS

  1. 生成您自己的自签名证书或使用现有 CA(证书颁发机构)证书作为根 CA。有关此过程的信息,请参考 Schannel 文档

  2. 可选:生成或导入由根 CA 签署的中间 CA 证书。虽然中间 CA 证书不是必需的,但拥有中间 CA 证书对于测试和调试连接很有用。

  3. 为 Vertica 生成并签署(或导入)服务器证书。

  4. 使用 ALTER TLS CONFIGURATION 将 Vertica 配置为使用客户端/服务器 TLS 进行新连接。有关详细信息,请参阅配置客户端-服务器 TLS

    对于服务器模式(无客户端证书验证):

    => ALTER TLS CONFIGURATION server TLSMODE 'ENABLE';
    => ALTER TLS CONFIGURATION server CERTIFICATE server_cert;
    

    对于相互模式(根据 TLSMODE 进行不同严格性的客户端证书验证):

    => ALTER TLS CONFIGURATION server TLSMODE 'TRY_VERIFY';
    => ALTER TLS CONFIGURATION server CERTIFICATE server_cert ADD CA CERTIFICATES ca_cert;
    
  5. 或者,您可以使用 CREATE AUTHENTICATION 禁用所有非 SSL 连接。

    => CREATE AUTHENTICATION no_tls METHOD 'reject' HOST NO TLS '0.0.0.0/0';
    => CREATE AUTHENTICATION no_tls METHOD 'reject' HOST NO TLS '::/128';
    
  6. 使用签署服务器证书的同一 CA 为您的客户端生成和签署证书。

  7. 将 pem 证书链转换为单个 pkcs 12 文件。

  8. 将客户端密钥和链从 pkcs12 文件导入到密钥库 JKS 文件中。有关使用 keytool 命令界面的信息,请参考 Java 文档

    $ keytool -importkeystore -srckeystore -alias my_alias -srcstoretype PKCS12 -srcstorepass my_password -noprompt -deststorepass my_password -destkeypass my_password -destkeystore /tmp/keystore.jks
    
  9. 将 CA 导入到信任库 JKS 文件中。

    $ keytool -import -file certs/intermediate_ca.pem -alias my_alias -trustcacerts -keystore /tmp/truststore.jks -storepass my_truststore_password -noprompt
    

用法注意事项

  • 断开用户会话的连接时,任何未提交的事务会自动回退。

  • 如果数据库不符合 Vertica 许可条款,则 Vertica 会在您建立与数据库的连接时发出 SQLWarning。您可以使用 Connection.getWarnings() 方法检索此警告。有关遵守许可条款的详细信息,请参阅管理许可证