跳到主要内容

HCCDA-GaussDB-实验练习-03 Java对数据库基本操作

·8726 字·18 分钟

Java对数据库基本操作

本实验指导用户使用JDBC实现GaussDB数据库基础操作。

1.基础环境配置 #

1.1 创建GaussDB实例(预计15-20分钟) #

注意:确保区域选择的是北京四, 否则会看到权限错误信息,无法购买数据库。

  1. 进入云数据库GaussDB服务,点击左侧的【服务列表】,选择其中【数据库】下的【云数据库GaussDB】。

  1. 进入云数据库GaussDB,点击页面右上角的【购买数据库实例】按钮。

  1. 进入购买页后,根据以下参数信息购买数据库。

  2. 主要参数如下,其他请保持默认。

  3. • 计费模式:选择【按需计费】

  4. • 区域:默认的【华北-北京四】

  5. • 实例名称:可以设置为【gauss-hccda】

  6. • 产品类型:基础版

  7. • 数据库引擎版本:选择最新版即可

  8. • 实例类型:集中式

  9. • 部署形态:1主2备

  10. • 性能规格: 通用型(1:4) | 4 vCPUs | 16 GB

  11. 说明:如果通用型卖完了, 请选择其它可用的规格,如 独享型(1:4) | 4 vCPUs | 16 GB 等。

  12. • 存储类型、存储空间、磁盘加密保持默认

  13. • 虚拟私有云:选择【vpc-hccda】, 【subnet-hccda】

  14. • 安全组:选择【sg-hccda】

  15. • 管理员密码:设置符合安全要求的root用户密码

  16. 确认信息无误后,点击【提交】。

注意:GaussDB实例创建需要20分钟,请耐心等待,可以先去执行其他跟数据库无关的操作。

1.2 创建用户及相应数据库和模式 #

创建用户及相应数据库和模式,用于程序后续配置使用。按下图所示,先进入数据库列表并点击登录对应数据库。

在实例登录页面,选择“自定义登录”页签,在节点信息中,选择角色为“master”的节点, 填写购买GaussDB数据库时填写的密码,单击“测试连接”,如果显示“连接成功”,则可以成功登录实例;勾选“记住密码” 和 选择“SQL执行记录”,最后单击“登录”按钮登录到数据库。

按下图所示,进入角色管理页面,点击“新建角色”按钮,进入角色管理页面。

在新建角色页面,输入角色名称 db_dev,密码设置为 XXXXXX ,此处注意一定勾

选“可以登录”和“可以创建数据库”两个选项,然后点击“保存”按钮。

相关参数:

角色名:db_dev

可以登录:勾选

密码:XXXXXX

可以创建数据库:勾选

按图所示创建 db_dev 角色,密码设置为 XXXXXX,此处注意一定勾选“可以登录”和“可以创建数据库”两个选项。

点击保存后将弹出“SQL预览”窗口,点击确定即可。

完成创建后,将当前连接切换为新创建的用户db_dev,如下图所示,点击“切换连接”按钮。

在弹出窗口,选择“自定义登录”输入刚创建的角色信息和密码,勾选“记住密码”和“命令执行记录”,并点击“登录”。

登录后,点击“新建数据库”

在弹出窗口中,按图示输入参数创建“db_test”数据库。

点击数据库链接“db_test”, 进入库管理页面。

按图所示,点击“新建Schema”,创建“schema_test”模式。

1.3 安装JDK #

至此,数据实例已配置完成,下面进行ECS开发环境基础配置。

首先进入实验室桌面,双击打开【Xfce终端】(请将终端窗口最大化),使用ssh命令远程登录ecs服务器。

ssh root@EIP

相关参数:

公网IP:(以实际分配为准),进入华为云控制台获取ECS的EIP

端口:22

用户名:root (以实际分配为准)

密码:xxxxxx (以实际分配为准)

连接成功,进入终端。

执行以下命令创建代码根目录,并进入该新创建目录。

mkdir /root/db-dev-cert
cd /root/db-dev-cert

在当前路径下,执行以下命令,创建代码结构目录。

mkdir libs
mkdir -p src/expt/db/basic

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

执行以下命令,下载jdbc驱动,并存放于 libs目录下。

cd /root/db-dev-cert/libs
wget https://repo.huaweicloud.com/repository/maven/com/huaweicloud/gaussdb/opengaussjdbc/503.2.T35/opengaussjdbc-503.2.T35.jar

执行以下命令,下载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.4 配置数据库配置文件 #

配置数据库配置文件(dbconfig.properties):

mkdir /root/db-dev-cert/config
cd /root/db-dev-cert/config
vim dbconfig.properties

输入正确的配置值:

jdbc_driver=com.huawei.opengauss.jdbc.Driver
db_url=jdbc:opengauss://192.168.0.71:8000/db_test
db_user=db_dev
db_password=XXXXXX
currentschema=schema_test

