文档首页/ 图引擎服务 GES/ 开发指南/ 使用Cypher JDBC Driver访问GES
更新时间:2024-11-25 GMT+08:00

使用Cypher JDBC Driver访问GES

功能介绍

GES Cypher JDBC Driver是专为GES编写的JDBC驱动,基于Neo4j JDBC Driver中的接口,提供了使用JDBC访问GES并进行cypher查询的一种方法。

尤其是当cypher请求返回数据量较大、并发数高、JVM缓存完整请求体有困难的场景下,该组件内置了一种可以流式解析响应body体的方法,与获得整个body体再解析相比,极大地降低了cpu和内存的占用。

依赖配置

  1. 下载相应的SDK和驱动,具体操作请参考连接管理章节。
  2. 若Maven源可用(有配置maven源,且maven源可以从开源仓库下载jar包),则解压huaweicloud-ges-sdk-java-xxx.zip,进入maven-install目录中,执行ges-sdk-java-maven-install.bat文件或ges-sdk-java-maven-install.sh文件,将graph-sdk-xxx.jar、cypher-jdbc-driver-xxx.jar安装到本地maven仓库,即可在maven工程中配置pom依赖以使用Cypher JDBC Driver。
    <dependency> 
          <groupId>com.huawei.ges</groupId> 
          <artifactId>cypher-jdbc-driver</artifactId> 
          <version>xxx</version> //此处需要输入当前cypher jdbc驱动的版本号
     </dependency>
    <dependency>
        <groupId>org.neo4j</groupId>
        <artifactId>neo4j-jdbc</artifactId>
        <version>xxx<version>
    </dependency>
    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpclient</artifactId>
        <version>xxx</version>
    </dependency>
  3. 若Maven源不可用(没有配置maven源或者maven源不能从开源仓库下载jar包),则解压huaweicloud-ges-sdk-java-xxx.zip,将jars目录下的cypher-jdbc-driver-xxx-with-dependencies.jar导入工程或者将cypher-jdbc-driver-xxx.jar以及cypher-jdbc-lib目录下所有包导入工程皆可。

参数说明

表1 JDBC getConnection参数说明

参数

参数说明

url

“jdbc:ges:”前缀拼接GES Cypher API的URL。

在GES控制台的“连接管理”页面,“可用图实例名称”下拉选择待访问的图名称,“JDBC连接字符串”即为Cypher API的URL。

prop

Properties对象,包含连接GES API所需的各项配置,详见表2

表2 Properties参数说明

参数

参数说明

X-Auth-Token

通过IAM鉴权接口获取到的token。

parse-json

是否转换点边对象,默认值为"false"。

  • 取值为false时,cypher返回体中的点和边将以map形式返回。
  • 为true时,以GesElement对象的形式返回。

deserializer-type

解析cypher响应的策略,可选项为lazy和eager,默认为lazy。

  • 取值为lazy时,采用流式解析cypher的策略,cypher返回体不常驻内存。
  • 取值为eager时为获取整个json后解析。

limit

流速控制,默认值100000,内核以批的形式返回给server侧的webapp,由webapp整理成流返回给前端。limit的含义为内核返回给webapp时的批的大小。对同一条查询,limit越小时,GES内核侧交互次数增多,jdbc client拿到第一条记录的时间越快,整体查询时间变长。

鉴权方法

GES Cypher JDBC Driver支持Token和AK/SK两种鉴权。

  1. Token鉴权代码示例:
    import com.huawei.ges.jdbc.io.model.GesElement;
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.util.Properties;
    
    public class CypherJDBCClient {
    
        public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
            String token = "";  // 调用IAM服务API获取
            String url = "";  // 值为“jdbc:ges:JDBC连接字符串”,其中“JDBC连接字符串”从GES控制台“连接管理”界面获取
            Class.forName("com.huawei.ges.jdbc.Driver").newInstance();
            Properties prop = new Properties();
            prop.setProperty("X-Auth-Token", token);
            prop.setProperty("deserializer-type", "lazy");
            prop.setProperty("parse-json", "true");
            prop.setProperty("limit", "10000");
            try (Connection conn = DriverManager.getConnection(url, prop)) {
                String query = "match (m) return m limit 1";
                try (PreparedStatement stmt = conn.prepareStatement(query)) {
                    try (ResultSet rs = stmt.executeQuery()) {
                        while (rs.next()) {
                            GesElement.GesVertex vertex = (GesElement.GesVertex) rs.getObject("m");
                            System.out.println(vertex.getId());
                            System.out.println(vertex.getLabels());
                            System.out.println(vertex.getProperties());
                        }
                    }
                }
            } catch (SQLException e) {
                System.out.println("Execute SQL query error.");
            }
        }
    }
  2. AK/SK鉴权可以使用GES业务面SDK提供的方法生成签名,导入业务面SDK依赖详见下载与安装

    AK/SK鉴权代码示例如下,ak,sk和regionCode参数获取请参考初始化参数获取章节。

    import com.huawei.ges.graph.v1.auth.aksk.HttpRestClient;
    import com.huawei.ges.jdbc.io.model.GesElement;
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.util.Map;
    import java.util.Properties;
    
    public class CypherJDBCClientByAKSK {
    
        public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
            // 认证用的ak和sk硬编码到代码中或者明文存储都有很大的安全风险,建议在配置文件或者环境变量中密文存放,使用时解密,确保安全
            // 本示例以ak和sk保存在环境变量中来实现身份验证为例,运行本示例前请先在本地环境中设置环境变量HUAWEICLOUD_SDK_AK和HUAWEICLOUD_SDK_SK
            String ak = System.getenv("HUAWEICLOUD_SDK_AK");
            String sk = System.getenv("HUAWEICLOUD_SDK_SK");
            String regionCode = "";
            String url = "";  // 值为“jdbc:ges:JDBC连接字符串”,其中“JDBC连接字符串”从GES控制台“连接管理”界面获取
            Map<String, String> iamHeader = HttpRestClient.getIamSignHeaders(ak, sk, regionCode);  // 业务面SDK的方法,生成签名
            Class.forName("com.huawei.ges.jdbc.Driver").newInstance();
            doCypherQuery(url, iamHeader);
        }
    
        public static void doCypherQuery(String url, Map<String, String> iamHeaders) {
            Properties prop = new Properties();
            for (Map.Entry<String, String> pair : iamHeaders.entrySet()) {
                prop.setProperty(pair.getKey(), pair.getValue());
            }
            prop.setProperty("deserializer-type", "lazy");
            prop.setProperty("parse-json", "true");
            prop.setProperty("limit", "10000");
            try (Connection conn = DriverManager.getConnection(url, prop)) {
                String query = "match (m) return m limit 1";
                try (PreparedStatement stmt = conn.prepareStatement(query)) {
                    try (ResultSet rs = stmt.executeQuery()) {
                        while (rs.next()) {
                            GesElement.GesVertex vertex = (GesElement.GesVertex) rs.getObject("m");
                            System.out.println(vertex.getId());
                            System.out.println(vertex.getLabels());
                            System.out.println(vertex.getProperties());
                        }
                    }
                }
            } catch (SQLException e) {
                System.out.println("Execute SQL query error.");
            }
        }
    }