南大通用GBase 8c是一款多模多态的分布式数据库,支持行存、列存、内存等多种存储模式和单机、主备式、分布式等多种部署形态。GBase 8c具备高性能、高可用、弹性伸缩、高安全性等特性,可以部署在物理机、虚拟机、容器、私有云和公有云,为关键行业核心系统、互联网业务系统和政企业务系统提供安全、稳定、可靠的数据存储和管理服务。

使用 jdbc 访问南大通用GBase 8c数据库时,如何获取其 cursor 游标数据呢?通过下面的用例来讲解操作过程(注:下方示例前2步在GBase 8c V5 3.0.0版本的远程客户端执行,3和4步是在java环境下执行)。

前置条件:正确安装GBase 8c,并配置远程连接;jdbc驱动可以去官网下载或咨询GBase技术人员索取。

(1)首先创建需要实现某种效果的自定义函数,后续使用,本文以获取游标所在用户名为例:

CREATE OR REPLACE FUNCTION get_users()
RETURNS refcursor AS $$
DECLARE
   result_cursor refcursor;
BEGIN
   OPEN result_cursor FOR
       SELECT * FROM users;
   RETURN result_cursor;
END;
$$ LANGUAGE plpgsql;

(2)创建测试表

create table users( id int, name varchar2(10));
insert into users values(1,'张三'),(2,'李四'),(3,'王五');

(3)游标数据调用代码如下所示:

public class jdbccallproc {
    public static void main(String[] args) {
        String jdbcURL = "jdbc:gbase8c://172.16.5.102:5432/postgres?loggerLevel=warning";
        String username = "regress";
        String password = "gbase;234";
        
        try {
            // 1. 注册 GBase8c JDBC 驱动程序
            Class.forName("com.gbase8c.Driver");
            
            // 2. 建立连接
            Connection connection = DriverManager.getConnection(jdbcURL, username, password);
            
            // 3. 调用存储过程
            String call = "{ ? = call get_users() }";
            connection.setAutoCommit(false);
            CallableStatement stmt = connection.prepareCall(call);
          
            // 4. 注册输出参数类型
            //stmt.registerOutParameter(1,OracleTypes.CURSOR );
            //stmt.registerOutParameter(1,1111 );
            stmt.registerOutParameter(1,Types.REF_CURSOR );
            
            // 5. 执行查询
            stmt.execute();
            
            // 6. 获取结果集
            ResultSet rs = (ResultSet) stmt.getObject(1);
            
            // 7. 处理结果集
            while (rs.next()) {
                int id = rs.getInt("id");
                String name = rs.getString("name");
                // 根据需要处理其他字段
                
                System.out.println("ID: " + id + ", Name: " + name);
            }
            
            // 8. 关闭连接
            rs.close();
            stmt.close();
            connection.close();
            
        } catch (ClassNotFoundException | SQLException e) {
            e.printStackTrace();
        }
    }
}

需要注意的是:

  • setAutoCommit(false) 需要添加,如果缺少会存在异常报错
  • registerOutParameter的类型支持oracle 的OracleTypes.CURSOR、1111以及Types.REF_CURSOR,示例中注释了前两种用法,有兴趣的可以自己实验

(4)调用结果如下:

ID: 1, Name: 张三
ID: 2, Name: 李四
ID: 3, Name: 王五

以一个例子抛砖引玉,欢迎大家进行技术上的交流~