备注: jdbc_driver是驱动的类名,db_url是连接数据库的URL,使用正确的值替换数据库IP, 数据库端口号,数据库名称,如”192.168.0.71:8000” 需修改为当前实际所使用数据库对应的主节点的IP地址(如果不设置成主节点的IP,会导致不能创建表格)和端口;db_test为之前所创建的数据库名称,若未按照之前实验参数创建,需对应匹配修改为真实数据库名称, db_user是连接数据库的用户,db_password是连接数据库的用户对应的密码,currentschema是当前数据库的模式名称。

2.连接数据库 #

使用程序对数据库进行操作之前,需要让程序先建立对数据的连接。本节将使用程序对数据库连接进行实验,并创建一个公共的工具类dbUtils,为后续实践打下基础,方便直接调用。

执行以下命令,在指定目录创建dbUtils.java文件。

cd /root/db-dev-cert/src/expt/db/basic
touch dbUtils.java

使用vi命令,将以下代码内容写入dbUtils.java文件中。

package expt.db.basic;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.Properties;

public class dbUtils {
    public static Connection getConnect(String driver, String db_conn_url) {
        Connection conn = null;

        try {
            Class.forName(driver);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }

        // open connecting
        System.out.println("connecting database...");
        try {
            System.out.println("connection url is: " + db_conn_url);
            conn = DriverManager.getConnection(db_conn_url);
            System.out.println("connection successfully!");
            return conn;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    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 Properties loadProperties() {
                InputStream input = null;
                 Properties prop = new Properties();
                try {
                        input = new FileInputStream("/root/db-dev-cert/config/dbconfig.properties");
                        // 加载配置文件
                        prop.load(input);
                } catch (IOException ex) {
                        ex.printStackTrace();
                } finally {
                        if (input != null) {
                                try {
                                        input.close();
                                } catch (IOException e) {
                                        e.printStackTrace();
                                }
                        }
                }
                return prop;
        }
    public static void printAllRecords(ResultSet rs) {
        try {
            ResultSetMetaData metaData = rs.getMetaData();
            for (int i = 0; i < metaData.getColumnCount(); i++) {
                System.out.print(metaData.getColumnName(i + 1) + "\t");
            }
            System.out.println();

            while (rs.next()) {
                for (int i = 0; i < metaData.getColumnCount(); i++) {
                    System.out.print(rs.getString(i + 1) + "\t");
                }
                System.out.println();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void printOneRecord(ResultSet rs) {
        try {
            ResultSetMetaData metaData = rs.getMetaData();
            for (int i = 0; i < metaData.getColumnCount(); i++) {
                System.out.print(metaData.getColumnName(i + 1) + "\t");
            }
            System.out.println();

            for (int i = 0; i < metaData.getColumnCount(); i++) {
                System.out.print(rs.getString(i + 1) + "\t");
            }
            System.out.println("\ncurrent row number: " + rs.getRow() + "\n");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

执行以下命令,在指定目录创建exptConnection.java文件

cd /root/db-dev-cert/src/expt/db/basic
touch exptConnection.java

使用vi命令,将以下代码内容写入exptConnection.java文件中。输入结束后,使用”:wq”保存退出vim编辑。

 package expt.db.basic;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.Properties;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public class exptConnection {
 
        
        public static void main(String[] args) {
                getConnect();
        }

        public static Connection getConnect() {
//装载配置文件。
Properties prop = dbUtils.loadProperties();
                Connection conn = null;
            //读取配置文件中的属性
                String jdbcdriver = prop.getProperty("jdbc_driver");
                String dburl = prop.getProperty("db_url");
                String user = prop.getProperty("db_user");
                String password = prop.getProperty("db_password");
            String connection_url = dburl + "?user=" + user + "&password=" + password; 
                //打印连接URL
System.out.println("connection_url: " + connection_url);
                /* 驱动注册 */ 
                try {
                        Class.forName(jdbcdriver);
                } catch (Exception e) {
                        e.printStackTrace();
                        return null;
                }
                /* 连接数据库 */
                System.out.println("connecting database...");
                try {
                        conn = DriverManager.getConnection(connection_url);
                        System.out.println("connection successfully!");
                        return conn;
                } catch (Exception e) {
                        e.printStackTrace();
                        return null;
                }
        }
}

注:需要确保配置文件(/root/db-dev-cert/config/dbconfig.properties)已经存在,而且配置值是正确的。

执行以下命令,进行编译:

javac -classpath ../../../ -d . exptConnection.java

编译完成后,会在当前目录下生编译成class数据文件及对应目录结构,参考如下:

yum -y install tree
tree

执行以下命令,运行对应代码文件

java -p /root/db-dev-cert/libs/opengaussjdbc-503.2.T35.jar expt.db.basic.exptConnection

回显结果输出如下:

回显信息末尾出现”connection successfully”,说明依据当前参数已正常连接数据库。

3.创建数据表 #

上一节中完成了对数据库的连接,使得程序能够对数据库实例建立连接。基于此连接建立的基础上,可进行数据库表创建的操作实验。本小节会将该连接代码单独抽取出来,方便后续实验可以重复使用,从而避免每次在编写相关操作代码之前,都拷贝一份连接代码。

执行以下命令,创建exptCreateTable.java文件。

cd /root/db-dev-cert/src/expt/db/basic
touch exptCreateTable.java

使用vi命令,将以下代码内容写入exptCreateTable.java文件中。输入结束后,使用”:wq”保存退出vi编辑。

package expt.db.basic;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

public class exptCreateTable {
        public static void main(String[] args) throws SQLException {
                //装载配置文件。
                Properties prop = dbUtils.loadProperties();
                //读取配置文件中的属性
                String jdbcdriver = prop.getProperty("jdbc_driver");
                String dburl = prop.getProperty("db_url");
                String user = prop.getProperty("db_user");
                String password = prop.getProperty("db_password");

                String conn_url = dburl + "?user=" + user + "&password=" + password + "&currentSchema=schema_test";
                Connection conn = dbUtils.getConnect(jdbcdriver, conn_url);

                Statement statement = conn.createStatement();
                statement.execute(
                                "create table test_table (id int, name varchar(10), destination varchar(20), uuid varchar(36))");
                System.out.println("execute successfully!");
                dbUtils.closeConnect(conn);
        }
}
javac -classpath ../../../ -d . exptCreateTable.java

执行以下命令,运行对应代码文件:

java -p /root/db-dev-cert/libs/opengaussjdbc-503.2.T35.jar expt.db.basic.exptCreateTable

回显结果输出如下:

回显信息末尾出现”excute successfully!”,说明正常连接数据库,并成功创建数据表。

4.增删查改数据 #

上一节中完成了对数据库表的创建,现在在上一节的基础上,使用程序在表中进行插入数据,查询并打印数据,修改数据,删除数据的实验。

执行以下命令,创建exptInsert.java文件。

cd /root/db-dev-cert/src/expt/db/basic
touch ExpDataOperation.java

使用vi命令,将以下代码内容写入ExpDataOperation.java文件中。

package expt.db.basic;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

public class ExpDataOperation {
 
                static Properties prop = new Properties();
                static void loadProperties() {
                        InputStream input = null;
                        try {
                                input = new FileInputStream("/root/db-dev-cert/config/dbconfig.properties");
                                // 加载配置文件
                                prop.load(input);
                        } catch (IOException ex) {
                                ex.printStackTrace();
                        } finally {
                                if (input != null) {
                                        try {
                                                input.close();
                                        } catch (IOException e) {
                                                e.printStackTrace();
                                        }
                                }
                        }
                }            
            public static void main(String[] args) throws SQLException {
                    
                        //装载配置文件。
                        loadProperties();
                        //读取配置文件中的属性
                        String jdbcdriver = prop.getProperty("jdbc_driver");
                        String dburl = prop.getProperty("db_url");
                        String user = prop.getProperty("db_user");
                        String password = prop.getProperty("db_password");

                        String conn_url = dburl + "?user=" + user + "&password=" + password + "&currentSchema=schema_test";
                        System.out.println("the connection url:" + conn_url);
                        Connection conn = dbUtils.getConnect(jdbcdriver, conn_url);
                        /* 插入一条数据 */ 
                Statement statement = conn.createStatement();
                statement.execute("INSERT INTO test_table(id, name, destination, uuid) "
                        + "values (2, 'zhangsan', 'hangzhou', 123456789)");
                System.out.println("插入行数: "+statement.getUpdateCount());
                
                /* 查询并打印数据 */
                ResultSet resultSet = null;
                PreparedStatement queryStatement=conn.prepareStatement("select * from test_table where id=?;");
                queryStatement.setObject(1,2);
                resultSet = queryStatement.executeQuery();
                dbUtils.printAllRecords(resultSet);

                /* 修改一条数据 */ 
                PreparedStatement updateStatement=conn.prepareStatement("update test_table set name=? where id=?");
                updateStatement.setObject(1, "wangwu");
                updateStatement.setObject(2, 2);
                updateStatement.execute();
                System.out.println("修改行数:"+updateStatement.getUpdateCount());

                /* 删除一条数据 */ 
                PreparedStatement deleteStatement = conn.prepareStatement("delete from test_table where id = ?");
                deleteStatement.setObject(1, 2);
                deleteStatement.execute();
                System.out.println("删除行数:"+deleteStatement.getUpdateCount());

                dbUtils.closeConnect(conn);
            }

}

执行以下命令,进行编译:

javac -classpath ../../../ -d . ExpDataOperation.java

执行以下命令,运行对应代码文件:

java -p /root/db-dev-cert/libs/opengaussjdbc-503.2.T35.jar expt.db.basic.ExpDataOperation

回显结果输出如下:

回显信息末尾出现"插入行数:1",说明程序中1条数据成功插入表中。

回显信息打印出插入的数据(2,zhangsan,hangzhou),说明查询功能正常。

回显信息末尾出现"修改行数:1",说明程序成功修改1条数据。

回显信息末尾出现"删除行数:1",说明程序成功删除1条数据。

5.批量插入数据 #

在实际场景中,会遇到大量的数据需要入库,此时若是按照之前的方式一次一条插入,将会非常耗时,同时消耗数据库性能,影响其它业务正常运行。因此本节进行批量插入的实验,同时会将和非批量插入方式做一个对比试验,从实际运行数据上来验证批量插入的性能提升。

执行以下命令,创建exptBatchInsert.java文件。

cd /root/db-dev-cert/src/expt/db/basic
touch exptBatchInsert.java

使用vim命令,将以下代码内容写入exptBatchInsert.java文件中。输入结束后,使用”:wq”保存退出vim编辑。

package expt.db.basic;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Properties;
import java.util.UUID;

public class exptBatchInsert {
    static String JDBC_DRIVER = "";
    static String conn_url = "";
    
    public static void main(String[] args) throws SQLException {
        int current;
                //装载配置文件。
        Properties prop = dbUtils.loadProperties();
                //读取配置文件中的属性
                JDBC_DRIVER = prop.getProperty("jdbc_driver");
                String dburl = prop.getProperty("db_url");
                String user = prop.getProperty("db_user");
                String password = prop.getProperty("db_password");
                String currentSchema = prop.getProperty("currentschema", "schema_test") ;
                conn_url = dburl + "?user=" + user + "&password=" + password + "&currentSchema=" + currentSchema;
                System.out.println("the connection url:" + conn_url);
                 
        current = insertRecordOnceATime(1, 1000);
        insertRecordBatch(current, 1000);
    }

    public static int insertRecordOnceATime(int begin, int count) {
        PreparedStatement preparedStatement;
        int index = begin;

        try {
            Connection conn = dbUtils.getConnect(JDBC_DRIVER, conn_url);
            conn.setAutoCommit(true);

            String targetQuery = "INSERT INTO test_table(id, name, destination, uuid) VALUES(?, ?, ?, ?)";
            preparedStatement = conn.prepareStatement(targetQuery);
            long start = System.currentTimeMillis();

            for( ; index < begin+count; index++) {
                preparedStatement.setInt(1, index);
                preparedStatement.setString(2, "name-"+index);
                preparedStatement.setString(3, "destination-"+index);
                preparedStatement.setString(4, UUID.randomUUID().toString());
                long startInternal = System.currentTimeMillis();
                preparedStatement.executeUpdate();
                System.out.println("each transaction time taken = " + (System.currentTimeMillis() - startInternal) + " ms");
            }

            long end = System.currentTimeMillis();
            System.out.println("total time taken = " + (end - start) + " ms");
            System.out.println("avg total time taken = " + (end - start)/ count + " ms");

            preparedStatement.close();
            dbUtils.closeConnect(conn);

        } catch (SQLException ex) {
            System.err.println("SQLException information");
            while (ex != null) {
                System.err.println("Error msg: " + ex.getMessage());
                ex = ex.getNextException();
            }
        }
        return index;
    }

    public static void insertRecordBatch(int begin, int count) {
        PreparedStatement preparedStatement;
        int index = begin;

        try {
            Connection conn = dbUtils.getConnect(JDBC_DRIVER, conn_url);
            conn.setAutoCommit(true);

            String targetQuery = "INSERT INTO test_table(id, name, destination, uuid) VALUES(?, ?, ?, ?)";
            preparedStatement = conn.prepareStatement(targetQuery);

            for( ; index < begin+count; index++) {
                preparedStatement.setInt(1, index);
                preparedStatement.setString(2, "name-"+index);
                preparedStatement.setString(3, "destination-"+index);
                preparedStatement.setString(4, UUID.randomUUID().toString());
                preparedStatement.addBatch();
            }

            long start = System.currentTimeMillis();
            int[] inserted = preparedStatement.executeBatch();
            long end = System.currentTimeMillis();

            System.out.println("total time taken to insert the batch = " + (end - start) + " ms");
            System.out.println("total time taken = " + (end - start)/count + " s");
            preparedStatement.close();
            dbUtils.closeConnect(conn);
            System.out.println("row influence number is: " + inserted.length);
        } catch (SQLException ex) {
            System.err.println("SQLException information");
            while (ex != null) {
                System.err.println("Error msg: " + ex.getMessage());
                ex = ex.getNextException();
            }
            throw new RuntimeException("Error");
        }
    }
}

执行以下命令,进行编译:

javac -classpath ../../../ -d . exptBatchInsert.java

执行以下命令,运行对应代码文件:

java -p /root/db-dev-cert/libs/opengaussjdbc-503.2.T35.jar expt.db.basic.exptBatchInsert

回显结果输出如下:

从回显信息中的总耗时可以看出,在1000数据量的情况下,一次一条数据的插入方式的总耗时,比批量插入耗时高出两个数量级。

6.添加游标数据 #

上一节中我们完成了数据库表批量数据的插入,现在继续在上一节产生的数据基础上,来完成本节数据游标实验。

执行以下命令,创建exptCursor.java文件。

cd /root/db-dev-cert/src/expt/db/basic
touch exptCursor.java

使用vi命令,将以下代码内容写入exptCursor.java文件中。输入结束后,使用”:wq”保存退出vi编辑。

package expt.db.basic;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;

public class exptCursor {
 
    public static void main(String[] args) throws SQLException {
        PreparedStatement preparedStatement;

        try {
                    //装载配置文件。
                    Properties prop = dbUtils.loadProperties();
                    //读取配置文件中的属性
                    String jdbcdriver = prop.getProperty("jdbc_driver");
                    String dburl = prop.getProperty("db_url");
                    String user = prop.getProperty("db_user");
                    String password = prop.getProperty("db_password");
                    String conn_url = dburl + "?user=" + user + "&password=" + password + "&currentSchema=schema_test";
                    System.out.println("the connection url:" + conn_url);                
            Connection conn = dbUtils.getConnect(jdbcdriver, conn_url);

            String targetQuery = "select * from test_table";
            preparedStatement = conn.prepareStatement(targetQuery, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
            ResultSet resultSet = preparedStatement.executeQuery();

            resultSet.next();
            dbUtils.printOneRecord(resultSet);

            resultSet.last();
            dbUtils.printOneRecord(resultSet);

            resultSet.previous();
            dbUtils.printOneRecord(resultSet);

            resultSet.first();
            dbUtils.printOneRecord(resultSet);

            System.out.println("is before first: " + resultSet.isBeforeFirst());
            resultSet.afterLast();
            System.out.println("is after last: " + resultSet.isAfterLast());
            resultSet.beforeFirst();
            System.out.println("is before first: " + resultSet.isBeforeFirst());
            resultSet.next();
            dbUtils.printOneRecord(resultSet);

            resultSet.absolute(4);
            dbUtils.printOneRecord(resultSet);
            resultSet.relative(1);
            dbUtils.printOneRecord(resultSet);

            resultSet.absolute(-2);
            dbUtils.printOneRecord(resultSet);
            resultSet.relative(-1);
            dbUtils.printOneRecord(resultSet);

            preparedStatement.close();
            dbUtils.closeConnect(conn);

        } catch (SQLException ex) {
            System.err.println("SQLException information");
            while (ex != null) {
                System.err.println("Error msg: " + ex.getMessage());
                ex = ex.getNextException();
            }
        }
    }
}

执行以下命令,进行编译:

javac -classpath ../../../ -d . exptCursor.java

执行以下命令,运行对应代码文件:

java -p /root/db-dev-cert/libs/opengaussjdbc-503.2.T35.jar expt.db.basic.exptCursor

回显结果输出如下:

从回显打印出的数据信息可以看出,与程序中对应游标各种使用产生效果是一一对应的。同时通过回显的结果,也可以更好的理解游标的使用。

7.分页查询数据 #

上一节中我们完成了对数据库表的创建,现在仍然在批量插入所产生数据的基础上,使用程序进行分页查询实验。

执行以下命令,创建exptPagination.java文件。

cd /root/db-dev-cert/src/expt/db/basic
touch exptPagination.java

使用vi命令,将以下代码内容写入exptPagination.java文件中。输入结束后,使用”:wq”保存退出vi编辑。

package expt.db.basic;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;

public class exptPagination {
 
        public static void main(String[] args) throws SQLException {
                int pageNumber = 1; // from 1 to N
                int pageSize = 3;
                //装载配置文件。
                Properties prop = dbUtils.loadProperties();
                //读取配置文件中的属性
                String jdbcdriver = prop.getProperty("jdbc_driver");
                String dburl = prop.getProperty("db_url");
                String user = prop.getProperty("db_user");
                String password = prop.getProperty("db_password");
                String conn_url = dburl + "?user=" + user + "&password=" + password + "&currentSchema=schema_test";
                System.out.println("the connection url:" + conn_url);                   
                Connection conn = dbUtils.getConnect(jdbcdriver, conn_url);
                if (args.length == 2) {
                        pageNumber = Integer.parseInt(args[0]);
                        pageSize = Integer.parseInt(args[1]);
                }

                pageQueryByCursor(conn, pageNumber, pageSize);
                dbUtils.closeConnect(conn);
        }

        public static void pageQueryByCursor(Connection conn, int pageNumber, int pageSize) {
                PreparedStatement preparedStatement;

                int startNo = (pageNumber - 1) * pageSize;
                int endNo = pageNumber * pageSize;

                String targetQuery = "select * from test_table";

                try {
                        preparedStatement = conn.prepareStatement(targetQuery, ResultSet.TYPE_SCROLL_INSENSITIVE,
                                        ResultSet.CONCUR_READ_ONLY);
                        preparedStatement.setMaxRows(endNo);
                        ResultSet resultSet = preparedStatement.executeQuery();

                        resultSet.beforeFirst();
                        resultSet.relative(startNo);

                        dbUtils.printAllRecords(resultSet);
                        preparedStatement.close();
                } catch (SQLException ex) {
                        System.err.println("SQLException information");
                        while (ex != null) {
                                System.err.println("Error msg: " + ex.getMessage());
                                ex = ex.getNextException();
                        }
                }
        }
}

执行以下命令,进行编译:

javac -classpath ../../../ -d . exptPagination.java

执行以下命令,运行对应代码文件:

java -p /root/db-dev-cert/libs/opengaussjdbc-503.2.T35.jar expt.db.basic.exptPagination

回显结果输出如下:

从回显信息中可以看到,默认情况下,程序以每页三条记录规格,输出了第一页的记录内容。

若想以每页10条记录规格,输出第100页的内容,可在程序执行时指定页规格和页号两个参数。

执行以下命令,运行对应代码文件:

java -p /root/db-dev-cert/libs/opengaussjdbc-503.2.T35.jar expt.db.basic.exptPagination 100 10

回显结果输出如下:

分页的方式不仅可以使用游标实现,还可以使用SQL语句自身实现,其实现的函数示例代码如下,可以将其替换先前游标实现内容,并予以尝试。

 public static void pageQueryByLimitAndOffset(Connection conn, int pageNumber, int pageSize) 
{
        PreparedStatement preparedStatement;
        String targetQuery = "select * from test_table limit ?, ?";
        try {
            preparedStatement = conn.prepareStatement(targetQuery);
            preparedStatement.setInt(1, (pageNumber-1)*pageSize);
            preparedStatement.setInt(2, pageSize);
            ResultSet resultSet = preparedStatement.executeQuery();

            dbUtils.printAllRecords(resultSet);
            preparedStatement.close();
        } catch (SQLException ex) {
            System.err.println("SQLException information");
            while (ex != null) {
                System.err.println("Error msg: " + ex.getMessage());
                ex = ex.getNextException();
            }
        }
    }

8.通过Mybatis连接数据库 #

在 DAS上选择数据库(db_test) 和 模式(schema_test),然后执行下面的SQL创建商品表goods并插入数据:

CREATE TABLE goods (
     userid INTEGER PRIMARY KEY,
        goodsid INTEGER,
        deliveryTime date,
         title VARCHAR(100),
         description VARCHAR(100),
         category VARCHAR(20),
       originalPrice FLOAT(3),
        price FLOAT(3)
) ;

8.1 准备数据

创建商品表如下图:

执行成功后的日志:

在DAS上执行下面的SQL插入数据:

INSERT INTO goods(goodsid, userid, deliveryTime, title, description, category, originalPrice, price)
values (1,1,'2024-06-21','手机','华为手机','电子产品',5000,6000) ;
INSERT INTO goods(goodsid, userid, deliveryTime, title, description, category, originalPrice, price)
values (2,2,'2024-06-21','手机','小米手机','电子产品',1000,2000) ;
INSERT INTO goods(goodsid, userid, deliveryTime, title, description, category, originalPrice, price)
values (3,3,'2024-06-22','热水器','美的热水器','电器',3000,4000) ;
INSERT INTO goods(goodsid, userid, deliveryTime, title, description, category, originalPrice, price)
values (4,4,'2024-06-26','苹果','红苹果','水果',5,10) ;
INSERT INTO goods(goodsid, userid, deliveryTime, title, description, category, originalPrice, price)
values (5,5,'2024-06-28','桃子','水密桃','水果',10,15) ;
INSERT INTO goods(goodsid, userid, deliveryTime, title, description, category, originalPrice, price)
values (6,6,'2024-06-29','杯子','水杯','日用品',15,30);
INSERT INTO goods(goodsid, userid, deliveryTime, title, description, category, originalPrice, price)
values (7,7,'2024-06-30','空调','格力空调','电器',3000,5000);

插入成功如下图:

8.2 安装Maven

  1. 在ECS服务器上执行下面的命令下载并安装maven
mkdir -p /root/db-dev-cert/maven
cd /root/db-dev-cert/maven
wget https://sandbox-experiment-files.obs.cn-north-4.myhuaweicloud.com:443/lab2024/hccdp/HCCDP/apache-maven-3.6.0-bin.tar.gz
tar -zxvf apache-maven-3.6.0-bin.tar.gz
ln -s /root/db-dev-cert/maven/apache-maven-3.6.0/bin/mvn /usr/local/bin/mvn

2)执行下面的命令检查maven 是否安装成功 。

mvn -version

备注:确保安装了JDK。

  1. 执行下面的命令修改maven的配置settings.xml,设置本地库目录和华为仓库。
cd /root/db-dev-cert/maven/apache-maven-3.6.0/conf
vim settings.xml

拷贝下面的配置到settings.xml去设置本地目录(确保ECS服务器上存在本地目录(/root/db-dev-cert/libs))

<localRepository>/root/db-dev-cert/libs</localRepository>

设置华为仓库:

a)拷贝下面的配置到settings.xml的节点下面去增加镜像。

<mirror>
      <id>huaweicloud</id>
      <mirrorOf>*,!HuaweiCloudSDK</mirrorOf>
      <url>https://repo.huaweicloud.com/repository/maven/</url>
    </mirror>

b)拷贝下面的配置到settings.xml的< profiles>下面增加profile, 然后使用”:wq”保存settings.xml退出vim编辑。

<profile>
      <id>MyProfile</id>
      <repositories>
        <repository>
          <id>HuaweiCloudSDK</id>
          <url>https://repo.huaweicloud.com/repository/maven/huaweicloudsdk/</url>
          <releases>
            <enabled>true</enabled>
          </releases>
          <snapshots>
            <enabled>false</enabled>
          </snapshots>
        </repository>
      </repositories>
    </profile>

8.3 书写代码

1) 创建接口类GoodsMapper。

用来进行数据库操作

mkdir -p /root/db-dev-cert/mybatisdemo/src/main/java/com/huawei/guassdb/mapper
cd /root/db-dev-cert/mybatisdemo/src/main/java/com/huawei/guassdb/mapper
vim GoodsMapper.java

输入下面的内容到文件里:

package com.huawei.guassdb.mapper;
import java.util.List;
import com.huawei.guassdb.pojo.Goods;
public interface GoodsMapper {
        Goods selectGoodsByUserId(int goodsid);
        List<Goods> getAllGoods();
}

2)创建Goods_Mapper.xml文件。

用来配置SQL与JAVA API的映射,namespace的名称必需与第1步的GoodsMapper名称一样, select节点的id属性与GoodsMapper的方法同名。

执行下面的命令,去创建文件:

cd /root/db-dev-cert/mybatisdemo/src/main/java/com/huawei/guassdb/mapper
vim Goods_Mapper.xml

输入"i"命令插入下面的内容到文件里,然后输入":wq"保存退出:

<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.huawei.guassdb.mapper.GoodsMapper"><select id="selectGoodsByUserId" resultType="com.huawei.guassdb.pojo.Goods" parameterType="int">
        select  * FROM goods WHERE userid = #{userid}</select><select id="getAllGoods" resultType="com.huawei.guassdb.pojo.Goods" >
        select  * FROM goods 
    </select></mapper>

3) 创建Goods类。

执行下面的命令,去创建文件:

mkdir /root/db-dev-cert/mybatisdemo/src/main/java/com/huawei/guassdb/pojo
cd /root/db-dev-cert/mybatisdemo/src/main/java/com/huawei/guassdb/pojo
vim Goods.java

输入"i"命令插入下面的内容到文件里,然后输入":wq"保存退出:

package com.huawei.guassdb.pojo;
public class Goods {
        private long goodsid;
        private long userid;
        private String title;
        private String deliveryTime;
        private String description;
        private String category ;
        private float originalPrice;
        private float price;
        public long getGoodsid() {
                return goodsid;
        }
        public void setGoodsid(long goodsid) {
                this.goodsid = goodsid;
        }

        public long getUserid() {
                return userid;
        }
        public void setUserid(long userid) {
                this.userid = userid;
        }
        public String getDescription() {
                return description;
        }
        public void setDescription(String description) {
                this.description = description;
        }
        public String getCategory() {
                return category;
        }
        public void setCategory(String category) {
                this.category = category;
        }
        public float getOriginalPrice() {
                return originalPrice;
        }
        public void setOriginalPrice(float originalPrice) {
                this.originalPrice = originalPrice;
        }
        public float getPrice() {
                return price;
        }
        public void setPrice(float price) {
                this.price = price;
        }
        public long getGoodsId() {
                return goodsid;
        }
        public void setGoodsId(long goodsid) {
                this.goodsid = goodsid;
        }        
        public void setTitle(String title) {
                this.title = title;
        }
        public String getTitle() {
                return this.title;
        }
        public String getDeliveryTime() {
                return deliveryTime;
        }

        public void setDeliveryTime(String deliveryTime) {
                this.deliveryTime = deliveryTime;
        }
        @Override
        public String toString() {
                return "Goods{" + "用户账号=" + userid + ", 产品='" + title + '\'' +", 商品号='" + goodsid + '\'' +
                ", 产品描述='" + description + "\', 产品类别='" + category +  '\'' +
                ", 出厂价格='" + originalPrice + "\', 市场价格='" + price +  '\'' +
                "}";
        }
}

4)创建配置文件mybatis\mybatis-config.xml

mybatis的核心配置文件,配置数据库连接相关的配置项,以及Mappter等。

执行下面的命令,去创建文件:

mkdir /root/db-dev-cert/mybatisdemo/src/main/java/mybatis
cd /root/db-dev-cert/mybatisdemo/src/main/java/mybatis
vim mybatis-config.xml

输入"i"命令插入下面的内容到文件里,然后输入":wq"保存退出(需要替换正确的数据库IP,数据库端口号, 数据库名称,schema名称,用户名和密码):

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
  <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.huawei.opengauss.jdbc.Driver"/>
                <property name="url" value="jdbc:opengauss://192.168.0.168:8000/db_test?currentSchema=schema_test"/>
                <property name="username" value="db_dev"/>
                <property name="password" value="XXXXXX"/>
            </dataSource>
        </environment>
    </environments>        
    <mappers>
        <mapper resource="com/huawei/guassdb/mapper/Goods_Mapper.xml"/>
    </mappers>
</configuration>

备注:如果修改了本配置文件的值,需要用maven重新编译构建确保配置生效。

5)创建MyBatisUtil.java文件

用来建立数据库会话SqlSession,用它在数据库执行SQL命令。

执行下面的命令,去创建文件:

mkdir /root/db-dev-cert/mybatisdemo/src/main/java/com/huawei/guassdb/util
cd /root/db-dev-cert/mybatisdemo/src/main/java/com/huawei/guassdb/util
vim MyBatisUtil.java

输入"i"命令插入下面的内容到文件里,然后输入":wq"保存退出:

package com.huawei.guassdb.util;
import java.io.IOException;
import java.io.InputStream;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

public class MyBatisUtil {

        private static SqlSessionFactory sqlSessionFactory;
         
    static {
        try {
            String resource = "mybatis/mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public static SqlSession getSqlSession() {
        return sqlSessionFactory.openSession();
    }
}

6)创建TestMyBatis类

Main入口类,用来测试和打印数据在屏幕上。

执行下面的命令,去创建文件:

cd /root/db-dev-cert/mybatisdemo/src/main/java/com/huawei/guassdb/util
vim TestMyBatis.java

输入"i"命令插入下面的内容到文件里,然后输入":wq"保存退出:

package com.huawei.guassdb.util;

import java.util.List;

import org.apache.ibatis.session.SqlSession;

import com.huawei.guassdb.mapper.GoodsMapper;
import com.huawei.guassdb.pojo.Goods;

public class TestMyBatis {
    public static void main(String[] args) {
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
        try {
                System.out.println("**********查询一个商品******************");
                GoodsMapper mapper = sqlSession.getMapper(GoodsMapper.class);
            Goods goods = mapper.selectGoodsByUserId(1);
            System.out.println(goods);
            System.out.println("**********所有商品**********************");
            List<Goods> allgoods = mapper.getAllGoods();
            for (int i = 0; i < allgoods.size(); i ++ ) {
                    System.out.println(allgoods.get(i));
            }
            System.out.println("*****************结束*******************");
            System.out.println("----finished successfully!----");
            
        } finally {
            sqlSession.close();
        }
        System.exit(0);
    }
}

8.4 编译构建并运行程序打印数据

1)创建pom.xml

