金融场景下GaussDB Java编程综合实践
本实验主要介绍了模拟银行金融场景下,使用Java程序在华为云部署GaussDB数据库中,完成用户开户、用户开卡、用户购买理财产品等功能,并完成GaussDB相关运维操作。
一 购买 GaussDB 实例 #
1.1 进入云数据库GaussDB服务,点击左侧的【服务列表】,选择其中【数据库】下的【云数据库GaussDB】。
1.2 进入云数据库GaussDB,点击页面右上角的【购买数据库实例】按钮。
1.3 进入购买页后,根据以下参数信息购买数据库。
主要参数如下,其他请保持默认。
• 计费模式:选择【按需计费】
• 区域:默认的【华北-北京四】
• 实例名称:可以设置为【gauss-hccda】
• 产品类型:基础版
• 数据库版本:选择最新版即可
• 实例类型:集中式
• 部署形态:1主2备
• 性能规格: 通用型(1:4) | 4 vCPUs | 16 GB
说明:如果通用型卖完了, 请选择其它可用的规格,如 独享型(1:4) | 4 vCPUs | 16 GB 等。
• 存储类型、存储空间、磁盘加密保持默认
• 虚拟私有云:选择【vpc-hccda】, 【subnet-hccda】
• 安全组:请注意选择已预置的资源sg-hccda,注意:不要选择默认的default!
• 管理员密码:设置符合安全要求的root用户密码
• 数据库端口:保持默认8000
确认信息无误后,点击【提交】。
注意:GaussDB实例创建需要20分钟,请耐心等待
二 通过Xfce终端登录ECS服务器,下载 gsql 客户端并解压 #
2.1 通过桌面上的Xfce终端登录ECS服务器
输入以下命令,并将命令中的IP地址替换为ECS弹性公网IP
ssh root@xxx.xxx.xx.x
注意:上面的IP地址可进入华为云ECS服务查看:
ECS服务器密码如下图所示:
2.2 下载gsql客户端,并解压
wget https://dbs-download.obs.cn-north-1.myhuaweicloud.com/GaussDB/1716897684140/GaussDB_driver.zip
unzip GaussDB_driver.zip
cd /root/GaussDB_driver/Centralized/Euler2.5_X86_64
tar -xzvf GaussDB-Kernel_505.1.0_Euler_64bit_Gsql.tar.gz -C /opt
cd /opt/
source gsql_env.sh
2.3 使用gsql客户端连接数据库
以下命令的连接数据库,xxx.xxx.xx.xx是GaussDB主节点的IP,yourpassword是设置的数据库密码,请根据实际情况替换。
gsql -h xxx.xxx.xx.xx -d postgres -p 8000 -U root -W yourpassword -r
注意:GaussDB主节点的IP可通过点击GaussDB实例名称,进入信息页面查看:
\conninfo
\q
三 实验数据模型介绍 #
3.1 E-R图
3.2 关系模式
对于C银行中的4个对象,分别建立属于每个对象的属性集合,具体属性描述如下:
1、客户(客户编号、客户名称、客户邮箱,客户身份证,客户手机号)
2、银行卡(银行卡号,银行卡类型,客户编号)
3、理财产品(产品名称,产品编号,产品描述,购买金额,理财年限)
4、资产表(资产编号,客户编号,产品编号,类型,状态,申购金额,收益,申购时间)
对象之间的关系:
1、一个客户可以办理多张银行卡
2、一个客户可以购买多个理财产品
根据关系分析,设计关系模式如下图:
说明:
1、由于一个客户可以办理多张银行卡,所以银行卡表引用客户表的客户编号作为外键。
2、由于一个客户可以购买多个理财产品,同一类理财产品可由多个客户购买。所以生成关系表——资产表。资产表引用客户表的商品编号作为外键,引用理财产品表的产品编号作为外键,并且添加商品状态、商品数量、商品收益和购买时间等属性。
3、客户和保险、客户和基金的关系同理,所以资产表同样作为生成的关系表,修改资产表的理财产品编号为商品编号,商品编号引用自理财产品表、保险和基金表的编号。
3.3 物理模型
对象及字段属性为:
1、client(c_id,c_name,c_mail,c_id_card,c_phone)
2、bank_card(b_number,b_type,b_client_id)
3、financial_product(p_id,p_name,p_description,p_amount,p_year)
4、financial_asset(a_id, a_client_id,a_product_id,a_type,a_status,a_quantity,a_income,a_purchase_time)
接下来进行GaussDB数据模型表操作。
四 JDBC实验操作步骤 #
4.1 基础环境配置
- 创建用户及相应数据库和模式,用于程序后续配置使用。按下图所示,先进入数据库列表并点击登录对应数据库。
gsql -h xxx.xx.xx.x -d postgres -p 8000 -U root -W yourpassword -r
创建数据库finance。
create database finance with encoding ='utf8' ;
切换到finance数据库下。(需输入root用户密码)
\c finance
创建用户db_dev。(需指定密码)
create user db_dev identified by 'yourpassword';
创建schema finance。
create schema finance authorization db_dev;
查看schema信息。
\dn finance
\q
- 执行以下命令创建代码根目录,并进入该新创建目录。
mkdir /root/db-dev-cert
cd /root/db-dev-cert
- 在当前路径下,执行以下命令,创建代码结构目录。
mkdir libs
提示:libs后续用来存放第三方运行依赖库,basic目录下存放本次实验涉及的具体代码。
- 执行以下命令,获取GaussDB JDBC驱动,并存放于 libs目录下。
cd /root/GaussDB_driver/Centralized/Euler2.5_X86_64/
tar -zxvf GaussDB-Kernel_505.1.0_Euler_64bit_Jdbc.tar.gz
cp gaussdbjdbc.jar /root/db-dev-cert/libs/
ll /root/db-dev-cert/libs/
- 执行以下命令,下载JDK软件包,并配置环境。
cd /root
wget https://sandbox-experiment-files.obs.cn-north-4.myhuaweicloud.com:443/lab2024/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
执行以下命令,验证java运行命令是否就绪:
java -version
回显结果输出如下:
执行以下命令,验证javac运行命令是否就绪:
javac -version
回显结果输出如下:
- 在当前路径下,执行以下命令,创建综合实验代码结构目录。
mkdir -p /root/db-dev-cert/src/expt/db
cd /root/db-dev-cert/src/expt/db
mkdir -p finance/dao
mkdir -p finance/resources
ll /root/db-dev-cert/src/expt/db/finance/
提示:dao后续用来存放数据访问对象层的相关代码,resource目录下存放配置文件。
为了展示目录结构,执行下面的命令去安装tree组件 :
yum -y install tree
执行 tree 命令可以查看当前目录结构,如下图:
tree
4.2 数据库连接
执行以下命令,在指定目录创建config-db.propertie文件
cd /root/db-dev-cert/src/expt/db/finance/resources
vim config-db.properties
使用vim命令并按i进入输入模式,将以下代码内容写入config-db.properties文件中。修改DB_URL 和 PASSWORD的值。修改完成后,按ESC按钮后,输入”:wq”保存退出vim编辑。
JDBC_DRIVER= com.huawei.gaussdb.jdbc.Driver
DB_URL=jdbc:gaussdb://xxx.xxx.xx.xx:8000/finance
SCHEMA=finance
USER=db_dev
PASSWORD=yourpassword
注意:DB_URL变量对应的值中,“xxx.xxx.xx.xx” 需修改为当前实际所使用数据库对应的主节点的IP地址(不要用备节点的IP地址否则后续会出现权限不足的情况),“yourpassword”需修改为创建用户db_dev时指定的密码。
执行以下命令,在指定目录创建Const.java文件
cd /root/db-dev-cert/src/expt/db/finance
vim Const.java
使用vim命令并按i进入输入模式,将以下代码内容写入Const.java文件中。输入结束后,按ESC按钮后,输入”:wq”保存退出vim编辑。
package expt.db.finance;
public class Const {
public static final String PREFIX_LEVEL_FIR = " => ";
public static final String PREFIX_LEVEL_SEC = " ==> ";
public static final Boolean SUCCEED = true;
public static final Boolean FAILED = false;
public static final int INVALID = -1;
}
执行以下命令,在指定目录创建DBUtils.java文件
cd /root/db-dev-cert/src/expt/db/finance/dao
vim DBUtils.java
使用vim命令并按i进入输入模式,将以下代码内容写入DBUtils.java文件中。输入结束后,按ESC按钮后,输入”:wq”保存退出vim编辑。
package expt.db.finance.dao;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.Properties;
import expt.db.finance.Const;
public class DBUtils {
public static Connection getConnect() {
Connection conn = null;
System.out.println("connecting database...");
try {
InputStream inputStream = DBUtils.class.getClassLoader().
getResourceAsStream("expt/db/finance/resources/config-db.properties");
Properties properties = new Properties();
properties.load(inputStream);
String url = properties.getProperty("DB_URL");
String user = properties.getProperty("USER");
String password = properties.getProperty("PASSWORD");
String driverClass = properties.getProperty("JDBC_DRIVER");
String schema = properties.getProperty("SCHEMA");
Class.forName(driverClass);
conn = DriverManager.getConnection(url, user, password);
conn.setSchema(schema);
} catch (Exception e) {
e.printStackTrace();
return null;
}
System.out.println("connection successfully?");
return conn;
}
public static void closeConnect(Connection conn) {
System.out.println("colsing connection...");
try {
conn.close();
System.out.println("connection closed?");
} catch (Exception e) {
e.printStackTrace();
}
}
public static void printAllRecords(ResultSet rs) {
try {
if (rs == null || rs.isBeforeFirst() == false) {
System.out.println(Const.PREFIX_LEVEL_SEC + "?????????");
return;
}
继续拷贝下面的代码到上面的Java文件中:
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 {
if (rs == null || rs.isBeforeFirst() == false) {
System.out.println(Const.PREFIX_LEVEL_SEC + "?????????");
return;
}
ResultSetMetaData metaData = rs.getMetaData();
for (int i = 0; i < metaData.getColumnCount(); i++) {
System.out.print(metaData.getColumnName(i + 1) + "\t");
}
System.out.println();
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();
}
}
}
4.3 数据表初始化
执行以下命令,在指定目录创建initTables.java文件
cd /root/db-dev-cert/src/expt/db/finance
vim initTables.java
使用vim命令并按i进入输入模式,将以下代码内容写入initTables.java文件中。输入结束后,按ESC按钮后,输入”:wq”保存退出vim编辑。
package expt.db.finance;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import expt.db.finance.dao.DBUtils;
public class initTables {
public static void main(String[] args) throws SQLException {
Connection conn = DBUtils.getConnect();
createTableClient(conn);
createTableBankCard(conn);
createTableFinancialProduct(conn);
createTableFinancialAsset(conn);
System.out.println("??????????!");
}
public static void executeSql(Connection conn, String targetSql) {
Statement statement = null;
try {
statement = conn.createStatement();
statement.execute(targetSql);
} catch (SQLException ex) {
System.err.println("SQLException information");
while (ex != null) {
System.err.println("Error msg: " + ex.getMessage());
ex = ex.getNextException();
}
}
}
public static void createTableClient(Connection conn) {
String execSql = "DROP Table If Exists finance.client;" +
"Create Table finance.client " +
"(c_id int Primary key," +
" c_name varchar(100) not null," +
" c_id_card char(20) unique not null," +
" c_phone char(20) unique not null," +
" c_mail char(30) unique);";
executeSql(conn, execSql);
System.out.println("table client created");
}
继续拷贝下面的代码到上面的Java文件中:
public static void createTableBankCard(Connection conn) {
String execSql = "DROP Table If Exists finance.bank_card;" +
"Create Table finance.bank_card " +
"(b_number char(30) Primary key," +
" b_type char(20) not null," +
" b_client_id int not null);";
executeSql(conn, execSql);
System.out.println("table bank_card created");
}
public static void createTableFinancialProduct(Connection conn) {
String execSql = "DROP Table If Exists finance.financial_product;" +
"Create Table finance.financial_product " +
"(p_id int Primary key," +
" p_name varchar(100) not null," +
" p_description varchar(1000)," +
" p_amount int," +
" p_year int);";
executeSql(conn, execSql);
System.out.println("table financial_product created");
}
public static void createTableFinancialAsset(Connection conn) {
String execSql = "DROP Table If Exists finance.financial_asset;" +
"Create Table finance.financial_asset " +
"(a_id int Primary key," +
" a_client_id int not null," +
" a_product_id int not null," +
" a_type int not null," +
" a_status char(20)," +
" a_quantity int," +
" a_income int," +
" a_purchase_time Date);";
executeSql(conn, execSql);
System.out.println("table financial_asset created");
}
}
执行以下命令,进行编译:
javac -classpath ../../../ -d . initTables.java
编译完成后,会在当前目录下生编译成class数据文件及对应目录结构,执行tree命令可以看到如下的文件目录 :
tree
执行以下命令,运行对应代码文件
mkdir -p expt/db/finance/resources
cd /root/db-dev-cert/src/expt/db/finance/
cp resources/config-db.properties expt/db/finance/resources/
java -p /root/db-dev-cert/libs/gaussdbjdbc.jar expt.db.finance.initTables
回显结果输出如下:
回显信息末尾出现” 数据表初始化创建完成!”,说明数据表都已全部初始化完成。注意该程序初始化表时,会先去判断当前表是否存在,若存在会先清除后再创建,其原有数据也会清除,用作环境初始化使用。
4.4 数据初始化
执行以下命令,在指定目录创建initData.java文件
cd /root/db-dev-cert/src/expt/db/finance
vi initData.java
使用vim命令并按i进入输入模式,将以下代码内容写入initData.java文件中。输入结束后,按ESC按钮后,输入”:wq”保存退出vim编辑。
package expt.db.finance;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import expt.db.finance.dao.DBUtils;
public class initData {
static String[] dataSqls = new String[]{
"INSERT INTO finance.client(c_id,c_name,c_mail,c_id_card,c_phone) "
+ "VALUES (1,'左晓婷', 'zuoxiaoting@huawei.com', '340211199301010001', '18815650001');",
"INSERT INTO finance.client(c_id,c_name,c_mail,c_id_card,c_phone) "
+ "VALUES (2,'虞成刚', 'yuchenggang@huawei.com', '340211199301010002', '18815650002');",
"INSERT INTO finance.client(c_id,c_name,c_mail,c_id_card,c_phone) "
+ "VALUES (3,'朱长刚', 'zhuchanggang@huawei.com', '340211199301010003', '18815650003');",
"INSERT INTO finance.client(c_id,c_name,c_mail,c_id_card,c_phone) "
+ "VALUES (4,'任高峰', 'rengaofeng@huawei.com', '340211199301010004', '18815650004');",
"INSERT INTO finance.client(c_id,c_name,c_mail,c_id_card,c_phone) "
+ "VALUES (5,'安艳芳', 'anyanfang@huawei.com', '340211199301010005', '18815650005');",
"INSERT INTO finance.client(c_id,c_name,c_mail,c_id_card,c_phone) "
+ "VALUES (6,'滕长丽', 'tengchangli@huawei.com', '340211199301010006', '18815650006');",
"INSERT INTO finance.client(c_id,c_name,c_mail,c_id_card,c_phone) "
+ "VALUES (7,'傅小芳', 'fuxiaofang@huawei.com', '340211199301010007', '18815650007');",
"INSERT INTO finance.client(c_id,c_name,c_mail,c_id_card,c_phone) "
+ "VALUES (8,'卞兰娟', 'bianlanjuan@huawei.com', '340211199301010008', '18815650008');",
"INSERT INTO finance.client(c_id,c_name,c_mail,c_id_card,c_phone) "
+ "VALUES (9,'邵小婷', 'shaoxiaoting@huawei.com', '340211199301010009', '18815650009');",
"INSERT INTO finance.client(c_id,c_name,c_mail,c_id_card,c_phone) "
+ "VALUES (10,'章晓峰', 'zhangxiaofeng@huawei.com', '340211199301010010', '18815650010');",
继续拷贝下面的代码到上面的Java文件中:
"INSERT INTO finance.bank_card(b_number,b_type,b_client_id) VALUES('6222021302020000001', '信用卡',1);",
"INSERT INTO finance.bank_card(b_number,b_type,b_client_id) VALUES('6222021302020000002', '信用卡',2);",
"INSERT INTO finance.bank_card(b_number,b_type,b_client_id) VALUES('6222021302020000003', '信用卡',3);",
"INSERT INTO finance.bank_card(b_number,b_type,b_client_id) VALUES('6222021302020000004', '信用卡',4);",
"INSERT INTO finance.bank_card(b_number,b_type,b_client_id) VALUES('6222021302020000005', '储蓄卡',5);",
"INSERT INTO finance.bank_card(b_number,b_type,b_client_id) VALUES('6222021302020000006', '储蓄卡',6);",
"INSERT INTO finance.bank_card(b_number,b_type,b_client_id) VALUES('6222021302020000007', '储蓄卡',7);",
"INSERT INTO finance.bank_card(b_number,b_type,b_client_id) VALUES('6222021302020000008', '储蓄卡',8);",
"INSERT INTO finance.bank_card(b_number,b_type,b_client_id) VALUES('6222021302020000009', '储蓄卡',9);",
"INSERT INTO finance.bank_card(b_number,b_type,b_client_id) VALUES('6222021302020000010', '储蓄卡',10);",
继续拷贝下面的代码到上面的Java文件中:
"INSERT INTO finance.financial_product(p_name,p_id,p_description,p_amount,p_year) "
+ "VALUES ('债券',1,'以国 债、金融央行票据企业为主要投资方向的银理财产品。',50000,6);",
"INSERT INTO finance.financial_product(p_name,p_id,p_description,p_amount,p_year) "
+ "VALUES ('信贷资产',2,'一般指银行作为委托人将通过发理财产品募集资金给信公司,成立计划产购买理财品发售银行或第三方信贷资。',50000,6);",
"INSERT INTO finance.financial_product(p_name,p_id,p_description,p_amount,p_year) "
+ "VALUES ('股票',3,'与股票 挂钩的理财产品。目前市场上主要以港股居多',50000,6);",
"INSERT INTO finance.financial_product(p_name,p_id,p_description,p_amount,p_year) "
+ "VALUES ('大宗商品',4,'与 大宗商品期货挂钩的理财产。 目前市场上主要以挂钩黄金、石油农产品的理财居多。',50000,6);",
"INSERT INTO financial_asset(a_id, a_client_id, a_product_id, a_type, a_status, a_quantity, a_income, a_purchase_time) "
+ "VALUES (1, 1, 1, 1, '可用', 4, 8001, '2018-07-01');",
"INSERT INTO financial_asset(a_id, a_client_id, a_product_id, a_type, a_status, a_quantity, a_income, a_purchase_time) "
+ "VALUES (2, 2, 2, 1, '可用', 3, 8002, '2018-07-02');",
"INSERT INTO financial_asset(a_id, a_client_id, a_product_id, a_type, a_status, a_quantity, a_income, a_purchase_time) "
+ "VALUES (3, 3, 3, 1, '可用', 2, 8003, '2018-07-03');",
"INSERT INTO financial_asset(a_id, a_client_id, a_product_id, a_type, a_status, a_quantity, a_income, a_purchase_time) "
+ "VALUES (4, 4, 4, 1, '冻结', 1, 8004, '2018-07-04');"
};
public static void main(String[] args) throws SQLException {
Connection conn = DBUtils.getConnect();
Statement statement = conn.createStatement();
for(String targetSql: dataSqls) {
System.out.println(targetSql);
statement.execute(targetSql);
}
System.out.println("complete!");
}
}
执行以下命令,进行编译:
javac -classpath ../../../ -d . initData.java
执行以下命令,运行对应代码文件
java -p /root/db-dev-cert/libs/gaussdbjdbc.jar expt.db.finance.initData
回显结果输出如下:
回显信息末尾出现”complete!”,说明数据表数据已全部初始化完毕。
4.5 DAO层实现
DAO(Data Access Object)即数据接入对象,在实际开发场景下,用来封装数据操作及数据处理等数据相关业务行为,向上给业务层提供统一的调用接口,将业务逻辑与数据底层处理及操作解耦。
执行以下命令,在指定目录创建Client.java, BankCard.java, FinancialProduct.java, FinancialAsset.java等四个代码文件。
cd /root/db-dev-cert/src/expt/db/finance/dao
vim Client.java
使用vim命令并按i进入输入模式,将以下代码内容写入Client.java文件中。输入结束后,按ESC按钮后,输入”:wq”保存退出vim编辑。
package expt.db.finance.dao;
import java.sql.Connection;
import java.sql.SQLException;
import expt.db.finance.Const;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
public class Client {
private Connection conn;
public Client(Connection connection) {
conn = connection;
}
public ResultSet queryClientList() {
PreparedStatement pstat = null;
ResultSet rs = null;
try {
pstat = conn.prepareStatement("select c_id as 客户ID, c_name as 姓名, "
+ "c_id_card as 身份证号, c_phone as 电话号码, c_mail as 电子邮件地址 "
+ "from client");
rs = pstat.executeQuery();
} catch (SQLException ex) {
System.err.println("SQLException information");
while (ex != null) {
System.err.println("Error msg: " + ex.getMessage());
ex = ex.getNextException();
}
}
继续拷贝下面的代码到上面的Java文件中:
return rs;
}
public ResultSet queryClientById(int id) {
PreparedStatement pstat = null;
ResultSet rs = null;
try {
pstat = conn.prepareStatement("select c_id as 客户ID, c_name as 姓名, "
+ "c_id_card as 身份证号, c_phone as 电话号码, c_mail as 电子邮件地址 "
+ "from client where c_id = ?");
pstat.setInt(1, id);
rs = pstat.executeQuery();
} catch (SQLException ex) {
System.err.println("SQLException information");
while (ex != null) {
System.err.println("Error msg: " + ex.getMessage());
ex = ex.getNextException();
}
}
return rs;
}
public boolean insertClient(int id, String name, String id_card, String phone_number, String email) {
PreparedStatement pstat = null;
try {
pstat = conn.prepareStatement("INSERT INTO "
+ "client(c_id, c_name, c_id_card, c_phone, c_mail) "
+ "VALUES (?,?,?,?,?);");
pstat.setInt(1, id);
pstat.setString(2, name);
pstat.setString(3, id_card);
pstat.setString(4, phone_number);
pstat.setString(5, email);
pstat.execute();
return Const.SUCCEED;
} catch (SQLException ex) {
System.err.println("SQLException information");
while (ex != null) {
System.err.println("Error msg: " + ex.getMessage());
ex = ex.getNextException();
}
继续拷贝下面的代码到上面的Java文件中:
return Const.FAILED;
}
}
public boolean updateClient(int id, String name, String phone_number, String email) {
PreparedStatement pstat = null;
try {
pstat = conn.prepareStatement("UPDATE client set c_name=?, c_phone=?, c_mail=? where c_id=?");
pstat.setString(1, name);
pstat.setString(2, phone_number);
pstat.setString(3, email);
pstat.setInt(4, id);
pstat.execute();
return Const.SUCCEED;
} catch (SQLException ex) {
System.err.println("SQLException information");
while (ex != null) {
System.err.println("Error msg: " + ex.getMessage());
ex = ex.getNextException();
}
return Const.FAILED;
}
}
public boolean deleteClient(int id) {
PreparedStatement pstat = null;
try {
pstat = conn.prepareStatement("DELETE from client where c_id = ?");
pstat.setInt(1, id);
pstat.execute();
return true;
} catch (SQLException ex) {
System.err.println("SQLException information");
while (ex != null) {
System.err.println("Error msg: " + ex.getMessage());
ex = ex.getNextException();
}
return false;
}
}
}
使用vim命令并按i进入输入模式,将以下代码内容写入BankCard.java文件中。输入结束后,按ESC按钮后,输入”:wq”保存退出vim编辑。
vim BankCard.java
package expt.db.finance.dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import expt.db.finance.Const;
public class BankCard {
private Connection conn;
public BankCard(Connection connection) {
this.conn = connection;
}
public ResultSet queryBankCardList() {
PreparedStatement pstat = null;
ResultSet rs = null;
try {
pstat = conn.prepareStatement("select b_number as 银行卡号, b_type as 卡片类型, "
+ "b_client_id as 客户ID "
+ "from bank_card");
rs = pstat.executeQuery();
} catch (SQLException ex) {
System.err.println("SQLException information");
while (ex != null) {
System.err.println("Error msg: " + ex.getMessage());
ex = ex.getNextException();
}
}
return rs;
}
继续拷贝下面的代码到上面的Java文件中:
public ResultSet queryBankCardByCardNumber(String bank_card_number) {
PreparedStatement pstat = null;
ResultSet rs = null;
try {
pstat = conn.prepareStatement("select b_number as 银行卡号, b_type as 卡片类型, "
+ "b_client_id as 客户ID "
+ "from bank_card where b_number = ?");
pstat.setString(1, bank_card_number);
rs = pstat.executeQuery();
} catch (SQLException ex) {
System.err.println("SQLException information");
while (ex != null) {
System.err.println("Error msg: " + ex.getMessage());
ex = ex.getNextException();
}
}
return rs;
}
public ResultSet queryBankCardByClientId(int clientId) {
PreparedStatement pstat = null;
ResultSet rs = null;
try {
pstat = conn.prepareStatement("select b_number as 银行卡号, b_type as 卡片类型, "
+ "b_client_id as 客户ID "
+ "from bank_card where b_client_id = ?");
pstat.setInt(1, clientId);
rs = pstat.executeQuery();
} catch (SQLException ex) {
System.err.println("SQLException information");
while (ex != null) {
System.err.println("Error msg: " + ex.getMessage());
ex = ex.getNextException();
}
}
return rs;
}
继续拷贝下面的代码到上面的Java文件中:
public int countOfBankCards(int clientId) {
PreparedStatement pstat = null;
ResultSet rs = null;
int recordsCount = Const.INVALID;
try {
pstat = conn.prepareStatement("select count(*) as RECORDSCOUNT from bank_card where b_client_id = ?");
pstat.setInt(1, clientId);
rs = pstat.executeQuery();
if (rs.next()) {
recordsCount = rs.getInt("RECORDSCOUNT");
}
} catch (SQLException ex) {
System.err.println("SQLException information");
while (ex != null) {
System.err.println("Error msg: " + ex.getMessage());
ex = ex.getNextException();
}
}
return recordsCount;
}
public boolean insertBankCard(String card_number, String card_type, int client_id) {
PreparedStatement pstat = null;
try {
pstat = conn.prepareStatement("INSERT INTO bank_card(b_number, b_type, b_client_id) "
+ "VALUES (?,?,?);");
pstat.setString(1, card_number);
pstat.setString(2, card_type);
pstat.setInt(3, client_id);
pstat.execute();
return Const.SUCCEED;
} catch (SQLException ex) {
System.err.println("SQLException information");
while (ex != null) {
System.err.println("Error msg: " + ex.getMessage());
ex = ex.getNextException();
}
return Const.FAILED;
}
}
继续拷贝下面的代码到上面的Java文件中:
public boolean deleteBankCardByCardNumber(String bank_card_number) {
PreparedStatement pstat = null;
try {
pstat = conn.prepareStatement("DELETE from bank_card where b_number = ?");
pstat.setString(1, bank_card_number);
pstat.execute();
return true;
} catch (SQLException ex) {
System.err.println("SQLException information");
while (ex != null) {
System.err.println("Error msg: " + ex.getMessage());
ex = ex.getNextException();
}
return false;
}
}
}
使用vim命令并按i进入输入模式,将以下代码内容写入FinancialProduct.java文件中。输入结束后,按ESC按钮后,输入”:wq”保存退出vim编辑。
vim FinancialProduct.java
package expt.db.finance.dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class FinancialProduct {
private Connection conn;
public FinancialProduct(Connection connection) {
conn = connection;
}
public ResultSet queryProductList() {
PreparedStatement pstat = null;
ResultSet rs = null;
try {
pstat = conn.prepareStatement("select p_id as 产品编号, p_name as 产品名称, "
+ "p_description as 产品描述, p_amount as 购买金额, p_year as 理财年限 "
继续拷贝下面的代码到上面的Java文件中:
+ "from financial_product");
rs = pstat.executeQuery();
} catch (SQLException ex) {
System.err.println("SQLException information");
while (ex != null) {
System.err.println("Error msg: " + ex.getMessage());
ex = ex.getNextException();
}
}
return rs;
}
public ResultSet queryProductById(int product_id) {
PreparedStatement pstat = null;
ResultSet rs = null;
try {
pstat = conn.prepareStatement("select p_id as 产品编号, p_name as 产品名称, "
+ "p_description as 产品描述, p_amount as 购买金额, p_year as 理财年限 "
+ "from financial_product where p_id = ?");
pstat.setInt(1, product_id);
rs = pstat.executeQuery();
} catch (SQLException ex) {
System.err.println("SQLException information");
while (ex != null) {
System.err.println("Error msg: " + ex.getMessage());
ex = ex.getNextException();
}
}
return rs;
}
}
使用vim命令并按i进入输入模式,将以下代码内容写入FinancialAsset.java文件中。输入结束后,按ESC按钮后,输入”:wq”保存退出vim编辑。
vim FinancialAsset.java
package expt.db.finance.dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import expt.db.finance.Const;
public class FinancialAsset {
private Connection conn;
public FinancialAsset(Connection connection) {
conn = connection;
}
public ResultSet queryAssetList() {
PreparedStatement pstat = null;
ResultSet rs = null;
try {
pstat = conn.prepareStatement("select a_id as 资产编号, a_client_id as 客户ID, "
+ "a_product_id as 产品编号, a_type as 产品类型, a_status as 状态, a_quantity as 金额, "
+ "a_income as 收益金额, a_purchase_time as 申购时间 "
+ "from financial_asset");
rs = pstat.executeQuery();
} catch (SQLException ex) {
System.err.println("SQLException information");
while (ex != null) {
System.err.println("Error msg: " + ex.getMessage());
ex = ex.getNextException();
}
}
return rs;
}
继续拷贝下面的代码到上面的Java文件中:
public ResultSet queryAssetById(int asset_id) {
PreparedStatement pstat = null;
ResultSet rs = null;
try {
pstat = conn.prepareStatement("select a_id as 资产编号, a_client_id as 客户ID, "
+ "a_product_id as 产品编号, a_type as 产品类型, a_status as 状态, a_quantity as 金额, "
+ "a_income as 收益金额, a_purchase_time as 申购时间 "
+ "from financial_asset where a_id = ?");
pstat.setInt(1, asset_id);
rs = pstat.executeQuery();
} catch (SQLException ex) {
System.err.println("SQLException information");
while (ex != null) {
继续拷贝下面的代码到上面的Java文件中:
System.err.println("Error msg: " + ex.getMessage());
ex = ex.getNextException();
}
}
return rs;
}
public ResultSet queryAssetByClientId(int client_id) {
PreparedStatement pstat = null;
ResultSet rs = null;
try {
pstat = conn.prepareStatement("select a_id as 资产编号, a_client_id as 客户ID, "
+ "a_product_id as 产品编号, a_type as 产品类型, a_status as 状态, a_quantity as 金额, "
+ "a_income as 收益金额, a_purchase_time as 申购时间 "
+ "from financial_asset where a_client_id = ?");
pstat.setInt(1, client_id);
rs = pstat.executeQuery();
} catch (SQLException ex) {
System.err.println("SQLException information");
while (ex != null) {
System.err.println("Error msg: " + ex.getMessage());
ex = ex.getNextException();
}
}
return rs;
}
public boolean insertAssetRecord(int asset_id, int client_id, int product_id, int asset_type, int quantity) {
PreparedStatement pstat = null;
try {
pstat = conn.prepareStatement("INSERT INTO financial_asset(a_id, a_client_id, a_product_id, "
+ "a_type, a_status, a_quantity, a_income, a_purchase_time) "
+ "VALUES (?,?,?,?,?,?,?,?);");
pstat.setInt(1, asset_id);
pstat.setInt(2, client_id);
pstat.setInt(3, product_id);
pstat.setInt(4, asset_type);
pstat.setString(5, "可用");
pstat.setInt(6, quantity);
pstat.setInt(7, 0);
继续拷贝下面的代码到上面的Java文件中:
pstat.setDate(8, new java.sql.Date(new java.util.Date().getTime()));
pstat.execute();
return Const.SUCCEED;
} catch (SQLException ex) {
System.err.println("SQLException information");
while (ex != null) {
System.err.println("Error msg: " + ex.getMessage());
ex = ex.getNextException();
}
return Const.FAILED;
}
}
public boolean deleteAssetRecordById(int asset_id) {
PreparedStatement pstat = null;
try {
pstat = conn.prepareStatement("DELETE from financial_asset where a_id = ?");
pstat.setInt(1, asset_id);
pstat.execute();
return Const.SUCCEED;
} catch (SQLException ex) {
System.err.println("SQLException information");
while (ex != null) {
System.err.println("Error msg: " + ex.getMessage());
ex = ex.getNextException();
}
return Const.FAILED;
}
}
public int countOfAssetRecords(int clientId) {
PreparedStatement pstat = null;
ResultSet rs = null;
int recordsCount = Const.INVALID;
try {
pstat = conn.prepareStatement("select count(*) as RECORDSCOUNT from financial_asset where a_client_id = ?");
pstat.setInt(1, clientId);
rs = pstat.executeQuery();
if (rs.next()) {
继续拷贝下面的代码到上面的Java文件中:
recordsCount = rs.getInt("RECORDSCOUNT");
}
} catch (SQLException ex) {
System.err.println("SQLException information");
while (ex != null) {
System.err.println("Error msg: " + ex.getMessage());
ex = ex.getNextException();
}
}
return recordsCount;
}
}
至此,DAO内的文件都已编写完成,为了后续上层业务能够正常使用DAO层,即确保DAO代码正确编写,需有方式能够对其进行测试。下一步继续testDAO.java测试。
执行以下命令,在指定目录创建testDAO.java文件
cd /root/db-dev-cert/src/expt/db/finance
vim testDAO.java
使用vim命令并按i进入输入模式,将以下代码内容写入testDAO.java文件中。输入结束后,按ESC按钮后,输入”:wq”保存退出vim编辑。
package expt.db.finance;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.ResultSet;
import expt.db.finance.dao.*;
public class testDAO {
public static void main(String[] args) throws SQLException {
Connection conn = DBUtils.getConnect();
testClient(conn);
testBankCard(conn);
testFinancialProduct(conn);
testFinancialAsset(conn);
conn.close();
}
public static void testFinancialAsset(Connection conn) {
FinancialAsset fa = new FinancialAsset(conn);
ResultSet rs = null;
继续拷贝下面的代码到上面的Java文件中:
rs = fa.queryAssetList();
DBUtils.printAllRecords(rs);
rs = fa.queryAssetById(1);
DBUtils.printAllRecords(rs);
fa.insertAssetRecord(5, 1, 2, 1, 666);
rs = fa.queryAssetByClientId(1);
DBUtils.printAllRecords(rs);
fa.deleteAssetRecordById(5);
rs = fa.queryAssetList();
DBUtils.printAllRecords(rs);
}
public static void testFinancialProduct(Connection conn) {
FinancialProduct fp = new FinancialProduct(conn);
ResultSet rs = null;
rs = fp.queryProductList();
DBUtils.printAllRecords(rs);
rs = fp.queryProductById(1);
DBUtils.printAllRecords(rs);
}
public static void testBankCard(Connection conn) {
BankCard bc = new BankCard(conn);
ResultSet rs = null;
rs = bc.queryBankCardList();
DBUtils.printAllRecords(rs);
bc.insertBankCard("card_number_01", "储蓄卡", 1);
rs = bc.queryBankCardByCardNumber("card_number_01");
DBUtils.printAllRecords(rs);
rs = bc.queryBankCardByClientId(1);
DBUtils.printAllRecords(rs);
bc.deleteBankCardByCardNumber("card_number_01");
rs = bc.queryBankCardByClientId(1);
DBUtils.printAllRecords(rs);
}
继续拷贝下面的代码到上面的Java文件中:
public static void testClient(Connection conn) {
Client client = new Client(conn);
ResultSet rs = null;
rs = client.queryClientList();
DBUtils.printAllRecords(rs);
client.insertClient(11, "name01", "idCard01", "phone01", "email01");
rs = client.queryClientById(11);
DBUtils.printAllRecords(rs);
client.updateClient(11, "name11", "phone11", "email11");
rs = client.queryClientById(11);
DBUtils.printAllRecords(rs);
client.deleteClient(11);
rs = client.queryClientList();
DBUtils.printAllRecords(rs);
}
}
执行以下命令,进行编译:
javac -classpath ../../../ -d . testDAO.java
编译完成后,会在当前目录下生编译成class数据文件及对应目录结构,执行tree命令可以查看目录结构,如下图 :
tree
执行以下命令,运行对应代码文件
java -p /root/db-dev-cert/libs/gaussdbjdbc.jar expt.db.finance.testDAO
回显结果输出如下:
回显信息中的内容和代码中的操作动作保持一致,且无异常信息,说明DAO相关代码完整可用,可以进行后续操作。
4.6 业务层实现
执行以下命令,在指定目录创建Utils.java, Service.java, FlowControl.java, launch.java文件。
cd /root/db-dev-cert/src/expt/db/finance
vim Utils.java
使用vim命令并按i进入输入模式,将以下代码内容写入Utils.java文件中。输入结束后,按ESC按钮后,输入”:wq”保存退出vim编辑。
package expt.db.finance;
import java.util.Scanner;
public class Utils {
public static int getInt(String hint) {
int target;
Scanner sc = new Scanner(System.in);
while (true) {
System.out.print(hint);
try {
target = sc.nextInt();
break;
} catch (Exception ex) {
System.out.println("* * * * * * ??????????? * * * * * *");
sc.nextLine();
}
}
return target;
}
public static String getString(String hint) {
String target;
Scanner sc = new Scanner(System.in);
while (true) {
System.out.print(hint);
try {
target = sc.nextLine();
break;
} catch (Exception ex) {
System.out.println("* * * * * * ??????????? * * * * * *");
sc.nextLine();
}
}
return target;
}
}
使用vim命令并按i进入输入模式,将以下代码内容写入Service.java文件中。输入结束后,按ESC按钮后,输入”:wq”保存退出vim编辑。
vim Service.java
package expt.db.finance;
import java.sql.Connection;
import java.sql.SQLException;
import expt.db.finance.dao.*;
public class Service {
private Connection conn;
private Client client;
private BankCard bankCard;
private FinancialProduct fp;
private FinancialAsset fa;
public Service() {
conn = openConnection();
client = new Client(conn);
bankCard = new BankCard(conn);
fp = new FinancialProduct(conn);
fa = new FinancialAsset(conn);
}
public Connection openConnection() {
return DBUtils.getConnect();
}
public void closeConnection() throws SQLException {
conn.close();
}
public void showClients() {
System.out.println("* * * * * * * * * 客 户 列 表 * * * * * * * * *");
DBUtils.printAllRecords(client.queryClientList());
System.out.println("* * * * * * * * * * * * * * * * * * * * * * * * * * *");
}
继续拷贝下面的代码到上面的Java文件中:
public void showClient() {
int clientId = Utils.getInt(Const.PREFIX_LEVEL_SEC + "请输入需要查询信息的客户的ID: ");
System.out.println("* * * * * * * * * 基 础 信 息 * * * * * * * * *");
DBUtils.printOneRecord(client.queryClientById(clientId));
System.out.println("* * * * * * * * * * * * * * * * * * * * * * * * * * *");
}
public void showClientWithCardsAndAssets() {
int clientId = Utils.getInt(Const.PREFIX_LEVEL_SEC + "请输入需要查询信息的客户的ID: ");
System.out.println("* * * * * * * * * * 基 本 信 息 * * * * * * * * *");
DBUtils.printOneRecord(client.queryClientById(clientId));
System.out.println("- - - - - - - - - - 开 卡 信 息 - - - - - - - - -");
DBUtils.printAllRecords(bankCard.queryBankCardByClientId(clientId));
System.out.println("- - - - - - - - - - 理财资产信息 - - - - - - - - -");
DBUtils.printAllRecords(fa.queryAssetByClientId(clientId));
System.out.println("* * * * * * * * * * * * * * * * * * * * * * * * * * *");
}
public void setUpAnAccount() {
System.out.println(Const.PREFIX_LEVEL_FIR + "已进入开户流程,请按提示要求输入客户相关信息,并按回车");
String name = Utils.getString(Const.PREFIX_LEVEL_SEC + "请输入客户姓名: ");
String idCard = Utils.getString(Const.PREFIX_LEVEL_SEC + "请输入客户身份证号: ");
String phoneNumber = Utils.getString(Const.PREFIX_LEVEL_SEC + "请输入客户手机号码: ");
String email = Utils.getString(Const.PREFIX_LEVEL_SEC + "请输入客户电子邮箱地址: ");
int clientId = Utils.getInt(Const.PREFIX_LEVEL_SEC + "请输入客户ID: ");
boolean ret = client.insertClient(clientId, name, idCard, phoneNumber, email);
if (ret == Const.SUCCEED) {
System.out.println(Const.PREFIX_LEVEL_SEC + "客户信息已录入成功!");
return;
}
System.out.println(Const.PREFIX_LEVEL_SEC + "客户信息已录入失败!");
}
继续拷贝下面的代码到上面的Java文件中:
public void modifyAnAccount() {
System.out.println(Const.PREFIX_LEVEL_FIR + "已进入更新客户信息流程,请按提示要求输入相关信息,并按回车");
int clientId = Utils.getInt(Const.PREFIX_LEVEL_SEC + "请输入需要修改信息的客户的ID: ");
String name = Utils.getString(Const.PREFIX_LEVEL_SEC + "请输入客户更新后姓名: ");
String phoneNumber = Utils.getString(Const.PREFIX_LEVEL_SEC + "请输入客户更新后手机号码: ");
String email = Utils.getString(Const.PREFIX_LEVEL_SEC + "请输入客户更新后电子邮箱地址: ");
boolean ret = client.updateClient(clientId, name, phoneNumber, email);
if (ret == Const.SUCCEED) {
System.out.println(Const.PREFIX_LEVEL_SEC + "客户础信信息更新成功!");
return;
}
System.out.println(Const.PREFIX_LEVEL_SEC + "客户信息已录入失败!");
}
public void closeAnAccount() {
System.out.println(Const.PREFIX_LEVEL_FIR + "已进入注销客户信息流程,请按提示要求输入相关信息,并按回车");
int clientId = Utils.getInt(Const.PREFIX_LEVEL_SEC + "请输入需要注销的客户的ID: ");
if (!isSafeToCloseAccount(clientId)) {
return;
}
boolean ret = client.deleteClient(clientId);
if (ret == Const.SUCCEED) {
System.out.println(Const.PREFIX_LEVEL_SEC + "销户成功!");
return;
}
System.out.println(Const.PREFIX_LEVEL_SEC + "销户失败!");
}
public void setUpAnCard() {
System.out.println(Const.PREFIX_LEVEL_FIR + "已进入开卡流程,请按提示要求输入相关信息,并按回车");
继续拷贝下面的代码到上面的Java文件中:
int clientId = Utils.getInt(Const.PREFIX_LEVEL_SEC + "请输入待开卡的客户的ID: ");
String cardNumber = Utils.getString(Const.PREFIX_LEVEL_SEC + "请输入卡号: ");
System.out.println("开卡中,默认开卡类型为储蓄卡");
String cardType = "储蓄卡";
boolean ret = bankCard.insertBankCard(cardNumber, cardType, clientId);
if (ret == Const.SUCCEED) {
System.out.println(Const.PREFIX_LEVEL_SEC + "开卡成功!");
return;
}
System.out.println(Const.PREFIX_LEVEL_SEC + "开卡失败!");
}
public void closeAnCard() {
System.out.println(Const.PREFIX_LEVEL_FIR + "已进入销卡流程,请按提示要求输入相关信息,并按回车");
String cardNumber = Utils.getString(Const.PREFIX_LEVEL_SEC + "请输入卡号: ");
boolean ret = bankCard.deleteBankCardByCardNumber(cardNumber);
if (ret == Const.SUCCEED) {
System.out.println(Const.PREFIX_LEVEL_SEC + "销卡成功!");
return;
}
System.out.println(Const.PREFIX_LEVEL_SEC + "销卡失败!");
}
public boolean isSafeToCloseAccount(int clientId) {
int countCardsUnderCurrentClient = bankCard.countOfBankCards(clientId);
int countAssetRecordsUnderCurrentClient = fa.countOfAssetRecords(clientId);
if (countCardsUnderCurrentClient == Const.INVALID ||
countAssetRecordsUnderCurrentClient == Const.INVALID) {
System.out.println(Const.PREFIX_LEVEL_SEC + "当前信息查询异常,暂不能进行销户操作!");
return false;
}
if (countCardsUnderCurrentClient > 0) {
System.out.println(Const.PREFIX_LEVEL_SEC + "当前客户存在" + countCardsUnderCurrentClient +
"张银行卡未注销,不能注销账户!");
return false;
继续拷贝下面的代码到上面的Java文件中:
}
if (countAssetRecordsUnderCurrentClient > 0) {
System.out.println(Const.PREFIX_LEVEL_SEC + "当前客户存在" + countCardsUnderCurrentClient +
"笔金融产品未赎回,不能注销账户!");
return false;
}
return true;
}
public void showFinancialProducts() {
System.out.println("* * * * * * * * * 理 财 产 品 * * * * * * * * *");
DBUtils.printAllRecords(fp.queryProductList());
System.out.println("* * * * * * * * * * * * * * * * * * * * * * * * * * *");
}
public void buyAsset() {
System.out.println(Const.PREFIX_LEVEL_FIR + "已进入金融产品购买流程,请按提示要求输入相关信息,并按回车");
int clientId = Utils.getInt(Const.PREFIX_LEVEL_SEC + "请输入客户ID: ");
int productId = Utils.getInt(Const.PREFIX_LEVEL_SEC + "请输入金融产品编号: ");
int assetType = 1;
int quantity = Utils.getInt(Const.PREFIX_LEVEL_SEC + "请输入申购金额: ");
int assetId = Utils.getInt(Const.PREFIX_LEVEL_SEC + "请输入资产编号: ");
boolean ret = fa.insertAssetRecord(assetId, clientId, productId, assetType, quantity);
if (ret == Const.SUCCEED) {
System.out.println(Const.PREFIX_LEVEL_SEC + "金融产品购买成功!");
return;
}
System.out.println(Const.PREFIX_LEVEL_SEC + "金融产品购买失败!");
}
public void redeemAsset() {
System.out.println(Const.PREFIX_LEVEL_FIR + "已进入金融产品赎回流程,请按提示要求输入相关信息,并按回车");
int assetId = Utils.getInt(Const.PREFIX_LEVEL_SEC + "请输入资产编号: ");
boolean ret = fa.deleteAssetRecordById(assetId);
if (ret == Const.SUCCEED) {
System.out.println(Const.PREFIX_LEVEL_SEC + "赎回成功!");
继续拷贝下面的代码到上面的Java文件中:
return;
}
System.out.println(Const.PREFIX_LEVEL_SEC + "赎回失败!");
}
}
使用vim命令并按i进入输入模式,将以下代码内容写入FlowControl.java文件中。输入结束后,使用”:wq”保存退出vim编辑。
vim FlowControl.java
package expt.db.finance;
import java.util.Scanner;
public class FlowControl {
Service service;
public FlowControl() {
service = new Service();
}
public void startFlow() {
int choices;
do {
System.out.print("\n"
+ "* * * * * * * * * 操作列表 * * * * * * * * *\n"
+ " -------------------------------------\n"
+ " 1) 客户列表查询 \n"
+ " 2) 客户详细信息查询 \n"
+ " 3) 客户基础信息修改 \n"
+ " 4) 客户开户 \n"
+ " 5) 客户开卡 \n"
+ " 6) 客户销卡 \n"
+ " 7) 客户销户 \n"
+ " -------------------------------------\n"
+ " 8) 理财产品查询 \n"
+ " 9) 理财产品购买 \n"
+ " 10) 理财产品赎回 \n"
+ " -------------------------------------\n"
+ " 0) 退出系统\n"
+ "* * * * * * * * * * * * * * * * * * * * * * *\n");
choices = Utils.getInt(Const.PREFIX_LEVEL_FIR + "请输入需要进行的操作编号: ");
继续拷贝下面的代码到上面的Java文件中:
switch (choices) {
case 1:
service.showClients();
waitForContinue();
break;
case 2:
service.showClientWithCardsAndAssets();
waitForContinue();
break;
case 3:
service.modifyAnAccount();
waitForContinue();
break;
case 4:
service.setUpAnAccount();
waitForContinue();
break;
case 5:
service.setUpAnCard();
waitForContinue();
break;
case 6:
service.closeAnCard();
waitForContinue();
break;
case 7:
service.closeAnAccount();
waitForContinue();
break;
case 8:
service.showFinancialProducts();
waitForContinue();
break;
case 9:
service.buyAsset();
waitForContinue();
break;
case 10:
service.redeemAsset();
waitForContinue();
break;
case 0:
System.out.println(Const.PREFIX_LEVEL_FIR + "已退出!");
break;
继续拷贝下面的代码到上面的Java文件中:
default:
System.out.println(Const.PREFIX_LEVEL_FIR + "当前输入信息无效!");
waitForContinue();
}
}
while(choices!=0);
}
public void waitForContinue() {
Scanner sc = new Scanner(System.in);
System.out.print(Const.PREFIX_LEVEL_FIR + "请按回车继续选择...");
sc.nextLine();
}
}
使用vim命令并按i进入输入模式,将以下代码内容写入launch.java文件中。输入结束后,按ESC按钮后,输入”:wq”保存退出vim编辑。
vim launch.java
package expt.db.finance;
public class launch {
public static void main(String[] args) {
FlowControl flowControl = new FlowControl();
flowControl.startFlow();
}
}
执行以下命令,进行编译:
javac -classpath ../../../ -d . launch.java
执行以下命令,运行对应代码文件
java -p /root/db-dev-cert/libs/gaussdbjdbc.jar expt.db.finance.launch
回显结果输出如下:
回显信息末尾提示输入操作编号,说明系统已经正常启动,此时可以按照提升输入操作编号,并进行相应业务操作。
此时可输入编号“1”来打印当前客户信息,回显信息如下:
五 GaussDB公有云运维管理操作 #
5.1 DN主备切换
- 进入GaussDB控制台,点击实例名,在最下方节点列表中查看当前节点状态 1.
此时主节点为gauss-hccda_root_0
- 点击节点列表下面的“DN主备倒换”按钮 1.
在跳出的对话框中,选择一台备节点,点击“一键输入”, 自动输入YES后,点击“确定”按钮
- 此时各节点会先备份,等待切换后再次观察节点信息, 最后主节点变更为gauss-hccda_root_1 。
主节点变更为gauss-hccda_root_1:
5.2 配置备份策略
- 在左侧选择“备份恢复”,在点击“修改备份策略”
- 修改备份策略,全量备份策略保留天数5天,备份周期为“周六、周日”
- 选择“创建备份”,发起手动备份“backup-hccda”
等待手动备份完成。
5.3 修改参数
- 选择左侧“参数管理”,点击高风险参数 1.
- 设置autoanalyze参数为“on”
- 保存参数设置, 点击“保存”按钮后会弹出确认窗口,在弹出确认窗口单击“一键输入”, 勾选“已确认” 后,点击“确定”按钮保存修改,修改设置大概会1分钟左右生效 。
- 在参数修改历史选项下的记录中,可以查看修改记录状态。
- gsql登录数据库,确认参数已修改 1.
注意:如果上面已做主备切换,xxx.xxx.xx.xx换成主备切换后的新主节点IP
gsql -d postgres -h xxx.xxx.xx.xx -p 8000 -U root -W yourpassword -r
show autoanalyze;
显示为on表示已修改完成。
\q
5.4 系统表查看
- 使用db_dev用户通过gsql登录finance数据库
gsql -d finance -h xxx.xxx.xx.xx -p 8000 -U db_dev -W yourpassword -r
- 设置search_path
set search_path=finance;
- 使用元命令查看finance schema下的表
\d
- 关联系统表查看finance schema下的表
select a.relname,b.nspname from pg_class a join pg_namespace b on a.relnamespace = b.oid where b.nspname = 'finance' and relkind ='r';
- 关联系统表查看finance schema下的索引
select a.relname,b.nspname from pg_class a join pg_namespace b on a.relnamespace = b.oid where b.nspname = 'finance' and relkind ='i';
\q
5.5 权限管控
- 使用root用户通过gsql登录finance数据库
gsql -d finance -h xxx.xxx.xx.xx -p 8000 -U root -W yourpassword -r
- 创建新用户test,“yourpassword"指定密码
create user test identified by 'yourpassword';
- 切换登录用户为test,并尝试查询finance.client表
\c - test
select * from finance.client;
此时报错为无finance schema的访问权限。
- 切换回root用户,并将finance schema的usage权限授予给test
\c - root
grant usage on schema finance to test;
- 切换登录用户为test,再次尝试查询finance.client表
\c - test
select * from finance.client;
此时报错为无client表的访问权限。
- 切换回root用户,并将client表的select权限授予给test
\c - root
grant select on finance.client to test;
- 切换登录用户为test,再次尝试查询finance.client表
\c - test
select * from finance.client limit 1;
此时可正常访问client表。因此进行跨schema的表访问时,需要具备schema的usage权限,以及对应表的select权限。
—————恭喜您完成本实验!—————–