Uso de JDBC para conectarse a un clúster
En GaussDB(DWS), puede usar un controlador JDBC para conectarse a una base de datos en Linux o Windows. El controlador puede conectarse a la base de datos a través de un ECS en la plataforma de Huawei Cloud o a través de Internet.
Cuando utilice el controlador JDBC para conectarse al clúster del almacén de datos, determine si desea habilitar la autenticación SSL. La autenticación SSL se utiliza para cifrar los datos de comunicación entre el cliente y el servidor. Protege los datos confidenciales transmitidos a través de Internet. Puede descargar un archivo de certificado autofirmado en la consola de gestión de GaussDB(DWS). Para que el certificado surta efecto, debe configurar el programa cliente usando la herramienta OpenSSL y la herramienta Java keytool.
El modo SSL ofrece mayor seguridad que el modo común. Se recomienda habilitar la conexión SSL cuando utilice JDBC para conectarse a un clúster de GaussDB(DWS).
Para obtener más información sobre cómo usar la API de JDBC, consulte la documentación oficial.
Prerrequisitos
- Ha instalado JDK 1.6 o posterior y configurado las variables de entorno.
- Ha descargado el controlador de JDBC. Para obtener más información, véase Descargar el controlador JDBC u ODBC.
GaussDB(DWS) también soporta el controlador JDBC de código abierto: PostgreSQL JDBC 9.3-1103 o posterior.
- Ha descargado el archivo de certificado SSL. Para obtener más información, consulte Descargar un certificado SSL.
Uso de un controlador JDBC para conectarse a una base de datos
El procedimiento para conectarse a la base de datos mediante un controlador JDBC en un entorno Linux es similar al de un entorno Windows. A continuación se describe el procedimiento de conexión en un entorno de Windows.
- Determine si desea utilizar el modo SSL para conectarse al clúster GaussDB(DWS).
- En caso afirmativo, habilite la conexión SSL haciendo referencia a Configuración de la conexión SSL. La conexión SSL está habilitada de forma predeterminada. Entonces vaya a 2.
- Si no es así, deshabilite la conexión SSL haciendo referencia a Configuración de la conexión SSL y vaya a 4.
- (Opcional) En Linux, utilice WinSCP para cargar el archivo de certificado SSL descargado en el entorno Linux.
- Configure el certificado para habilitar la conexión SSL.
- Descargue la herramienta OpenSSL para Windows. Dirección de descarga: https://slproweb.com/products/Win32OpenSSL.html. Actualmente, OpenSSL 3.0.0 no es compatible. Descargar Win64 OpenSSL v1.1.1w Light.
- Haga doble clic en el paquete de instalación Win64OpenSSL_Light-1_1_1w.exe e instálelo en la ruta predeterminada en la unidad C. Copie las DLL en el directorio OpenSSL, como se muestra en la siguiente figura. Mantenga la configuración predeterminada en los pasos restantes hasta que la instalación se realice correctamente.
- Instalar una variable de entorno. Haga clic en Start en la esquina inferior izquierda del PC local, haga clic con el botón derecho en This PC, seleccione More > Properties > View advanced system settings. Cambie a la ficha Advanced y haga clic en Environment Variables.
- En el área de System variables, haga doble clic en Path y haga clic en New en la ventana que se muestra. Agregue la ruta de OpenSSL bin a la última línea, por ejemplo, C:\Program Files\OpenSSL-Win64\bin, y haga clic en OK. Haga clic en OK y la variable se configura correctamente.
- Descomprima el paquete para obtener el archivo de certificado. La ruta de descompresión C:\ se utiliza como ejemplo.
Se recomienda almacenar el archivo de certificado en una ruta de la versión en inglés y puede especificar la ruta real al configurar el certificado. Si la ruta de acceso es incorrecta, se solicitará un mensaje indicando que el archivo no existe.
- Abra Command Prompt y cambie a la ruta de acceso C:\dws_ssl_cert\sslcert. Ejecute los siguientes comandos para importar la licencia root al almacén de confianza:
openssl x509 -in cacert.pem -out cacert.crt.der -outform der keytool -keystore mytruststore -alias cacert -import -file cacert.crt.der
- cacert.pem indica el certificado raíz obtenido después de la descompresión.
- cacert.crt.der indica el archivo intermedio generado. Puede almacenar el archivo en otra ruta y cambiar el nombre del archivo por el que desee.
- mytruststore indica el nombre del almacén de confianza generado y cacert indica el nombre de alias. Ambos parámetros pueden ser modificados.
Ingrese la contraseña del almacén de confianza como se le solicite y responda y.
- Convierte el formato de la clave privada del cliente.
openssl pkcs12 -export -out client.pkcs12 -in client.crt -inkey client.key
Introduzca la contraseña de la clave privada del cliente Gauss@MppDB. A continuación, introduzca y confirme la contraseña de clave privada autodefinida.
- Importe la clave privada al almacén de claves.
keytool -importkeystore -deststorepass Gauss@MppDB -destkeystore client.jks -srckeystore client.pkcs12 -srcstorepass Password -srcstoretype PKCS12 -alias 1
- En el comando anterior, Password es un ejemplo. Reemplácelo con la contraseña real.
- Si se muestra información similar a la siguiente y no se informa de ningún error, la importación se realiza correctamente. El archivo de clave de destino client.jks se generará en C:\dws_ssl_cert\sslcert.
- Descargue el paquete de controladores dws_8.1.x_jdbc_driver.zip y lo descomprima. Habrá dos paquetes JAR de unidad JDBC, gsjdbc4.jar y gsjdbc200.jar. Utilice cualquiera de ellos según sea necesario.
- Agregue el archivo JAR al proyecto de aplicación para que las aplicaciones puedan hacer referencia al archivo JAR.
Tome el proyecto Eclipse como ejemplo. Almacene el archivo JAR en el directorio del proyecto, por ejemplo, el directorio lib en el directorio del proyecto. En el proyecto Eclipse, haga clic con el botón derecho en el archivo JAR en el directorio lib y elija Build Path para hacer referencia al archivo JAR.
Figura 1 Referencia a un archivo JAR
Alternativamente, puede utilizar otro método. En el proyecto Maven, puede agregar directamente el controlador JDBC de GaussDB(DWS) como un elemento de dependencia al archivo POM. A continuación se muestra un ejemplo:
- 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 obtener más información acerca de la dirección del repositorio de imágenes configurada en setup.xml, consulte https://mvnrepository.com/.
- gsjdbc4.jar
- Cargue el controlador.
Los siguientes métodos están disponibles:
- Usar un código: Class.forName ("org.postgresql.Driver");
- Usar un parámetro durante el inicio de JVM: java -Djdbc.drivers=org.postgresql.Driver jdbctest
El paquete de controladores JDBC descargado en GaussDB(DWS) contiene gsjdbc4.jar y gsjdbc200.jar.
- gsjdbc4.jar: El paquete de controladores gsjdbc4.jar es compatible con PostgreSQL. Sus nombres de clase y estructuras de clase son los mismos que los del controlador PostgreSQL. Las aplicaciones que se ejecutan en PostgreSQL se pueden migrar directamente al sistema actual.
- gsjdbc200.jar: Si un proceso JVM necesita acceder a PostgreSQL y GaussDB(DWS) al mismo tiempo, se debe usar este paquete de controladores. En este paquete, el nombre de la clase principal es com.huawei.gauss200.jdbc.Driver (es decir, org.postgresql se reemplaza con com.huawei.gauss200.jdbc). El prefijo de URL de la conexión a la base de datos es jdbc:gaussdb. Otros parámetros son los mismos que los de gsjdbc4.jar.
- El paquete de controladores GaussDB(DWS) descargado desde el repositorio Maven es el mismo que el paquete de controladores gsjdbc4.
- Invoque al método DriverManager.getConnection() de JDBC para conectarse a bases de datos GaussDB(DWS).
La API de JDBC no proporciona la capacidad de reintento de conexión. Es necesario implementar el procesamiento de reintentos en el código de servicio.
Métodos de DriverManager.getConnection ():
- DriverManager.getConnection(String url);
- DriverManager.getConnection(String url, Properties info);
- DriverManager.getConnection(String url, String user, String password);
Tabla 1 Parámetros de conexión de base de datos Parámetro
Descripción
url
Especifica el descriptor de conexión de base de datos, que se puede ver en la consola de gestión. Para obtener más información, véase Obtención de la dirección de conexión de clúster.
El formato de URL es el siguiente:
- jdbc:postgresql:database
- jdbc:postgresql://host/database
- jdbc:postgresql://host:port/database
- jdbc:postgresql://host:port[,host:port][...]/database
NOTA:- Si se utiliza gsjdbc200.jar, cambie jdbc:postgresql a jdbc:gaussdb.
- database indica el nombre de la base de datos que se va a conectar.
- host indica el nombre o la dirección IP del servidor de base de datos. Si un ELB está enlazado al clúster, establezca host en la dirección IP del ELB.
- port indica el número de puerto del servidor de base de datos. De forma predeterminada, la base de datos que se ejecuta en el puerto 8000 del host local está conectada.
- Se pueden configurar múltiples direcciones IP y puertos. JDBC balancea la carga por acceso aleatorio y failover, e ignorará automáticamente las direcciones IP inalcanzables.
Separar varios pares de direcciones IP y puertos por comas (,). Ejemplo: jdbc:postgresql://10.10.0.13:8000,10.10.0.14:8000/database
- Si se utiliza JDBC para conectarse a un clúster, solo se pueden configurar los parámetros de conexión JDBC en una dirección de clúster. No se pueden agregar variables.
info
Especifica las propiedades de conexión de base de datos. Las propiedades comunes incluyen las siguientes:
- user: un tipo de cadena. Indica el usuario de la base de datos que crea la tarea de conexión.
- password: un tipo de cadena. Indica la contraseña del usuario de la base de datos.
- ssl: un tipo de boolean. Indica si se debe utilizar la conexión SSL.
- loggerLevel: tipo de cadena. Indica el volumen de datos de registro enviados al LogStream o LogWriter especificado en el DriverManager. Actualmente,OFF, DEBUG, and TRACE son compatibles. DEBUG indica que solo se imprimen registros de DEBUG o un nivel superior, generando poca información de registro. TRACE indica que se muestran los registros de los niveles de DEBUG y TRACE, generando información de registro detallada. El valor predeterminado es OFF, lo que indica que no se mostrará ningún registro.
- prepareThreshold: tipo entero. Indica el número de ejecuciones de PreparedStatement necesarias antes de que las solicitudes se conviertan en sentencias preparadas en los servidores. El valor predeterminado es de 5.
- batchMode: tipo de boolean. Indica si se debe conectar la base de datos en modo por lotes.
- fetchsize: tipo entero. Indica el tamaño de extracción predeterminado para las instrucciones en la conexión creada.
- ApplicationName: tipo de cadena. Indica un nombre de aplicación. El valor predeterminado es PostgreSQL JDBC Driver.
- allowReadOnly: tipo booleano. Indica si se debe habilitar el modo de solo lectura para la conexión. El valor predeterminado es false. Si el valor no se cambia a true, la ejecución de Connection.setReadOnly no tiene efecto.
- blobMode: tipo de cadena. Se utiliza para establecer el método de setBinaryStream para asignar valores a diferentes tipos de datos. El valor on indica que los valores se asignan al tipo de datos BLOB y off indica que los valores se asignan al tipo de datos BYTEA. El valor predeterminado es on.
- currentSchema: tipo de cadena. Especifica el esquema utilizado para conectarse a la base de datos.
- defaultQueryMetaData: Booleano. Especifica si se deben consultar los metadatos SQL de forma predeterminada. El valor predeterminado es false. Una vez habilitada esta función, se admiten operaciones de datos sin procesar. Sin embargo, no es compatible con operaciones create table as y select into en PrepareStatement.
- connectionExtraInfo: tipo de boolea. Este parámetro indica si el controlador JDBC informa de la ruta de despliegue del controlador y el propietario del proceso a la base de datos.
NOTA:
El valor puede ser true o false. El valor predeterminado es true. Si connectionExtraInfo se establece en true, el controlador JDBC informa de la ruta de despliegue del controlador y del propietario del proceso a la base de datos y muestra la información en el parámetro de connection_info. En este caso, puede consultar la información de PG_STAT_ACTIVITY o PGXC_STAT_ACTIVITY.
user
Especifica el usuario de la base de datos.
password
Especifica la contraseña del usuario de la base de datos.
A continuación se describe el código de muestra utilizado para cifrar la conexión mediante el 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; }
- Ejecutar sentencias SQL.
- Ejecute el siguiente comando para crear un objeto de sentencia:
1
Statement stmt = con.createStatement();
- Ejecute el siguiente comando para ejecutar el objeto de sentencia:
1
int rc = stmt.executeUpdate("CREATE TABLE tab1(id INTEGER, name VARCHAR(32));");
- Ejecute el siguiente comando para liberar el objeto de sentencia:
1
stmt.close();
- Ejecute el siguiente comando para crear un objeto de sentencia:
- Invoque a close () para cerrar la conexión.
Código de muestra
Este ejemplo de código ilustra cómo desarrollar aplicaciones basadas en la JDBC API proporcionada por GaussDB(DWS).
Antes de completar el siguiente ejemplo, debe crear un procedimiento almacenado. Para obtener más información, consulte Guía: Desarrollo basado en JDBC u 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 |
//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(); } } } |