执行下面的命令,去创建文件:

cd /root/db-dev-cert/mybatisdemo/
vim pom.xml

输入"i"命令插入下面的内容到文件里,然后输入":wq"保存退出:

<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
 
    <groupId>com.huawei.gaussdb</groupId>
    <artifactId>gaussdb-project</artifactId>
    <version>1.0</version>
 
    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>
 
    <dependencies>
        <!-- 添加junit依赖 -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
             <artifactId>mybatis</artifactId>
            <version>3.5.9</version>
        </dependency>        
       <dependency>
             <groupId>com.huaweicloud.gaussdb</groupId> 
             <artifactId>opengaussjdbc</artifactId>
             <version>503.2.T35</version>
       </dependency>        
    </dependencies>
    
 <build>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
        </resources>
    </build> 
</project>

2)在源代码的根目录执行下面的mvn命令编译构建jar文件。

cd /root/db-dev-cert/mybatisdemo/
mvn clean install
  1. 运行下面的 find命令检查是否成功产生gaussdb-project-1.0.jar文件。
cd /root/db-dev-cert/
find . -type f -name gaussdb-project-1.0.jar
  1. 确保mybatis JAR和 opengaussjdbc JAR文件存在。
cd /root/db-dev-cert/
find . -type f -name mybatis-3.5.9.jar
find . -type f -name opengaussjdbc-503.2.T35.jar

5)运行下面的java命令执行程序并打印数据。

cd /root/db-dev-cert/mybatisdemo
java -classpath .:/root/db-dev-cert/mybatisdemo/target/gaussdb-project-1.0.jar:/root/db-dev-cert/libs/org/mybatis/mybatis/3.5.9/mybatis-3.5.9.jar:/root/db-dev-cert/libs/com/huaweicloud/gaussdb/opengaussjdbc/503.2.T35/opengaussjdbc-503.2.T35.jar com.huawei.guassdb.util.TestMyBatis

正确的打印结果如下图: