Uso do JDBC para conectar-se a um cluster
No GaussDB(DWS), você pode usar um driver JDBC para se conectar a um banco de dados no Linux ou no Windows. O driver pode se conectar ao banco de dados por meio de um ECS na plataforma da Huawei Cloud ou pela Internet.
Ao usar o driver JDBC para se conectar ao cluster de armazém de dados, determine se a autenticação SSL deve ser ativada. A autenticação SSL é usada para criptografar dados de comunicação entre o cliente e o servidor. Ela protege os dados sensíveis transmitidos pela Internet. Você pode baixar um arquivo de certificado autoassinado no console de gerenciamento do GaussDB(DWS). Para que o certificado entre em vigor, você deve configurar o programa cliente usando a ferramenta OpenSSL e a ferramenta de chave Java.
O modo SSL oferece maior segurança do que o modo comum. Recomenda-se ativar a conexão SSL ao usar JDBC para conectar-se a um cluster do GaussDB(DWS).
Para obter detalhes sobre como usar a API de JDBC, consulte a documentação oficial.
Pré-requisitos
- Você instalou o JDK 1.6 ou posterior e configurou variáveis de ambiente.
- Você fez o download do driver JDBC. Para mais detalhes, consulte Baixa do driver JDBC ou ODBC.
GaussDB(DWS) também suporta driver JDBC de código aberto: PostgreSQL JDBC 9.3-1103 ou mais recente.
- Você baixou o arquivo do certificado SSL. Para obter detalhes, consulte Baixa de um certificado SSL.
Usar um driver JDBC para conectar-se a um banco de dados
O procedimento para se conectar ao banco de dados usando um driver JDBC em um ambiente Linux é semelhante ao de um ambiente Windows. A seguir descreve o procedimento de conexão em um ambiente Windows.
- Determine se você deseja usar o modo SSL para se conectar ao cluster do GaussDB(DWS).
- Se sim, ative a conexão SSL referindo-se a Configurar uma conexão SSL. A conexão SSL está ativada por padrão. Então vá para 2.
- Se não, desative a conexão SSL consultando Configurar uma conexão SSL e vá para 4.
- (Opcional) No Linux, use WinSCP para carregar o arquivo de certificado SSL baixado para o ambiente Linux.
- Configure o certificado para habilitar a conexão SSL.
- Baixe a ferramenta OpenSSL para Windows. Endereço de download: https://slproweb.com/products/Win32OpenSSL.html. Atualmente, o OpenSSL 3.0.0 não é suportado. Baixae Win64 OpenSSL v1.1.1w Light.
- Clique duas vezes no pacote de instalação Win64OpenSSL_Light-1_1_1w.exe e instale-o no caminho padrão na unidade C. Copie as DLLs para o diretório OpenSSL, conforme mostrado na figura a seguir. Mantenha as configurações padrão nas etapas restantes até que a instalação seja bem-sucedida.
- Instale uma variável de ambiente. Clique em Start no canto inferior esquerdo do PC local, clique com o botão direito do mouse em This PC, escolha More > Properties > View advanced system settings. Alterne para a guia Advanced e clique em Environment Variables.
- Na área System variables, clique duas vezes em Path e clique em New na janela exibida. Adicione o caminho bin de OpenSSL à última linha, por exemplo, C:\Program Files\OpenSSL-Win64\bin, e clique em OK. Clique em OK novamente e a variável será configurada com sucesso.
- Descompacte o pacote para obter o arquivo de certificado. O caminho de descompressão C:\ é usado como exemplo.
É aconselhável armazenar o arquivo de certificado em um caminho da versão em inglês e especificar o caminho real ao configurar o certificado. Se o caminho estiver incorreto, uma mensagem informando que o arquivo não existe será solicitada.
- Abra Command Prompt e alterne para o caminho C:\dws_ssl_cert\sslcert. Execute os seguintes comandos para importar a licença raiz para o repositório confiável:
openssl x509 -in cacert.pem -out cacert.crt.der -outform der keytool -keystore mytruststore -alias cacert -import -file cacert.crt.der
- cacert.pem indica o certificado raiz obtido após a descompressão.
- cacert.crt.der indica o arquivo intermediário gerado. Você pode armazenar o arquivo em outro caminho e alterar o nome do arquivo para o desejado.
- mytruststore indica o nome do repositório confiável gerado e cacert indica o nome do alias. Ambos os parâmetros podem ser modificados.
Digite a senha do repositório confiável conforme solicitado e responda y.
- Converta o formato da chave privada do cliente.
openssl pkcs12 -export -out client.pkcs12 -in client.crt -inkey client.key
Digite a senha da chave privada do cliente Gauss@MppDB. Em seguida, insira e confirme a senha da chave privada autodefinida.
- Importe a chave privada para o repositório de chaves.
keytool -importkeystore -deststorepass Gauss@MppDB -destkeystore client.jks -srckeystore client.pkcs12 -srcstorepass Password -srcstoretype PKCS12 -alias 1
- No comando anterior, Password é um exemplo. Substitua-a pela senha atual.
- Se informações semelhantes às seguintes forem exibidas e nenhum erro for relatado, a importação será bem-sucedida. O arquivo de chave de destino client.jks será gerado em C:\dws_ssl_cert\sslcert.
- Baixe o pacote de driver dws_8.1.x_jdbc_driver.zip e descompactá-lo. Haverá dois pacotes JAR de drive JDBC, gsjdbc4.jar e gsjdbc200.jar. Use qualquer um deles conforme necessário.
- Adicione o arquivo JAR ao projeto da aplicação para que as aplicações possam fazer referência ao arquivo JAR.
Tome como exemplo o projeto Eclipse. Armazene o arquivo JAR no diretório do projeto, por exemplo, o diretório lib no diretório do projeto. No projeto Eclipse, clique com o botão direito do mouse no arquivo JAR no diretório lib e escolha Build Path para fazer referência ao arquivo JAR.
Figura 1 Fazer referência a um arquivo JAR
Alternativamente, você pode usar outro método. No projeto Maven, você pode adicionar diretamente o driver JDBC do GaussDB(DWS) como um item de dependência ao arquivo POM. O seguinte mostra um exemplo:
- gsjdbc4.jar
1 2 3 4 5
<dependency> <groupId>com.huaweicloud.dws</groupId> <artifactId>huaweicloud-dws-jdbc</artifactId> <version>8.1.0</version> </dependency>
- gsjdbc200.jar
<dependency> <groupId>com.huaweicloud.dws</groupId> <artifactId>huaweicloud-dws-jdbc</artifactId> <version>8.1.1.1-200</version> </dependency>
Para obter detalhes sobre o endereço do repositório de imagens configurado em setting.xml, consulte https://mvnrepository.com/.
- gsjdbc4.jar
- Carregue o driver.
Os seguintes métodos estão disponíveis:
- Usar um código: Class.forName("org.postgresql.Driver");
- Usar um parâmetro durante a inicialização da JVM: java -Djdbc.drivers=org.postgresql.Driver jdbctest
O pacote de driver JDBC baixado no GaussDB(DWS) contém gsjdbc4.jar e gsjdbc200.jar.
- gsjdbc4.jar: o pacote de driver gsjdbc4.jar é compatível com o PostgreSQL. Seus nomes e estruturas de classes são os mesmos do driver de PostgreSQL. Aplicações executadas no PostgreSQL podem ser migradas diretamente para o sistema atual.
- gsjdbc200.jar: se um processo da JVM precisar acessar o PostgreSQL e o GaussDB(DWS) ao mesmo tempo, esse pacote de driver deve ser usado. Neste pacote, o nome da classe principal é com.huawei.gauss200.jdbc.Driver (ou seja, org.postgresql é substituído por com.huawei.gauss200.jdbc). O prefixo de URL da conexão do banco de dados é jdbc:gaussdb. Outros parâmetros são os mesmos do gsjdbc4.jar.
- O pacote de driver do GaussDB(DWS) baixado do repositório Maven é o mesmo que o pacote de driver gsjdbc4.
- Chame o DriverManager.getConnection() para conectar-se ao banco de dados do GaussDB(DWS).
A API do JDBC não fornece o recurso de repetição de conexão. Você precisa implementar o processamento de nova tentativa no código de serviço.
Métodos DriverManager.getConnection():
- DriverManager.getConnection(String url);
- DriverManager.getConnection(String url, Properties info);
- DriverManager.getConnection(String url, String user, String password);
Tabela 1 Parâmetros de conexão do banco de dados Parâmetro
Descrição
url
Especifica o descritor de conexão de banco de dados, que pode ser exibido no console de gerenciamento. Para mais detalhes, consulte Obtenção do endereço de conexão do cluster.
O formato do URL é o seguinte:
- jdbc:postgresql:database
- jdbc:postgresql://host/database
- jdbc:postgresql://host:port/database
- jdbc:postgresql://host:port[,host:port][...]/database
NOTA:- Se gsjdbc200.jar for usado, altere jdbc:postgresql para jdbc:gaussdb.
- database indica o nome do banco de dados a ser conectado.
- host indica o nome ou endereço IP do servidor de banco de dados. Se um ELB estiver vinculado ao cluster, defina host como o endereço IP do ELB.
- port indica o número da porta do servidor de banco de dados. Por padrão, o banco de dados executado na porta 8000 do host local é conectado.
- Vários endereços IP e portas podem ser configurados. O JDBC equilibra a carga por acesso aleatório e failover e ignorará automaticamente endereços IP inacessíveis.
Separe vários pares de endereços IP e portas por vírgulas (,). Exemplo: jdbc:postgresql://10.10.0.13:8000,10.10.0.14:8000/database
- Se o JDBC for usado para se conectar a um cluster, somente os parâmetros de conexão de JDBC poderão ser configurados em um endereço de cluster. Variáveis não podem ser adicionadas.
Informações
Especifica as propriedades de conexão do banco de dados. As propriedades comuns incluem o seguinte:
- user: um tipo de cadeia. Indica o usuário do banco de dados que cria a tarefa de conexão.
- password: um tipo de cadeia. Indica a senha do usuário do banco de dados.
- ssl: um tipo boolean. Indica se a conexão SSL deve ser usada.
- loggerLevel: tipo de cadeia. Indica o volume de dados de log enviados para o LogStream ou LogWriter especificado no DriverManager. Atualmente, OFF, DEBUG e TRACE são suportados. DEBUG indica que somente logs de DEBUG ou de um nível superior são impressos, gerando pouca informação de log. TRACE indica que os logs dos níveis DEBUG e TRACE são exibidos, gerando informações de log detalhadas. O valor padrão é OFF, indicando que nenhum registro será exibido.
- prepareThreshold: tipo de inteiro. Indica o número de execuções de PreparedStatement necessárias antes que as solicitações sejam convertidas em instruções preparadas nos servidores. O valor padrão é 5.
- batchMode: tipo boolean. Indica se o banco de dados deve ser conectado no modo em lotes.
- fetchsize: tipo de inteiro. Ele indica o tamanho de busca padrão para instruções na conexão criada.
- ApplicationName: tipo de cadeia. Indica um nome de aplicação. O valor padrão é PostgreSQL JDBC Driver.
- allowReadOnly: tipo boolean. Indica se o modo somente leitura deve ser ativado para conexão. O valor padrão é false. Se o valor não for alterado para true, a execução de connection.setReadOnly não terá efeito.
- blobMode: tipo de cadeia. Ele é usado para definir o método setBinaryStream para atribuir valores a diferentes tipos de dados. O valor on indica que os valores são atribuídos ao tipo de dados BLOB e off indica que os valores são atribuídos ao tipo de dados BYTEA. O valor padrão é on.
- currentSchema: tipo de cadeia. Especifica o esquema usado para conexão com o banco de dados.
- defaultQueryMetaData: boolean. Ele especifica se deve consultar metadados de SQL por padrão. O valor padrão é false. Depois que essa função é ativada, as operações de dados brutos são suportadas. No entanto, é incompatível com as operações create table as e select into no PrepareStatement.
- connectionExtraInfo: tipo boolean. Este parâmetro indica se o driver JDBC relata o caminho de implementação do driver e o proprietário do processo ao banco de dados.
NOTA:
O valor pode ser true ou false. O valor padrão é true. Se connectionExtraInfo for definido como true, o driver JDBC reportará o caminho de disponibilização do driver e o proprietário do processo ao banco de dados e exibirá as informações no parâmetro connection_info. Nesse caso, você pode consultar as informações de PG_STAT_ACTIVITY ou PGXC_STAT_ACTIVITY.
user
Especifica o usuário do banco de dados.
password
Especifica a senha do usuário do banco de dados.
A seguir, descrevemos o código de exemplo usado para criptografar a conexão usando o certificado SSL: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
// The following code obtains the database SSL connection operation and encapsulates the operation as an API. public static Connection GetConnection(String username, String passwd) { // Define the driver class. String driver = "org.postgresql.Driver"; //Set keyStore. System.setProperty("javax.net.ssl.trustStore", "mytruststore"); System.setProperty("javax.net.ssl.keyStore", "client.jks"); System.setProperty("javax.net.ssl.trustStorePassword", "password"); System.setProperty("javax.net.ssl.keyStorePassword", "password"); Properties props = new Properties(); props.setProperty("user", username); props.setProperty("password", passwd); props.setProperty("ssl", "true"); String url = "jdbc:postgresql://" + "10.10.0.13" + ':' + "8000" + '/' + "postgresgaussdb"; Connection conn = null; try { // Load the driver. Class.forName(driver); } catch (Exception e) { e.printStackTrace(); return null; } try { // Create a connection. conn = DriverManager.getConnection(url, props); System.out.println("Connection succeed!"); } catch (SQLException throwables) { throwables.printStackTrace(); return null; } return conn; }
- Executar instruções SQL.
- Execute o seguinte comando para criar um objeto de instrução:
1
Statement stmt = con.createStatement();
- Execute o seguinte comando para executar o objeto de instrução:
1
int rc = stmt.executeUpdate("CREATE TABLE tab1(id INTEGER, name VARCHAR(32));");
- Execute o seguinte comando para liberar o objeto de instrução:
1
stmt.close();
- Execute o seguinte comando para criar um objeto de instrução:
- Chame close() para encerrar a conexão.
Código de exemplo
Este exemplo de código ilustra como desenvolver aplicações baseadas na API de JDBC fornecida pelo GaussDB(DWS).
Antes de concluir o exemplo a seguir, você precisa criar um procedimento armazenado. Para obter detalhes, consulte Guia: desenvolvimento baseado em JDBC ou ODBC.
1 2 3 4 5 6 7 8 9 10 11 |
create or replace procedure testproc ( psv_in1 in integer, psv_in2 in integer, psv_inout in out integer ) as begin psv_inout := psv_in1 + psv_in2 + psv_inout; end; / |
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 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 |
//DBtest.java //gsjdbc4.jar is used as an example. If gsjdbc200.jar is used, replace the driver class name org.postgresql with com.huawei.gauss200.jdbc and replace the URL prefix jdbc:postgresql with jdbc:gaussdb. //Demonstrate the main steps for JDBC development, including creating databases, creating tables, and inserting data. import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.SQLException; import java.sql.Statement; import java.sql.CallableStatement; import java.sql.Types; public class DBTest { //Create a database connection. Replace the following IP address and database with the actual database connection address and database name. public static Connection GetConnection(String username, String passwd) { String driver = "org.postgresql.Driver"; String sourceURL = "jdbc:postgresql://10.10.0.13:8000/database"; Connection conn = null; try { // Load the database driver. Class.forName(driver).newInstance(); } catch (Exception e) { e.printStackTrace(); return null; } try { //Create a database connection. conn = DriverManager.getConnection(sourceURL, username, passwd); System.out.println("Connection succeed!"); } catch (Exception e) { e.printStackTrace(); return null; } return conn; }; //Run the common SQL statements to create table customer_t1. public static void CreateTable(Connection conn) { Statement stmt = null; try { stmt = conn.createStatement(); //Run the common SQL statements. int rc = stmt .executeUpdate("CREATE TABLE customer_t1(c_customer_sk INTEGER, c_customer_name VARCHAR(32));"); stmt.close(); } catch (SQLException e) { if (stmt != null) { try { stmt.close(); } catch (SQLException e1) { e1.printStackTrace(); } } e.printStackTrace(); } } //Run the prepared statements and insert data in batches. public static void BatchInsertData(Connection conn) { PreparedStatement pst = null; try { //Generate the prepared statements. pst = conn.prepareStatement("INSERT INTO customer_t1 VALUES (?,?)"); for (int i = 0; i < 3; i++) { //Add parameters. pst.setInt(1, i); pst.setString(2, "data " + i); pst.addBatch(); } //Execute batch processing. pst.executeBatch(); pst.close(); } catch (SQLException e) { if (pst != null) { try { pst.close(); } catch (SQLException e1) { e1.printStackTrace(); } } e.printStackTrace(); } } //Run the precompiled statement to update the data. public static void ExecPreparedSQL(Connection conn) { PreparedStatement pstmt = null; try { pstmt = conn .prepareStatement("UPDATE customer_t1 SET c_customer_name = ? WHERE c_customer_sk = 1"); pstmt.setString(1, "new Data"); int rowcount = pstmt.executeUpdate(); pstmt.close(); } catch (SQLException e) { if (pstmt != null) { try { pstmt.close(); } catch (SQLException e1) { e1.printStackTrace(); } } e.printStackTrace(); } } //Execute the storage procedure. public static void ExecCallableSQL(Connection conn) { CallableStatement cstmt = null; try { cstmt=conn.prepareCall("{? = CALL TESTPROC(?,?,?)}"); cstmt.setInt(2, 50); cstmt.setInt(1, 20); cstmt.setInt(3, 90); cstmt.registerOutParameter(4, Types.INTEGER); //Register a parameter of the out type. Its value is an integer. cstmt.execute(); int out = cstmt.getInt(4); //Obtain the out parameter. System.out.println("The CallableStatment TESTPROC returns:"+out); cstmt.close(); } catch (SQLException e) { if (cstmt != null) { try { cstmt.close(); } catch (SQLException e1) { e1.printStackTrace(); } } e.printStackTrace(); } } /** * Main program, which gradually invokes each static method. * @param args */ public static void main(String[] args) { //Create a database connection. Replace User and Password with the actual database user name and password. Connection conn = GetConnection("User", "Password"); //Create a table. CreateTable(conn); //Insert data in batches. BatchInsertData(conn); //Run the precompiled statement to update the data. ExecPreparedSQL(conn); //Execute the storage procedure. ExecCallableSQL(conn); //Close the database connection. try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } |