跳到主要内容

HCCDA-GaussDB-实验练习-05 金融场景下GaussDB Java编程综合实践

·11762 字·24 分钟

金融场景下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 基础环境配置

  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
  1. 执行以下命令创建代码根目录,并进入该新创建目录。
mkdir /root/db-dev-cert
cd /root/db-dev-cert
  1. 在当前路径下,执行以下命令,创建代码结构目录。
mkdir libs

提示:libs后续用来存放第三方运行依赖库,basic目录下存放本次实验涉及的具体代码。

  1. 执行以下命令,获取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/

  1. 执行以下命令,下载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

回显结果输出如下:

  1. 在当前路径下,执行以下命令,创建综合实验代码结构目录。
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主备切换

  1. 进入GaussDB控制台,点击实例名,在最下方节点列表中查看当前节点状态 1.

此时主节点为gauss-hccda_root_0

  1. 点击节点列表下面的“DN主备倒换”按钮 1.

在跳出的对话框中,选择一台备节点,点击“一键输入”, 自动输入YES后,点击“确定”按钮

  1. 此时各节点会先备份,等待切换后再次观察节点信息, 最后主节点变更为gauss-hccda_root_1 。

主节点变更为gauss-hccda_root_1:

5.2 配置备份策略

  1. 在左侧选择“备份恢复”,在点击“修改备份策略”

  1. 修改备份策略,全量备份策略保留天数5天,备份周期为“周六、周日”

  1. 选择“创建备份”,发起手动备份“backup-hccda”

等待手动备份完成。

5.3 修改参数

  1. 选择左侧“参数管理”,点击高风险参数 1.
  2. 设置autoanalyze参数为“on”

  1. 保存参数设置, 点击“保存”按钮后会弹出确认窗口,在弹出确认窗口单击“一键输入”, 勾选“已确认” 后,点击“确定”按钮保存修改,修改设置大概会1分钟左右生效 。

  1. 在参数修改历史选项下的记录中,可以查看修改记录状态。

  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 系统表查看

  1. 使用db_dev用户通过gsql登录finance数据库
gsql -d finance -h xxx.xxx.xx.xx -p 8000 -U db_dev -W yourpassword -r
  1. 设置search_path
set search_path=finance;
  1. 使用元命令查看finance schema下的表
\d
  1. 关联系统表查看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';
  1. 关联系统表查看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 权限管控

  1. 使用root用户通过gsql登录finance数据库
gsql -d finance -h xxx.xxx.xx.xx -p 8000 -U root -W yourpassword -r
  1. 创建新用户test,“yourpassword"指定密码
create user test identified by 'yourpassword';
  1. 切换登录用户为test,并尝试查询finance.client表
\c - test
select * from finance.client;

此时报错为无finance schema的访问权限。

  1. 切换回root用户,并将finance schema的usage权限授予给test
\c - root
grant usage on schema finance to test;

  1. 切换登录用户为test,再次尝试查询finance.client表
\c - test
select * from finance.client;

此时报错为无client表的访问权限。

  1. 切换回root用户,并将client表的select权限授予给test
\c - root
grant select on finance.client to test;

  1. 切换登录用户为test,再次尝试查询finance.client表
\c - test
select * from finance.client limit 1;

此时可正常访问client表。因此进行跨schema的表访问时,需要具备schema的usage权限,以及对应表的select权限。

—————恭喜您完成本实验!—————–