开发规范
如果用户在APP的开发中,使用了连接池机制,那么需要遵循如下规范,否则,连接池里面的连接就是有状态的,会对用户后续使用连接池进行操作的正确性带来影响。
- 如果在连接中设置了GUC参数,那么在将连接归还连接池之前,必须使用“SET SESSION AUTHORIZATION DEFAULT;RESET ALL;”将连接的状态清空。
- 如果使用了临时表,那么在将连接归还连接池之前,必须将临时表删除。
下载JDBC或ODBC驱动
JDBC或ODBC驱动程序用于连接DWS 集群,用户可以在管理控制台下载DWS 提供的JDBC或ODBC驱动程序,也可以使用开源的JDBC或ODBC驱动程序。
支持的开源JDBC或ODBC驱动程序
DWS 也支持开源的JDBC驱动程序:PostgreSQL JDBC驱动程序9.3-1103或更高版本。
DWS 也支持开源的ODBC驱动程序:PostgreSQL ODBC 09.01.0200或更高版本。
下载JDBC或ODBC驱动程序
- 登录DWS 管理控制台。
- 在左侧导航栏中,单击“连接管理”。
- 在“下载驱动程序”区域,选择一个驱动下载。
JDBC驱动
选择“DWS JDBC Driver”,然后单击“下载”可以下载与现有集群版本匹配的JDBC驱动。驱动包名为“dws_8.1.x_jdbc_driver.zip”,解压后有两个JDBC的驱动jar包,分别为“gsjdbc4.jar”和“gsjdbc200.jar”。
如果同时拥有不同版本的集群,单击“下载”时会下载与集群最低版本相对应的JDBC驱动。如果当前没有集群,单击“下载”时将下载到低版本的JDBC驱动。DWS 集群可向下兼容低版本的JDBC驱动。
单击“历史版本”可根据集群版本下载相应版本的JDBC驱动,建议按集群版本进行下载。
JDBC驱动包支持在所有平台所有版本中使用,且依赖JDK 1.6及以上版本。
ODBC驱动
选择相应的版本,然后单击“下载”可以下载与集群版本匹配的ODBC驱动。如果同时拥有不同版本的集群,单击“下载”时会下载与集群最低版本相对应的ODBC驱动。如果当前没有集群,单击“下载”时将下载到低版本的ODBC驱动。DWS 集群可向下兼容低版本的ODBC驱动。
单击“历史版本”可根据操作系统和集群版本下载相应版本的ODBC驱动,建议按集群版本进行下载。
ODBC驱动支持在以下系统中使用:
- “Microsoft Windows”驱动支持在以下系统中使用:
Windows 7及以上。
Windows Server 2008及以上。
- Euler Kunpeng_64”驱动支持在以下系统中使用:
EulerOS 2.8。
- “Redhat_Kunpeng_64”驱动支持在以下系统中使用:
CentOS 7.5,7.6。
NeoKylin 7.6。
- ”Redhat x86_64”驱动支持在以下系统中使用:
RHEL 6.4~7.6。
CentOS 6.4~7.4。
EulerOS 2.3。
- ”SUSE x86_64”驱动支持在以下系统中使用:
SLES 11.1~11.4。
SLES 12.0~12.3。
说明Windows驱动只支持32位版本,可以在32或64位操作系统使用,但是应用程序必须为32位。
使用JDBC连接数据库
DWS 支持在Linux或Windows环境下使用JDBC应用程序连接数据库。应用程序可以在云平台环境的弹性云主机中,或者互联网环境连接数据库。
用户通过JDBC连接DWS 集群时,可以选择是否采用SSL认证方式。SSL认证用于加密客户端和服务器之间的通讯数据,为敏感数据在Internet上的传输提供了一种安全保障手段。DWS 管理控制台提供了自签的证书供用户下载。使用该证书,用户需要配置客户端程序,使证书可用,此过程依赖于openssl工具以及java自带的keytool工具。
说明SSL模式安全性高于普通模式,建议在使用JDBC连接DWS 集群时采用SSL模式。
JDBC接口的使用方法,请自行查阅官方文档。
前提条件
- 已安装JDK 1.6或以上版本,并配置环境变量。
- 已下载JDBC驱动,请参见上方:下载JDBC或ODBC驱动。
DWS 也支持开源的JDBC驱动程序:PostgreSQL JDBC驱动程序9.3-1103或更高版本。
- 已下载SSL证书文件,请参见使用SSL进行安全的TCP/IP连接-“在gsql客户端配置SSL认证相关的数字证书参数”章节中的“下载SSL证书”。
使用JDBC连接数据库
在Linux和Windows环境下操作方法相同,以下步骤以Windows环境为例。
- 是否采用SSL方式连接DWS 集群。
是,参见使用SSL进行安全的TCP/IP连接-设置SSL连接章节中的开启SSL连接,默认为开启。执行步骤2。
否,参见使用SSL进行安全的TCP/IP连接-设置SSL连接章节中的关闭SSL连接,执行步骤4。
- (可选)如果使用Linux环境,使用WinScp工具将SSL证书上传到Linux环境上。
- 配置证书以使用SSL加密连接。
a.下载windows版本的OpenSSL工具。当前不支持OpenSSL 3.0.0,请选择下载“Win64 OpenSSL v1.1.1L Light”版本。
b.双击安装包“Win64OpenSSL_Light-1_1_1L.exe”安装到C盘默认路径即可,选择复制DLLs文件到OpenSSL目录下,如下图,剩余步骤默认单击下一步直到安装成功。
c.安装环境变量。单击本地PC左下角“开始”,右击“此电脑”,选择“更多 > 属性 > 高级系统设置”,切换到“高级”,单击“环境变量”。
d.在下方“系统变量”,双击“Path”变量,单击“新建”,在最后一行增加Openssl的bin路径,例如“C:\Program Files\OpenSSL-Win64\bin”,单击“确定”,再次单击“确定”,配置变量成功。
e.解压压缩包得到证书文件。假设解压路径为“C:\”。
证书文件建议保存在英文路径,配置证书时需要根据实际情况指定路径,否则可能提示文件不存在。
f.打开“命令提示符”程序,切换到“C:\dws_ssl_cert\sslcert”路径下,执行以下两条命令,转化根证书并导入到trustStore中。
openssl x509 -in cacert.pem -out cacert.crt.der -outform der
keytool -keystore mytruststore -alias cacert -import -file cacert.crt.der
−“cacert.pem”为解压后获取的根证书。
−“cacert.crt.der”为生成的中间文件。根据实际情况,可以填写保存到其他路径,也可以自定义文件名称。
−“mytruststore”为生成的可信库名称,“cacert”为别名用户,二者可以根据需要进行修改。
请用户根据提示信息输入自定义的可信库密码并确认密码,然后输入“y”确认信任证书。
g.执行以下命令转化客户端私钥。
openssl pkcs12 -export -out client.pkcs12 -in client.crt -inkey client.key
需要输入客户端私钥的密码“Gauss@MppDB”,然后输入并确认用户自定义的私钥密码。
h.执行以下命令,将私钥导入到keyStore中。
keytool -importkeystore -deststorepass Gauss@MppDB -destkeystore client.jks -
srckeystore client.pkcs12 -srcstorepass password -srcstoretype PKCS12 -alias 1
说明
命令中“ *password* ”为示例自定义密码,具体请根据用户实际输入密码为准。
回显如下类似信息且没有报错,则表示导入成功。此时“C:\dws_ssl_cert\sslcert”下会生成目标密钥文件:client.jks。
- 下载包名为dws_8.1.x_jdbc_driver.zip的驱动包,解压后有两个JDBC的驱动jar包“gsjdbc4.jar”和“gsjdbc200.jar”,用户可根据需求选择。
- 在应用程序的工程中,设置引用Jar包。
以Eclipse工程为例,先将jar包存放在工程目录下,例如将jar包放在工程目录的lib目录下,然后在Eclipse工程中,右键单击lib目录下的该jar包,再选择菜单“Build Path”,即可引用此jar包。
详见下图:引用jar包
- 加载驱动。
支持以下两种方法加载:
- 在代码中隐含装载:Class.forName("org.postgresql.Driver");
- 在JVM启动时参数传递:java -Djdbc.drivers=org.postgresql.Driver jdbctest
说明DWS 下载的JDBC驱动包中提供gsjdbc.jar。
gsjdbc4.jar:与PostgreSQL保持兼容,其中类名、类结构与PostgreSQL驱动完全一致,曾经运行于PostgreSQL的应用程序可以直接移植到当前系统中使用。
- 调用JDBC的数据库连接方法DriverManager.getConnection()连接DWS 数据库。
JDBC接口不提供重试连接的能力,您需要在业务代码中实现重试处理。
DriverManager.getConnection()方法支持以下重载:
- DriverManager.getConnection(String url);
- DriverManager.getConnection(String url, Properties info);
- DriverManager.getConnection(String url, String user, String password);
数据库连接参数
参数 | 描述 |
---|---|
url | 数据库连接描述符,可以在管理控制台查看,具体步骤请参见获取集群连接地址。 url的格式如下: jdbc:postgresql:database jdbc:postgresql://host/database jdbc:postgresql://host:port/database jdbc:postgresql://host:port[,host:port][...]/database 说明 使用gsjdbc200.jar时,将“jdbc:postgresql”修改为“jdbc:gaussdb” database为要连接的数据库名称。 host为数据库服务器名称或IP地址。 DWS管理控制台上集群的连接IP,根据网络环境判断,如果连接DWS的机器跟DWS集群在同一个网络下,则选择内网IP,不在同一个网络下,则选择公网IP。 port为数据库服务器端口。缺省情况下,会尝试连接到localhost的8000端口的database。 支持多ip端口配置形式,jdbc自动实现了负载均衡,多ip端口配置形式是采取随机访问+failover的方式,这个过程系统会自动忽略不可达IP。 以","隔开,例如jdbc:postgresql://10.10.0.13:8000,10.10.0.14:8000/database 使用JDBC连接集群时集群链接地址只支持指定jdbc连接参数,不支持增加变量参数。 |
info | 数据库连接属性。常用的属性如下: user:String类型。表示创建连接的数据库用户。 password:String类型。表示数据库用户的密码。 ssl:Boolean类型。表示是否使用SSL连接。 loggerLevel:string类型。为LogStream或LogWriter设置记录进DriverManager当前值的日志信息量。目前支持"OFF"、"DEBUG"和"TRACE"。 值为"DEBUG"时,表示只打印DEBUG级别以上的日志,将记录非常少的信息。值等于TRACE时,表示打印DEBUG和TRACE级别的日志,将产生详细的日志信息。默认值为OFF,表示不打印日志。 prepareThreshold:integer类型。用于确定在转换为服务器端的预备语句之前,要求执行方法PreparedStatement的次数。缺省值是5。 batchMode : boolean类型,用于确定是否使用batch模式连接。 fetchsize:integer类型,用于设置数据库链接所创建statement的默认fetchsize。 ApplicationName:string类型。应用名称,在不做设置时,缺省值为PostgreSQL JDBC Driver。 allowReadOnly:boolean类型,用于设置connection是否允许设置readonly模式,默认为false,若该参数不被设置为true,则执行connection.setReadOnly不生效。 blobMode:string类型,用于设置setBinaryStream方法为不同的数据类型赋值,设置为on时表示为blob数据类型赋值,设置为off时表示为bytea数据类型赋值,默认为on。 connectionExtraInfo:Boolean类型。表示驱动是否上报当前驱动的部署路径、进程属主用户到数据库。 说明 取值范围:true或false,默认值为true。设置connectionExtraInfo为true,JDBC驱动会将当前驱动的部署路径、进程属主用户上报到数据库中,记录在connection_info参数里;同时可以在PG_STAT_ACTIVITY和PGXC_STAT_ACTIVITY中查询到。 |
user | 数据库用户。 |
password | 数据库用户的密码。 |
以SSL证书方式加密连接样例代码如下:
//以下代码将获取数据库SSL连接操作封装为一个接口。
public static Connection GetConnection(String username, String passwd)
{
//定义驱动类。
String driver = "org.postgresql.Driver";
//设置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" + '/'
+ "gaussdb";
Connection conn = null;
try
{
//加载驱动。
Class.forName(driver);
}
catch( Exception e )
{
e.printStackTrace();
return null;
}
try
{
//创建连接。
conn = DriverManager.getConnection(url, props );
System.out.println("Connection succeed!");
}
catch(Exception e)
{
e.printStackTrace();
return null;
}
return conn;
}
- 执行SQL语句。
a.创建语句对象。
Statement stmt = con.createStatement();
b.执行语句对象。
int rc = stmt.executeUpdate("CREATE TABLE tab1(id INTEGER, name VARCHAR(32));");
c.释放语句对象。
stmt.close();
- 调用方法close()关闭连接。
示例代码
此示例将演示如何基于DWS 提供的JDBC接口开发应用程序。
说明在完成以下示例前,需要先创建存储过程。具体请参见《[数据仓库服务用户开发指南](https://www.ctyun.cn/document/10014061/10025616)》中的“教程:使用JDBC或ODBC开发”章节。
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;
/
//DBtest.java
//以下用例以gsjdbc4.jar为例。
//演示基于JDBC开发的主要步骤,会涉及创建数据库、创建表、插入数据等。
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 {
//创建数据库连接,以下IP地址和database替换为对应的数据库连接地址和数据库名称。
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 {
//加载数据库驱动。
Class.forName(driver).newInstance();
} catch (Exception e) {
e.printStackTrace();
return null;
}
try {
//创建数据库连接。
conn = DriverManager.getConnection(sourceURL, username, passwd);
System.out.println("Connection succeed!");
} catch (Exception e) {
e.printStackTrace();
return null;
}
return conn;
};
//执行普通SQL语句,创建customer_t1表。
public static void CreateTable(Connection conn) {
Statement stmt = null;
try {
stmt = conn.createStatement();
//执行普通SQL语句。
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();
}
}
//执行预处理语句,批量插入数据。
public static void BatchInsertData(Connection conn) {
PreparedStatement pst = null;
try {
//生成预处理语句。
pst = conn.prepareStatement("INSERT INTO customer_t1 VALUES (?,?)");
for (int i = 0; i < 3; i++) {
//添加参数。
pst.setInt(1, i);
pst.setString(2, "data " + i);
pst.addBatch();
}
//执行批处理。
pst.executeBatch();
pst.close();
} catch (SQLException e) {
if (pst != null) {
try {
pst.close();
} catch (SQLException e1) {
e1.printStackTrace();
}
}
e.printStackTrace();
}
}
//执行预编译语句,更新数据。
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();
}
}
//执行存储过程。
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); //注册out类型的参数,类型为整型。
cstmt.execute();
int out = cstmt.getInt(4); //获取out参数
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();
}
}
/**
* 主程序,逐步调用各静态方法。
* @param args
*/
public static void main(String[] args) {
//创建数据库连接,以下User、Password替换为实际连接的数据库用户和密码。
Connection conn = GetConnection("User", "Password");
//创建表。
CreateTable(conn);
//批插数据。
BatchInsertData(conn);
//执行预编译语句,更新数据。
ExecPreparedSQL(conn);
//执行存储过程。
ExecCallableSQL(conn);
//关闭数据库连接。
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
配置JDBC连接集群(使用IAM认证方式)
概述
DWS 提供了使用IAM认证方式访问数据库的功能。当使用JDBC应用程序连接集群时,您可以在JDBC连接中配置IAM用户名及其用户凭证等信息,在连接数据库时系统就会自动生成临时数据库凭证,从而成功连接到数据库。
说明当前仅支持1.3.1及以上版本的集群及其配套的JDBC驱动程序使用IAM认证方式访问数据库。请先参考上方“下载JDBC或ODBC驱动”章节,下载JDBC驱动程序。
IAM用户凭证有密码和访问密钥(Access Key ID和Secret Access Key,简称AK和SK)两种类型,您要为JDBC连接提供 IAM 访问密钥。
如需使用IAM用户凭证访问数据库,必须先给您的IAM用户授予DWS Database Access权限,同时拥有DWS Administrator和DWS Database Access权限的用户,才能基于IAM用户生成临时数据库用户凭证以连接DWS 数据库。
需要注意的是,DWS Database Access是用户组级别的权限,您可以通过为用户组授权并将用户加入到用户组的方式,使用户具有用户组中的权限。
在IAM中,只有admin用户组的用户可以管理用户。如需给IAM用户授权,您的IAM帐号必须属于IAM的admin用户组,否则,请联系IAM账号管理员帮您授权。
使用IAM用户凭证访问数据库的流程如下:
- 授予IAM用户DWS Database Access权限。
- 创建IAM用户凭证。
- 配置JDBC连接使用IAM认证方式连接集群。
授予IAM用户DWS Database Access权限
- 登录云管理控制台,单击“服务列表 > 管理与监管 > 统一身份认证服务”,打开IAM管理控制台。
- 修改您的IAM用户所属的用户组,给用户组设置策略,授予用户组DWS Database Access权限,并将您的IAM用户添加到该IAM用户组中。
只有IAM的admin用户组的用户才能执行此步骤。在IAM中,只有admin用户组的用户可以管理用户,包括创建用户组及用户、设置用户组权限等。
具体操作请参见《统一身份认证服务用户指南》中的“用户指南 > 管理用户和用户组 > 查看或修改用户组”。
您也可以新创建一个IAM用户组,并给用户组设置策略,授予用户组DWS Administrator和DWS Database Access权限,然后将您的IAM用户添加到该IAM用户组中。具体操作请参见《统一身份认证服务用户指南》中的“用户指南。
管理用户和用户组 > 创建用户组”。
创建IAM用户凭证
用户可以登录管理控制台创建访问密钥,如果您已经创建过了,也可以使用已有的访问密钥。
- 登录管理控制台。
- 将鼠标移到右上角的用户名,单击“我的凭证”。
- 再单击“管理访问密钥”页签,可以查看已有的访问密钥,也可以单击“新增访问密钥”进行创建。
访问密钥是IAM身份认证的重要凭证,只有在新增访问密钥时,用户才可以下载到含有Access Key ID(AK)和Secret Access Key(SK)的密钥文件,在管理控制台只能查看到Access Key ID,如果您未曾下载过该密钥文件,请联系您的管理员进行获取,或者重新创建。
说明每个用户最多可创建2个访问密钥,有效期为永久。为了帐号安全性,建议您定期更换并妥善保存访问密钥。
配置JDBC连接使用IAM认证方式连接集群
配置JDBC连接参数
数据库连接参数
参数 | 描述 |
---|---|
url | gsjdbc4.jar/gsjdbc200.jar数据库连接描述符。JDBC接口不提供重试连接的能力,您需要在业务代码中实现重试连接的处理。url示例如下: jdbc:dws:iam://dws-IAM-demo:cn-north-4/gaussdb?AccessKeyID=XXXXXXXXXXXXXXXXXXXX&SecretAccessKey=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX&DbUser=user_test&AutoCreate=true JDBC URL参数说明: jdbc:dws:iam是URL格式的前缀。 dws-IAM-demo为数据库集群名称。 cn-north-4是集群所在的区域。 有关DWS的区域信息,请向数据库系统管理员获取。 gaussdb是要连接的数据库名。 AccessKeyID/SecretAccessKey为参数DbUser指定的IAM用户所对应的访问密钥ID和秘密访问密钥。 DbUser请设置为IAM用户名,注意,当前版本暂不支持IAM用户名中含有中划线的情况。 − 如果数据库中已存在DbUser指定的用户,则临时用户凭证具有与现有用户相同的权限。 − 如果数据库中不存在DbUser指定的用户,且AutoCreate参数值为true,则自动创建一个以DbUser参数值作为用户名的新用户,默认创建的用户为数据库普通用户。 AutoCreate可以不设置,默认为false。该参数表示是否在数据库中自动创建一个以DbUser参数值作为用户名的数据库用户。 − true表示自动创建。如果用户已存在则不会再创建。 − false表示不会自动创建。如果数据库中不存在DbUser指定的用户名将返回失败。 |
info | 数据库连接属性。常用的属性如下: ssl:Boolean类型。表示是否使用SSL连接。 loglevel:Integer类型。为LogStream或LogWriter设置记录进DriverManager当前值的日志信息量。 目前支持org.postgresql.Driver.DEBUG和org.postgresql.Driver.INFO。值为1时,表示只打印org.postgresql.Driver.INFO,将记录非常少的信息。值大于等于2时,表示打印org.postgresql.Driver.DEBUG和org.postgresql.Driver.INFO,将产生详细的日志信息。默认值为0,表示不打印日志。 charSet:String类型。表示在向数据库发送数据或从数据库接收数据时使用到的字符集。 prepareThreshold:Integer类型。用于确定在转换为服务器端的预备语句之前,要求执行方法PreparedStatement的次数。缺省值是5。 |
示例
//以下用例以gsjdbc4.jar为例。
//以下代码将获取数据库连接操作封装为一个接口,可通过给定集群所在的区域、集群名称、AccessKeyID、SecretAccessKey及对应的IAM用户名来连接数据库。
public static Connection GetConnection(String clustername, String regionname, String AK, String SK, String username)
{
//驱动类。
String driver = "org.postgresql.Driver";
//数据库连接描述符。
String sourceURL = "jdbc:dws:iam://" + clustername + ":" + regionname + "/postgresgaussdb?" + "AccessKeyID=" + AK + "&SecretAccessKey=" + SK + "&DbUser=" + username + "&autoCreate=true";
Connection conn = null;
try
{
//加载驱动。
Class.forName(driver);
}
catch( Exception e )
{
return null;
}
try
{
//创建连接。
conn = DriverManager.getConnection(sourceURL);
System.out.println("Connection succeed!");
}
catch(Exception e)
{
return null;
}
return conn;
};
使用ODBC连接数据库
DWS 支持使用ODBC应用程序连接数据库。应用程序可以在云平台环境的弹性云主机中,或者互联网环境连接数据库。
ODBC接口的使用方法,请自行查阅官方文档。
前提条件
- 已下载Linux版本的ODBC驱动包“dws_odbc_driver_for_linux.zip”和Windows版本的ODBC驱动包“dws_odbc_driver_for_windows.zip”,请参见上方“下载JDBC或ODBC驱动”章节。DWS 也支持开源的ODBC驱动程序:PostgreSQL ODBC 09.01.0200或更高版本。
- 已下载开源unixODBC代码文件,支持版本为2.3.0。
- 已下载SSL证书文件,请参见使用SSL进行安全的TCP/IP连接章节“在 gsql 客户端配置 SSL 认证相关的数字证书参数”部分内容,下载SSL证书。
在Linux环境使用ODBC连接
- 将ODBC驱动包和代码文件上传到Linux环境,并解压到指定目录。
- 以root用户登录Linux环境。
- 准备unixODBC。
a.解压unixODBC代码文件。
tar-xvf unixODBC-2.3.0.tar.gz
b.修改配置。
cd unixODBC-2.3.0
vi configure
将“LIB_VERSION”修改为如下内容,并保存退出。
LIB_VERSION="1:0:0"
c.编译并安装。
./configure--enable-gui=no
make
make install
- 替换驱动文件。
a.解压“dws_odbc_driver_for_linux.zip”。
unzip dws_odbc_driver_for_linux.zip
b.将“dws_odbc_driver_for_linux.zip”解压后“lib”目录下所有文件,替换到“/usr/local/lib”。
c.将“dws_odbc_driver_for_linux.zip”解压后“odbc/lib”目录下的“psqlodbcw.la”和“psqlodbcw.so”,保存到“/usr/local/lib”。
- 执行以下命令,修改驱动文件配置。
vi /usr/local/etc/odbcinst.ini
将以下内容保存到配置中
[DWS]
Driver64=/usr/local/lib/psqlodbcw.so
参数说明如下:
- “[DWS]”:表示驱动器名称,支持自定义。
- “Driver64”或“Driver”:表示驱动动态库的路径。64位系统优先查找“Driver64”配置项,如果未配置则会继续查找“Driver”。
- 执行以下命令,修改数据源文件。
vi /usr/local/etc/odbc.ini
将以下内容保存到配置文件中,并退出修改。
[DWSODBC]
Driver=DWS
Servername=10.10.0.13
Database=gaussdb
Username=dbadmin
Password=password
Port=8000
Sslmode=allow
参数名 | 说明 | 参数值样例 |
---|---|---|
[DSN] | 数据源的名称。 | [DWSODBC] |
Driver | 驱动名称,对应“odbcinst.ini”中的DriverName。 | Driver=DWS |
Servername | 服务器的IP地址。 | Servername=10.10.0.13 |
Database | 要连接的数据库的名称。 | Database=gaussdb |
Username | 数据库用户名称。 | Username=dbadmin |
Password | 数据库用户密码。 | Password=password |
Port | 服务器的端口号。 | Port=8000 |
Sslmode | SSL认证工作模式。集群默认开启。 取值及含义: disable:只尝试非SSL连接。 allow:首先尝试非SSL连接,如果连接失败,再尝试SSL连接。 prefer:首先尝试SSL连接,如果连接失败,将尝试非SSL连接。 require:只尝试SSL连接。如果存在CA文件,则按设置成verify-ca的方式验证。 verify-ca:只尝试SSL连接,并且验证服务器是否具有由可信任的证书机构签发的证书。 verify-full:DWS不支持此模式。 说明 SSL模式安全性高于普通模式,集群默认开启SSL功能允许来自客户端的SSL连接或非SSL连接,建议在使用ODBC连接DWS集群时采用SSL模式。 |
Sslmode=allow |
说明其中,参数“Servername”和“Port”的值,可以在DWS 的管理控制台查看。请登录DWS 管理控制台,单击“连接管理”, 在“数据仓库连接字符串”区域,选择指定的集群,获取该集群的“内网访问地址”或“公网访问地址”。具体步骤请参见[获取集群连接地址](https://www.ctyun.cn/document/10014061/10047782)。
- 配置环境变量。
vi ~/.bashrc
在配置文件中追加以下内容。
export LD_LIBRARY_PATH=/usr/local/lib/:$LD_LIBRARY_PATH
export ODBCSYSINI=/usr/local/etc
export ODBCINI=/usr/local/etc/odbc.ini
- 导入环境变量。
source ~/.bashrc
- 执行以下命令,开始连接。
/usr/local/bin/isql -v DWSODBC
界面显示以下信息表示连接成功:
+---------------------------------------+
| Connected! |
| |
| sql-statement |
| help [tablename] |
| quit |
| |
+---------------------------------------+
SQL>
在Windows环境使用ODBC连接
- 解压Windows版本的ODBC驱动包“dws_odbc_driver_for_windows.zip”,并安装“psqlodbc.msi”。
- 解压SSL证书压缩包,并准备证书文件。
用户可以根据实际情况选择自动或手动部署方法。
自动部署:
双击"sslcert_env.bat"文件,即可完成证书的默认位置的部署。
说明该sslcert_env.bat为了保证证书环境的纯净,在%APPDATA%\postgresql目录存在时,会提示是否需要移除相关目录。如果有需要,请备份该目录中的文件。
手动部署:
a.在“%APPDATA%\”目录创建一个新文件夹,并命名为“postgresql”。
b.将证书文件包中的“client.crt”、“client.key”、“client.key.cipher”、“client.key.rand”文件保存至“%APPDATA%\postgresql”目录,并且将文件名中的client改为 postgres ,例如“client.key”修改为“postgres.key”。
c.将“cacert.pem”文件保存至“%APPDATA%\postgresql”目录,并更名为“root.crt”。
- 打开驱动管理器
因为目前DWS 只提供了32位的ODBC驱动程序,所以只支持32位的应用程序开发 ;在配置数据源时,也请使用32位的驱动管理器(假设操作系统安装盘符为C:盘,如果是其他盘符,请对路径做相应修改):
- 64位操作系统请使用:C:\Windows\SysWOW64\odbcad32.exe
请勿直接使用“控制面板->系统和安全->管理工具->数据源(ODBC)”。
说明WoW64的全称是"Windows32-bit on Windows 64-bit",C:\Windows\SysWOW64\存放的是64位系统上的32位运行环境。而C:\Windows\System32\存放的是与操作系统一致的运行环境,具体的技术信息请查阅Windows的相关技术文档。
- 32位操作系统请使用:C:\Windows\System32\odbcad32.exe
或者单击“开始菜单->控制面板->系统和安全->管理工具->数据源(ODBC)”打开驱动管理器。
- 配置连接数据源。
a.在打开的驱动管理器上,选择“用户DSN>添加>PostgreSQL Unicode”,然后进行配置。
详见下图:配置连接数据源
其中,配置项“Server”和“Port”的值,可以在DWS 的管理控制台查看。请登录DWS 管理控制台,单击“连接管理”, 在“数据仓库连接字符串”区域,选择指定的集群,获取该集群的“内网访问地址”或“公网访问地址”。具体步骤请参见获取集群连接地址。
b.单击“Test”验证连接正确,界面提示“Connection successful”。
- 编写ODBC样例程序连接数据源。
ODBC接口不提供重试连接数据库的能力,您需要在业务代码中实现重试连接的处理。
样例代码如下:
// 此示例演示如何通过ODBC方式获取DWS 中的数据。
// DBtest.c (compile with: libodbc.so)
#include <stdlib.h>
#include <stdio.h>
#include <sqlext.h>
#ifdef WIN32
#include <windows.h>
#endif
SQLHENV V_OD_Env; // Handle ODBC environment
SQLHSTMT V_OD_hstmt; // Handle statement
SQLHDBC V_OD_hdbc; // Handle connection
char typename[100];
SQLINTEGER value = 100;
SQLINTEGER V_OD_erg,V_OD_buffer,V_OD_err,V_OD_id;
int main(int argc,char *argv[])
{
// 1. 申请环境句柄
V_OD_erg = SQLAllocHandle(SQL_HANDLE_ENV,SQL_NULL_HANDLE,&V_OD_Env);
if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
{
printf("Error AllocHandle\n");
exit(0);
}
// 2. 设置环境属性(版本信息)
SQLSetEnvAttr(V_OD_Env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);
// 3. 申请连接句柄
V_OD_erg = SQLAllocHandle(SQL_HANDLE_DBC, V_OD_Env, &V_OD_hdbc);
if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
{
SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
exit(0);
}
// 4. 设置连接属性
SQLSetConnectAttr(V_OD_hdbc, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_ON, 0);
// 5. 连接数据源,其中的用户名和用户密码等信息之所以能省略,是因为在odbc.ini文件中进行了配置,若没配置需要在SQLConnect函数参数中具体写明要连接数据库的用户名和用户密码等信息。
V_OD_erg = SQLConnect(V_OD_hdbc, (SQLCHAR*) "gaussdb", SQL_NTS,
(SQLCHAR*) "", SQL_NTS, (SQLCHAR*) "", SQL_NTS);
if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
{
printf("Error SQLConnect %d\n",V_OD_erg);
SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
exit(0);
}
printf("Connected !\n");
// 6. 设置语句属性
SQLSetStmtAttr(V_OD_hstmt,SQL_ATTR_QUERY_TIMEOUT,(SQLPOINTER *)3,0);
// 7. 申请语句句柄
SQLAllocHandle(SQL_HANDLE_STMT, V_OD_hdbc, &V_OD_hstmt);
// 8. 直接执行SQL语句。
SQLExecDirect(V_OD_hstmt,"drop table IF EXISTS testtable",SQL_NTS);
SQLExecDirect(V_OD_hstmt,"create table testtable(id int)",SQL_NTS);
SQLExecDirect(V_OD_hstmt,"insert into testtable values(25)",SQL_NTS);
// 9. 准备执行
SQLPrepare(V_OD_hstmt,"insert into testtable values(?)",SQL_NTS);
// 10. 绑定参数
SQLBindParameter(V_OD_hstmt,1,SQL_PARAM_INPUT,SQL_C_SLONG,SQL_INTEGER,0,0,
&value,0,NULL);
// 11. 执行准备好的语句
SQLExecute(V_OD_hstmt);
SQLExecDirect(V_OD_hstmt,"select id from testtable",SQL_NTS);
// 12. 获取结果集某一列的属性
SQLColAttribute(V_OD_hstmt,1,SQL_DESC_TYPE,typename,100,NULL,NULL);
printf("SQLColAtrribute %s\n",typename);
// 13. 绑定结果集
SQLBindCol(V_OD_hstmt,1,SQL_C_SLONG, (SQLPOINTER)&V_OD_buffer,150,
(SQLLEN *)&V_OD_err);
// 14. 通过SQLFetch取结果集中数据
V_OD_erg=SQLFetch(V_OD_hstmt);
// 15. 通过SQLGetData获取并返回数据。
while(V_OD_erg != SQL_NO_DATA)
{
SQLGetData(V_OD_hstmt,1,SQL_C_SLONG,(SQLPOINTER)&V_OD_id,0,NULL);
printf("SQLGetData ----ID = %d\n",V_OD_id);
V_OD_erg=SQLFetch(V_OD_hstmt);
};
printf("Done !\n");
// 16. 断开数据源连接并释放句柄资源
SQLFreeHandle(SQL_HANDLE_STMT,V_OD_hstmt);
SQLDisconnect(V_OD_hdbc);
SQLFreeHandle(SQL_HANDLE_DBC,V_OD_hdbc);
SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
return(0);
}