创建和配置连接
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 中查看您的密钥和证书,请参阅CERTIFICATES和CRYPTOGRAPHIC_KEYS。
-
生成您自己的自签名证书或使用现有 CA(证书颁发机构)证书作为根 CA。有关此过程的信息,请参考 Schannel 文档。
-
可选:生成或导入由根 CA 签署的中间 CA 证书。虽然中间 CA 证书不是必需的,但拥有中间 CA 证书对于测试和调试连接很有用。
-
为 Vertica 生成并签署(或导入)服务器证书。
-
使用 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;
-
或者,您可以使用 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';
-
使用签署服务器证书的同一 CA 为您的客户端生成和签署证书。
-
将 pem 证书链转换为单个 pkcs 12 文件。
-
将客户端密钥和链从 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
-
将 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()
方法检索此警告。有关遵守许可条款的详细信息,请参阅管理许可证。