一 准备环境收起
-
预置环境
注意:开始实验之前请点击手册上方“预置实验环境”按钮。 -
预置实验环境需几分钟,成功后将会创建本实验所需的云资源(例如VPC、安全组或云服务器)。
-
如有预置的 ECS 资源,其用户、密码信息可点击实验操作桌面下方按钮查看。
-
登录云账户
进入【实验操作桌面】,打开Chrome浏览器,选择“IAM 用户登录”,并在对话框中输入系统为您分配的华为云实验账号和密码进行登录。
【实验操作桌面】是什么?
注意:请使用实验手册上方账号信息,切勿使用您自己的华为云账号登录。
二 实验配置收起
1.购买 GaussDB 实例
1)进入云数据库GaussDB服务,点击左侧的【服务列表】,选择其中【数据库】下的【云数据库GaussDB】。
2)进入云数据库GaussDB,点击页面右上角的【购买数据库实例】按钮。
3) 进入购买页后,根据以下参数信息购买数据库。
主要参数如下,其他请保持默认。
• 计费模式:选择【按需计费】
• 区域和项目:默认的【华北-北京四】
• 实例名称:可以设置为【gauss-hccdp】
• 产品类型:基础版
• 数据库引擎版本:选择最新版即可
• 实例类型:集中式版
• 部署形态:1主2备
• 可用区:选择默认的可用区一、可用区二、可用区三, 如果这些可用区购买完了,可以自行选择其他可用区。
• 性能规格: 选择 “通用型(1:4) | 4 vCPUs | 16 GB”, 如果购买完了 ,选择其他最小的规格即可,如独享型(1:4) | 4 vCPUs | 16 GB。
• 存储类型、存储空间、磁盘加密:保持默认
• 虚拟私有云、内网安全组:选择已预置的资源vpc-hce和subnet-hce
• 安全组:选择已预置的sg-hce
• 数据库端口: 使用默认的端口8000
• 管理员密码:设置符合安全要求的root用户密码,并记住以便后用,其他选择默认
4) 确认信息无误后,点击【提交】。
5) 任务提交成功后,点击【返回云数据库GaussDB列表】。
6)此时数据库进入创建状态,在运行状态处显示为【创建中】。
注意:gaussDB实例创建需要20分钟,请耐心等待
7) 当运行状态处于【正常】,表示数据库已创建完成。
2.登录数据库
1) 在数据库实例管理页面,单击已创建实例的操作列的“登录”链接。
2) 在实例登录页面,选择“自定义登录”页签,在节点信息中,选择角色为“master”的节点。
3) 填写购买GaussDB数据库时填写的密码,单击“测试连接”,如果显示“连接成功”,则可以登录实例;勾选“记住密码” 和“SQL执行记录”,最后单击“登录”按钮。
3.新建数据库和用户
登录成功后,在数据库实例首页,单击“新建数据库”按钮。
创建名为demo的数据库,其他参数可以使用默认值。
在数据库列表下面,点击新建的demo数据库操作列的“SQL查询”链接,进入SQL窗口:
使用以下命令,在demo库下创建db_dev用户,并授予sysadmin的权限, 自定义满足要求的yourpassword,并请记住,以便后用。
create user db_dev sysadmin password “yourpassword”;
4.登录已预置好的ECS
查看ECS绑定的EIP
双击打开实验桌面的 Xfce 终端,并执行以下命令,登录ecs:
ssh root@EIP
注意:请将命令中的EIP替换为您ecs的实际EIP。
接受秘钥输入“yes”,并按回车。
输入密码,并按回车(输入密码时,命令行窗口不会显示密码)。
成功登录云服务器之后如下图所示:
接受秘钥输入“yes”,并按回车。
复制预置成功的ecs密码,粘贴并按回车(输入密码时,命令行窗口不会显示密码),连接ECS。
成功登录ECS之后如下图所示:
任务一:掌握JDBC的使用收起
1 加载驱动,连接数据库,配置负载均衡
1) 执行以下命令,下载GaussDB jdbc驱动,并存放于 libs目录下。
mkdir -p /opt/expt/db/libs
cd /opt/expt/db/libs
wget https://sandbox-expriment-files.obs.cn-north-1.myhuaweicloud.com/20220525/opengaussjdbc.jar
2) 执行以下命令,下载JDK软件包,并配置环境。
wget https://sandbox-expriment-files.obs.cn-north-1.myhuaweicloud.com:443/20220525/OpenJDK11U-jdk_x64_linux_openj9_linuxXL_11.0.10_9_openj9-0.24.0.tar.gz
tar xzvf OpenJDK11U-jdk_x64_linux_openj9_linuxXL_11.0.10_9_openj9-0.24.0.tar.gz
mv jdk-11.0.10+9 /usr/lib/
ln -s /usr/lib/jdk-11.0.10+9/bin/java /usr/local/bin/java
ln -s /usr/lib/jdk-11.0.10+9/bin/javac /usr/local/bin/javac
3) 实验环境
执行以下命令,验证java运行命令是否就绪:
java -version
回显结果输出如下:
执行以下命令,验证javac运行命令是否就绪:
javac -version
回显结果输出如下:
4) 执行以下命令,在指定目录创建exptConnection.java文件
mkdir -p /opt/expt/db/basic
cd /opt/expt/db/basic
5) 使用vi命令,将以下代码内容写入exptConnection.java文件中。输入结束后,使用”:wq”保存退出vim编辑。
vi exptConnection.java
package expt.db.basic;
import java.sql.Connection;import java.sql.DriverManager;import java.util.Properties;
public class exptConnection {
static final String JDBC_DRIVER = “com.huawei.opengauss.jdbc.Driver”;
static final String DB_URL = “jdbc:opengauss://192.168.0.72:8000/demo”;
static final String USER = “db_dev”;
static final String PASS = “yourpassword”;
static String connection_url = DB_URL + “?user=” + USER + “&password=” + PASS;
public static void main(String args) {
getConnect();
}
public static Connection getConnect() {
Connection conn = null;
// 驱动注册
try {
Class.forName(JDBC_DRIVER);
} catch (Exception e) {
e.printStackTrace();
return null;
}
// 连接数据库
System.out.println(“connecting database…”);
try {
System.out.println("connection url is: " + connection_url);
conn = DriverManager.getConnection(connection_url);
System.out.println(“connection successfully!”);
return conn;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
备注:
DB_URL变量对应的值中,“192.168.0.72:8000/demo” 需修改为当前实际所使用数据库对应的主节点IP地址,“yourpassword” 修改为新创建的用户db_dev的密码 。
GaussDB主节点的IP可通过点击GaussDB实例名称,进入信息页面查看:
滑动到节点列表处,就可以看到主节点IP:
6) 执行以下命令,进行编译:
javac -d . exptConnection.java
编译完成后,会在当前目录下编译生成class数据文件及对应目录结构。
执行yum命令安装tree工具:
yum install tree
执行tree命令查看目录结构:
7) 执行以下命令,运行对应代码文件
java -cp /opt/expt/db/libs/opengaussjdbc.jar:. expt.db.basic.exptConnection
回显结果输出如下:
回显信息末尾出现”connection successfully”,说明依据当前参数已正常连接数据库。
8) 配置负载均衡
点击数据库实例,获取备机信息
如上拓扑图中,可用区一为主实例,其他两个可用区为备实例,因此192.168.0.72为主实例的IP,192.168.0.71/ 192.168.0.108为备实例的IP。
9) 配置负载均衡中的轮询策略,将代码中DB_URL的内容修改为以下内容,其中增加了其他节点的IP:PORT信息,由于增加轮询策略,需要新增参数字符串。轮询策略可以修改为autoBalance=true或者autoBalance=roundrobin;设置autoBalance为priorityn表示开启JDBC优先级负载均衡功能,将应用程序的多个连接首先均衡到url上配置的前n个中可用的CN数据库节点,当url上配置前n个节点全部不可用时,连接会随机分配到数据库集群中其他可用CN数据库节点;设置为shuffle表示开启JDBC随机负载均衡功能,将应用程序的多个连接随机均衡到数据库集群中的各个可用CN;设置为false,不开启JDBC负载均衡功能和优先级负载均衡功能,默认为不开启负载均衡。(由于本实验中数据库实例为主备,所以负载均衡只需掌握使用该功能的方法,不需考虑是否实现。)
static final String DB_URL = “jdbc:opengauss://192.168.0.72:8000,192.168.0.71:8000,192.168.0.108:8000/demo”;
static final String PARM = “autoBalance=true”;
static String connection_url = DB_URL + “?user=” + USER + “&password=” + PASS + “&” + PARM;
如果修改后有报错,请全部复制该代码至exptConnection.java中,然后修改正确的DB_URL,PASS值。
package expt.db.basic;
import java.sql.Connection;import java.sql.DriverManager;import java.util.Properties;
public class exptConnection {
static final String JDBC_DRIVER = “com.huawei.opengauss.jdbc.Driver”;
static final String DB_URL = “jdbc:opengauss://192.168.0.72:8000,192.168.0.71:8000,192.168.0.108:8000/demo”;
static final String USER = “db_dev”;
static final String PASS = “yourpassword”;
static final String PARM = “autoBalance=true”;
static String connection_url = DB_URL + “?user=” + USER + “&password=” + PASS + “&” + PARM;
public static void main(String args) {
getConnect();
}
public static Connection getConnect() {
Connection conn = null;
// 驱动注册
try {
Class.forName(JDBC_DRIVER);
} catch (Exception e) {
e.printStackTrace();
return null;
}
// 连接数据库
System.out.println(“connecting database…”);
try {
System.out.println("connection url is: " + connection_url);
conn = DriverManager.getConnection(connection_url);
System.out.println(“connection successfully!”);
return conn;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
10) 重新编译后运行程序。
javac -d . exptConnection.java
java -cp /opt/expt/db/libs/opengaussjdbc.jar:. expt.db.basic.exptConnection
11) JDBC设置读写分离,将参数修改为targetServerType=master,则尝试连接到url连接串中的主节点,如果找不到主节点将抛出异常(设置targetServerType=slave,则尝试连接到url连接串中的备节点,如果找不到备节点将抛出异常;设置targetServerType=preferSlave,则尝试连接到url连接串中的备节点,如果备节点不可用,将连接到主节点,否则抛出异常)。本实验只进行主库的连接。
static final String PARM = “targetServerType=master”;
12) 重新编译后运行程序。
javac -d . exptConnection.java
java -cp /opt/expt/db/libs/opengaussjdbc.jar:. expt.db.basic.exptConnection
2 执行建表语句
1) 执行以下命令,创建exptCreateTable.java文件。
cd /opt/expt/db/basic
2) 使用vi命令,将以下代码内容写入exptCreateTable.java文件中,修改正确的DB_URL,PASS值。输入结束后,使用”:wq”保存退出vim编辑。执行建表语句,在之前的连接前提下,修改主函数部分,即建表语句。
vi exptCreateTable.java
package expt.db.basic;
import java.sql.*;import java.util.Properties;
public class exptCreateTable {
static final String JDBC_DRIVER = “com.huawei.opengauss.jdbc.Driver”;
static final String DB_URL = “jdbc:opengauss://192.168.0.72:8000,192.168.0.71:8000,192.168.0.108:8000/demo”;
static final String USER = “db_dev”;
static final String PASS = “yourpassword”;
static final String PARM = “targetServerType=master”;
static String connection_url = DB_URL + “?user=” + USER + “&password=” + PASS + “¤tSchema=db_dev” + “&” + PARM;
public static Connection getConnect() {
Connection conn = null;
// 驱动注册
try {
Class.forName(JDBC_DRIVER);
} catch (Exception e) {
e.printStackTrace();
return null;
}
// 连接数据库
System.out.println(“connecting database…”);
try {
System.out.println("connection url is: " + connection_url);
conn = DriverManager.getConnection(connection_url);
System.out.println(“connection successfully!”);
return conn;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
//建表语句(需修改)
public static void main(String args) throws SQLException {
//执行SQL语句
Connection conn = getConnect();
Statement statement = conn.createStatement();
statement.execute(“create table test_table (id int, name varchar(10), destination varchar(20), uuid varchar(36))”);
System.out.println(“execute successfully!”);
}
}
3) 编译后运行程序,回显显示execute successfully!表示创建表完成。
javac -d . exptCreateTable.java
java -cp /opt/expt/db/libs/opengaussjdbc.jar:. expt.db.basic.exptCreateTable
3 执行插入语句
1) 执行以下命令,创建exptInsert.java文件。
cd /opt/expt/db/basic
2) 使用vi命令,将以下代码内容写入exptInsert.java文件中,修改正确的DB_URL,PASS值。输入结束后,使用”:wq”保存退出vim编辑。
vi exptInsert.java
package expt.db.basic;
import java.sql.*;import java.util.Properties;import java.util.UUID;
public class exptInsert {
static final String JDBC_DRIVER = “com.huawei.opengauss.jdbc.Driver”;
static final String DB_URL = “jdbc:opengauss://192.168.0.72:8000,192.168.0.71:8000,192.168.0.108:8000/demo”;
static final String USER = “db_dev”;
static final String PASS = “yourpassword”;
static final String PARM = “targetServerType=master”;
static String connection_url = DB_URL + “?user=” + USER + “&password=” + PASS + “¤tSchema=db_dev” + “&” + PARM;
public static Connection getConnect() {
Connection conn = null;
// 驱动注册
try {
Class.forName(JDBC_DRIVER);
} catch (Exception e) {
e.printStackTrace();
return null;
}
// 连接数据库
System.out.println(“connecting database…”);
try {
System.out.println("connection url is: " + connection_url);
conn = DriverManager.getConnection(connection_url);
System.out.println(“connection successfully!”);
return conn;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static void main(String[] args) throws SQLException {
//执行SQL语句
Connection conn = getConnect();
Statement statement = conn.createStatement();
statement.execute("INSERT INTO test_table(id, name, destination, uuid) " + "values (2, 'zhangsan', 'hangzhou', 123456789)");
System.out.println("Number of rows affected: "+statement.getUpdateCount());
}
}
3) 编译后运行程序,回显显示“Number of rows affected: 1”表示数据插入成功。
javac -d . exptInsert.java
java -cp /opt/expt/db/libs/opengaussjdbc.jar:. expt.db.basic.exptInsert
4 执行查询语句
1) 执行以下命令,创建exptQuery.java文件。
cd /opt/expt/db/basic
2) 使用vi命令,将以下代码内容写入exptQuery.java文件中,修改正确的DB_URL,PASS值。输入结束后,使用”:wq”保存退出vim编辑。
vi exptQuery.java
package expt.db.basic;
import java.sql.*;import java.util.Properties;import java.util.UUID;
public class exptQuery {
static final String JDBC_DRIVER = “com.huawei.opengauss.jdbc.Driver”;
static final String DB_URL = “jdbc:opengauss://192.168.0.72:8000,192.168.0.71:8000,192.168.0.108:8000/demo”;
static final String USER = “db_dev”;
static final String PASS = “yourpassword”;
static final String PARM = “targetServerType=master”;
static String connection_url = DB_URL + “?user=” + USER + “&password=” + PASS + “¤tSchema=db_dev” + “&” + PARM;
public static Connection getConnect() {
Connection conn = null;
// 驱动注册
try {
Class.forName(JDBC_DRIVER);
} catch (Exception e) {
e.printStackTrace();
return null;
}
// 连接数据库
System.out.println(“connecting database…”);
try {
System.out.println("connection url is: " + connection_url);
conn = DriverManager.getConnection(connection_url);
System.out.println(“connection successfully!”);
return conn;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static void closeConnect(Connection conn) {
System.out.println(“closing connection…”);
try {
conn.close();
System.out.println(“connection closed!”);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void printAllRecords(ResultSet rs) {
try {
ResultSetMetaData metaData = rs.getMetaData();
for (int i = 0; i < metaData.getColumnCount(); i++) {
System.out.print(metaData.getColumnName(i + 1) + “\t”);
}
System.out.println();
while (rs.next()) {
for (int i = 0; i < metaData.getColumnCount(); i++) {
System.out.print(rs.getString(i + 1) + "\t");
}
System.out.println();
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void printOneRecord(ResultSet rs) {
try {
ResultSetMetaData metaData = rs.getMetaData();
for (int i = 0; i < metaData.getColumnCount(); i++) {
System.out.print(metaData.getColumnName(i + 1) + “\t”);
}
System.out.println();
for (int i = 0; i < metaData.getColumnCount(); i++) {
System.out.print(rs.getString(i + 1) + “\t”);
}
System.out.println("\ncurrent row number: " + rs.getRow() + “\n”);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String args) throws SQLException {
//执行SQL语句
Connection conn = getConnect();
ResultSet resultSet = null;
PreparedStatement preparedStatement=conn.prepareStatement(“select * from test_table where id=?;”);
preparedStatement.setObject(1,2);
resultSet = preparedStatement.executeQuery();
printAllRecords(resultSet);
closeConnect(conn);
}
}
3) 编译后运行程序,回显显示“影响行数: 1”表示数据插入成功。
javac -d . exptQuery.java
java -cp /opt/expt/db/libs/opengaussjdbc.jar:. expt.db.basic.exptQuery
5 批量插入数据
1) 执行以下命令,创建exptBatchInsert.java文件。
cd /opt/expt/db/basic
2) 使用vi命令,将以下代码内容写入exptBatchInsert.java文件中,修改正确的DB_URL,PASS值。输入结束后,使用”:wq”保存退出vim编辑。第一个进行单条插入,第二个进行批量插入。
vi exptBatchInsert.java
package expt.db.basic;
import java.sql.*;import java.util.Properties;import java.util.UUID;
public class exptBatchInsert {
static final String JDBC_DRIVER = “com.huawei.opengauss.jdbc.Driver”;
static final String DB_URL = “jdbc:opengauss://192.168.0.72:8000,192.168.0.71:8000,192.168.0.108:8000/demo”;
static final String USER = “db_dev”;
static final String PASS = “yourpassword”;
static final String PARM = “targetServerType=master”;
static String connection_url = DB_URL + “?user=” + USER + “&password=” + PASS + “¤tSchema=db_dev” + “&” + PARM;
public static Connection getConnect() {
Connection conn = null;
// 驱动注册
try {
Class.forName(JDBC_DRIVER);
} catch (Exception e) {
e.printStackTrace();
return null;
}
// 连接数据库
System.out.println(“connecting database…”);
try {
System.out.println("connection url is: " + connection_url);
conn = DriverManager.getConnection(connection_url);
System.out.println(“connection successfully!”);
return conn;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static void closeConnect(Connection conn) {
System.out.println(“closing connection…”);
try {
conn.close();
System.out.println(“connection closed!”);
} catch (Exception e) {
e.printStackTrace();
}
}
public static int insertRecordOnceATime(int begin, int count) {
PreparedStatement preparedStatement;
int index = begin;
try {
Connection conn = getConnect();
conn.setAutoCommit(true);
String targetQuery = “INSERT INTO test_table(id, name, destination, uuid) VALUES(?, ?, ?, ?)”;
preparedStatement = conn.prepareStatement(targetQuery);
long start = System.currentTimeMillis();
for( ; index < begin+count; index++) {
preparedStatement.setInt(1, index);
preparedStatement.setString(2, “name-”+index);
preparedStatement.setString(3, “destination-”+index);
preparedStatement.setString(4, UUID.randomUUID().toString());
long startInternal = System.currentTimeMillis();
preparedStatement.executeUpdate();
System.out.println(“each transaction time taken = " + (System.currentTimeMillis() - startInternal) + " ms”);
}
long end = System.currentTimeMillis();
System.out.println(“total time taken = " + (end - start) + " ms”);
System.out.println(“avg total time taken = " + (end - start)/ count + " ms”);
preparedStatement.close();
closeConnect(conn);
} catch (SQLException ex) {
System.err.println(“SQLException information”);
while (ex != null) {
System.err.println("Error msg: " + ex.getMessage());
ex = ex.getNextException();
}
}
return index;
}
public static void insertRecordBatch(int begin, int count) {
PreparedStatement preparedStatement;
int index = begin;
try {
Connection conn = getConnect();
conn.setAutoCommit(true);
String targetQuery = “INSERT INTO test_table(id, name, destination, uuid) VALUES(?, ?, ?, ?)”;
preparedStatement = conn.prepareStatement(targetQuery);
for( ; index < begin+count; index++) {
preparedStatement.setInt(1, index);
preparedStatement.setString(2, “name-”+index);
preparedStatement.setString(3, “destination-”+index);
preparedStatement.setString(4, UUID.randomUUID().toString());
preparedStatement.addBatch();
}
long start = System.currentTimeMillis();
int inserted = preparedStatement.executeBatch();
long end = System.currentTimeMillis();
System.out.println(“total time taken to insert the batch = " + (end - start) + " ms”);
System.out.println(“total time taken = " + (end - start)/count + " s”);
preparedStatement.close();
closeConnect(conn);
System.out.println("row influence number is: " + inserted.length);
} catch (SQLException ex) {
System.err.println(“SQLException information”);
while (ex != null) {
System.err.println("Error msg: " + ex.getMessage());
ex = ex.getNextException();
}
throw new RuntimeException(“Error”);
}
}
public static void main(String args) throws SQLException {
int current;
current = insertRecordOnceATime(1, 1000);
insertRecordBatch(current, 1000);
}
}
3) 编译后运行程序,从运行结果中看,批量插入只需24ms,而单条插入单条提交插入需要2967ms。
javac -d . exptBatchInsert.java
java -cp /opt/expt/db/libs/opengaussjdbc.jar:. expt.db.basic.exptBatchInsert
6 关闭自动提交
1) 执行以下命令,创建exptBatchInsert2.java文件。
cd /opt/expt/db/basic
2) 使用vi命令,将以下代码内容写入exptBatchInsert2.java文件中,修改正确的DB_URL,PASS值。输入结束后,使用”:wq”保存退出vim编辑。第一个进行单条插入,第二个进行批量插入。
vi exptBatchInsert2.java
package expt.db.basic;
import java.sql.*;import java.util.Properties;import java.util.UUID;
public class exptBatchInsert2 {
static final String JDBC_DRIVER = “com.huawei.opengauss.jdbc.Driver”;
static final String DB_URL = “jdbc:opengauss://192.168.0.72:8000,192.168.0.71:8000,192.168.0.108:8000/demo”;
static final String USER = “db_dev”;
static final String PASS = “yourpassword”;
static final String PARM = “targetServerType=master”;
static String connection_url = DB_URL + “?user=” + USER + “&password=” + PASS + “¤tSchema=db_dev” + “&” + PARM;
public static Connection getConnect() {
Connection conn = null;
// 驱动注册
try {
Class.forName(JDBC_DRIVER);
} catch (Exception e) {
e.printStackTrace();
return null;
}
// 连接数据库
System.out.println("connecting database...");
try {
System.out.println("connection url is: " + connection_url);
conn = DriverManager.getConnection(connection_url);
System.out.println("connection successfully!");
return conn;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static void closeConnect(Connection conn) {
System.out.println("closing connection...");
try {
conn.close();
System.out.println("connection closed!");
} catch (Exception e) {
e.printStackTrace();
}
}
public static int insertRecordOnceATime(int begin, int count) {
PreparedStatement preparedStatement;
int index = begin;
try {
Connection conn = getConnect();
conn.setAutoCommit(false);
String targetQuery = "INSERT INTO test_table(id, name, destination, uuid) VALUES(?, ?, ?, ?)";
preparedStatement = conn.prepareStatement(targetQuery);
long start = System.currentTimeMillis();
for( ; index < begin+count; index++) {
preparedStatement.setInt(1, index);
preparedStatement.setString(2, "name-"+index);
preparedStatement.setString(3, "destination-"+index);
preparedStatement.setString(4, UUID.randomUUID().toString());
long startInternal = System.currentTimeMillis();
preparedStatement.executeUpdate();
System.out.println("each transaction time taken = " + (System.currentTimeMillis() - startInternal) + " ms");
}
conn. commit();
long end = System.currentTimeMillis();
System.out.println("total time taken = " + (end - start) + " ms");
System.out.println("avg total time taken = " + (end - start)/ count + " ms");
preparedStatement.close();
closeConnect(conn);
} catch (SQLException ex) {
System.err.println("SQLException information");
while (ex != null) {
System.err.println("Error msg: " + ex.getMessage());
ex = ex.getNextException();
}
}
return index;
}
public static void insertRecordBatch(int begin, int count) {
PreparedStatement preparedStatement;
int index = begin;
try {
Connection conn = getConnect();
conn.setAutoCommit(true);
String targetQuery = "INSERT INTO test_table(id, name, destination, uuid) VALUES(?, ?, ?, ?)";
preparedStatement = conn.prepareStatement(targetQuery);
for( ; index < begin+count; index++) {
preparedStatement.setInt(1, index);
preparedStatement.setString(2, "name-"+index);
preparedStatement.setString(3, "destination-"+index);
preparedStatement.setString(4, UUID.randomUUID().toString());
preparedStatement.addBatch();
}
long start = System.currentTimeMillis();
int[] inserted = preparedStatement.executeBatch();
long end = System.currentTimeMillis();
System.out.println("total time taken to insert the batch = " + (end - start) + " ms");
System.out.println("total time taken = " + (end - start)/count + " s");
preparedStatement.close();
closeConnect(conn);
System.out.println("row influence number is: " + inserted.length);
} catch (SQLException ex) {
System.err.println("SQLException information");
while (ex != null) {
System.err.println("Error msg: " + ex.getMessage());
ex = ex.getNextException();
}
throw new RuntimeException("Error");
}
}
public static void main(String[] args) throws SQLException {
int current;
current = insertRecordOnceATime(1, 1000);
insertRecordBatch(current, 1000);
}
}
3) 编译后运行程序,从运行结果中看,批量插入只需26ms,而单条插入批量提交需要441ms,比之前的单条插入单条提交的速度有所提升。
javac -d . exptBatchInsert2.java
java -cp /opt/expt/db/libs/opengaussjdbc.jar:. expt.db.basic.exptBatchInsert2
任务二:掌握ODBC的使用收起
1.加载驱动,连接数据库
1) 获取unixODBC源码包。
yum install -y libtool
yum install -y libtool-ltdl-devel
yum install -y openssl-devel
mkdir -p /opt/odbc
cd /opt/odbc
wget https://sandbox-experiment-files.obs.cn-north-4.myhuaweicloud.com/2442/unixODBC-2.3.7.tar.gz
2) 安装unixODBC。如果机器上已经安装了其他版本的unixODBC,可以直接覆盖安装。
tar zxvf unixODBC-2.3.7.tar.gz
cd unixODBC-2.3.7
修改configure文件,找到LIB_VERSION,将它的值修改为"1:0:0",这样将编译出*.so.1的动态库,与psqlodbcw.so的依赖关系相同。
vim configure
跳转到17642行,将LIB_VERSION="2:0:0"修改为LIB_VERSION="1:0:0"后,使用”:wq”退出。
LIB_VERSION=“1:0:0”
进行编译(如果要在ARM服务器上编译,请追加一个configure参数:–build=aarch64-unknown-linux-gnu)
./configure --enable-gui=no make
使用root用户进行安装
make install
3) 替换客户端GaussDB驱动程序。
将GaussDB-Kernel-VxxxRxxxCxx-xxxxx-64bit-Odbc.tar.gz解压。解压后会得到两个文件夹:lib与odbc,在odbc文件夹中还会有一个lib文件夹。将解压后得到的/lib文件夹与/odbc/lib文件夹中的所有动态库都拷贝到“/usr/local/lib”目录下。
cd /root
wget https://sandbox-expriment-files.obs.cn-north-1.myhuaweicloud.com/2434/GaussDB-Kernel-V500R002C10-EULER-64bit-Odbc.tar.gz
tar zxvf GaussDB-Kernel-V500R002C10-EULER-64bit-Odbc.tar.gz
cd /root/lib/
cp * /usr/local/lib
cd /root/odbc/lib/
cp * /usr/local/lib
4) 配置数据源
使用vi命令,在“/usr/local/etc/odbcinst.ini”文件中追加以下内容。
vi /usr/local/etc/odbcinst.ini
[GaussMPP]Driver64=/usr/local/lib/psqlodbcw.sosetup=/usr/local/lib/psqlodbcw.so
使用vi命令,在“/usr/local/etc/odbc.ini”文件中追加以下内容, 然后修改Servername,Password的值。(其中Servername需要更换为实际GaussDB主节点IP,用户名、密码和数据库可以继续沿用JDBC实验中的信息)
vi /usr/local/etc/odbc.ini
[MPPODBC]Driver=GaussMPPServername=192.168.0.72Database=demoUsername=db_devPassword=yourpasswordPort=8000
5) 配置环境变量,使用vim ~/.bashrc,在.bashrc文件中追加以下内容
export LD_LIBRARY_PATH=/usr/local/lib/:$LD_LIBRARY_PATHexport ODBCSYSINI=/usr/local/etcexport ODBCINI=/usr/local/etc/odbc.ini
6) 生效环境变量
source ~/.bashrc
7) 测试数据源
isql -v MPPODBC
回显为以下内容,表示测试成功:
成功后可以使用命令"quit"或者"ctrl+c"回到系统页面
2.执行SQL语句
1) 创建/opt/odbc/db/basic目录,并在目录下创建DBtest.c文件
mkdir -p /opt/odbc/db/basic
cd /opt/odbc/db/basic
2) 使用vi命令,将以下代码添加进DBtest.c文件中。
vi DBtest.c
// 此示例演示如何通过ODBC方式获取GaussDB中的数据。// 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, (SQLPOINTER)SQL_AUTOCOMMIT_ON, 0);
// 5. 连接数据源,这里的“userName”与“password”分别表示连接数据库的用户名和用户密码,请根据实际情况修改。
// 如果odbc.ini文件中已经配置了用户名密码,那么这里可以留空(“”);但是不建议这么做,因为一旦odbc.ini权限管理不善,将导致数据库用户密码泄露。
V_OD_erg = SQLConnect(V_OD_hdbc, (SQLCHAR*) “MPPODBC”, 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 customer_t1”,SQL_NTS);
SQLExecDirect(V_OD_hstmt,“CREATE TABLE customer_t1(c_customer_sk INTEGER, c_customer_name VARCHAR(32));”,SQL_NTS);
SQLExecDirect(V_OD_hstmt,“insert into customer_t1 values(25,‘LiLei’)”,SQL_NTS);
// 9. 准备执行
SQLPrepare(V_OD_hstmt,“insert into customer_t1 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);
}
3) 使用gcc编译程序
gcc -lodbc -g DBtest.c -o DBtest
4) 执行DBtest程序,回显为Done!
./DBtest
5) 验证数据,使用isql登录数据库,并执行sql,回显有数据,表示程序创建表并插入数据成功。
登录数据库:
isql -v MPPODBC
执行查询SQL:
select * from customer_t1;
退出isql连接:
quit
任务三:掌握Psycopg的使用收起
1.加载驱动,连接数据库
1) 在当前路径下,执行以下命令,创建代码结构目录
mkdir -p /opt/py/db/basic
提示:basic目录下存放本次实验涉及的具体代码。
2) 执行以下命令,验证python3运行命令是否就绪:
python3 -V
回显结果输出如下:
3) 在根目录中下载编译好的psycopg2压缩包并解压,解压完成后查看
wget https://opengauss.obs.cn-south-1.myhuaweicloud.com/3.0.0/x86/openGauss-3.0.0-CentOS-x86_64-Python.tar.gz
ls
tar -zxvf openGauss-3.0.0-CentOS-x86_64-Python.tar.gz
ls
-
将psycopg2拷贝到python安装目录的第三方包文件夹(即site-packages目录)下,并将lib文件夹中的内容移动到/usr/local/lib目录下
mv psycopg2/ /usr/local/lib/python3.6/site-packages/
mv lib/* /usr/local/lib -
使用以下命令打开.bash_profile文件
vim ~/.bash_profile -
把以下命令追加到.bash_profile文件中,它将lib目录配置在LD_LIBRARY_PATH环境变量中, 输入完成后,输入:wq后保存退出。
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib -
使用以下命令使环境变量生效
source ~/.bash_profile -
执行以下命令,在指定目录创建conn.py文件
cd /opt/py/db/basic -
使用vi命令,将以下代码内容写入conn.py文件中,然后修改host为GaussDB主节点IP,password为用户db_dev的密码。输入结束后,使用”:wq”保存退出vim编辑
vi conn.py
import psycopg2
conn=psycopg2.connect(database=“demo”,user=“db_dev”,password=“yourpassword”,host=“192.168.0.72”,port=8000)
print(“Conn database successfully”) -
执行以下命令,运行conn.py脚本
python3 conn.py
回显结果输入如下:
回显信息末尾出现”Conn database successfully”,说明依据当前参数已正常连接数据库。
2.执行SQL语句
- 在/opt/py/db/basic目录下创建demo.py文件
cd /opt/py/db/basic - 使用vi命令,将以下代码添加进demo.py文件中,然后修改host为GaussDB主节点IP,password为用户db_dev的密码。
vi demo.py
import psycopg2
conn=psycopg2.connect(database=“demo”,user=“db_dev”,password=“yourpassword”,host=“192.168.0.72”,port=8000)#创建指针对象
cur=conn.cursor()# 创建表
cur.execute(“CREATE TABLE employee(id integer,name varchar,sex varchar);”)#插入数据
cur.execute(“INSERT INTO employee(id,name,sex) VALUES(%s,%s,%s)”,(1,‘Steve’,‘M’))
cur.execute(“INSERT INTO employee(id,name,sex) VALUES(%s,%s,%s)”,(2,‘Emma’,‘F’))
cur.execute(“INSERT INTO employee(id,name,sex) VALUES(%s,%s,%s)”,(3,‘Chris’,‘M’))
获取结果
cur.execute(‘SELECT * FROM employee’)
results=cur.fetchall()print (results)
关闭连接
conn.commit()
cur.close()
conn.close()
3) 执行以下命令,运行demo.py脚本
python3 demo.py
回显结果输入如下:
回显信息末尾出现表中的数据,说明依据当前脚本已经执行成功,并将表中的数据取出返回。
------恭喜您完成本实验------