使用Cypher JDBC Driver访问GES
功能介绍
GES Cypher JDBC Driver是专为GES编写的JDBC驱动,基于Neo4j JDBC Driver中的接口,提供了使用JDBC访问GES并进行cypher查询的一种方法。
尤其是当cypher请求返回数据量较大、并发数高、JVM缓存完整请求体有困难的场景下,该组件内置了一种可以流式解析响应body体的方法,与获得整个body体再解析相比,极大地降低了cpu和内存的占用。
依赖配置
- 下载相应的SDK和驱动,具体操作请参考连接管理。
- 若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>
- 若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目录下所有包导入工程皆可。
参数说明
参数 |
释义 |
url |
GES Cypher API的URL,添加前缀jdbc:ges:http(s)为前缀以方便JDBC Driver识别,是DriverManager.getConnection的第一个参数。 |
prop |
Properties对象,包含连接GES API所需的各项配置,详见表2。 |
参数 |
释义 |
X-Auth-Token |
通过iam鉴权接口获取到的token。 |
parse-json |
是否转换点边对象,默认值为"false"。
|
deserializer-type |
解析cypher响应的策略,可选项为lazy和eager,默认为lazy。
|
limit |
流速控制,默认值100000,内核以批的形式返回给server侧的webapp,由webapp整理成流返回给前端。limit的含义为内核返回给webapp时的批的大小。对同一条查询,limit越小时,GES内核侧交互次数增多,jdbc client拿到第一条记录的时间越快,整体查询时间变长。 |
使用示例
package org.example; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.Properties; public class App { static String ip = "${ip}"; static int port = 80; static String projectId = "${projectId}"; static String graphName = "${graphName}"; static String token = "${x_auth_token}"; public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException { Class.forName("com.huawei.ges.jdbc.Driver").newInstance(); String url = "jdbc:ges:http://{{graph_ip}}:{{graph_port}}/ges/v1.0/{{project_id}}/graphs/{{graph_name}}/action?action_id=execute-cypher-query"; url = url.replace("{{graph_ip}}", ip).replace("{{graph_port}}",port + "").replace("{{project_id}}", projectId).replace("{{graph_name}}", graphName); 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 1000"; try(PreparedStatement stmt = conn.prepareStatement(query)){ try(ResultSet rs = stmt.executeQuery()){ Object o = null; while(rs.next()) { o = rs.getObject("m"); processVertex(o); } } } } catch (SQLException e) { // here process exception. // ... } } }
鉴权方法
GES Cypher JDBC Driver支持Token和AK/SK两种鉴权Token鉴权相关参数详见使用参数和使用示例。
AKSK鉴权需要依赖GES业务面SDK获取AK/SK签名后,使用签名进行鉴权操作。
导入业务面SDK依赖详见导入业务面SDK,GraphInfo的配置详见初始化GES业务面客户端,并且需要您输入获取到的AccessKey,secretKey和regionName参数。
以AK/SK鉴权方式为例,代码示例如下:
import com.huawei.ges.jdbc.io.model.GesElement; import com.huawei.graph.sdk.GraphInfo; import com.huawei.graph.sdk.exception.GraphSdkException; import com.huawei.graph.sdk.utils.HttpRestClient; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Properties; import java.util.Map; public class CypherJDBCClientByAKSK { private static final Logger logger = LoggerFactory.getLogger("CypherJDBCClientByAKSK"); private static String ip = ""; private static int port = 80; private static String projectId = ""; private static String graphName = ""; // 认证用的ak和sk硬编码到代码中或者明文存储都有很大的安全风险,建议在配置文件或者环境变量中密文存放,使用时解密,确保安全 // 本示例以ak和sk保存在环境变量中来实现身份验证为例,运行本示例前请先在本地环境中设置环境变量HUAWEICLOUD_SDK_AK和HUAWEICLOUD_SDK_SK String accessKey = System.getenv("HUAWEICLOUD_SDK_AK"); String secretKey = System.getenv("HUAWEICLOUD_SDK_SK"); String regionName = "cn-north-4XXX"; public static GraphInfo getGraphInfo() { //正式代码应该通过正常方式初始化graphInfo对象。 GraphInfo info = getGraphInfoByYourSelf(); info.setAccessKey(accessKey); info.setSecretKey(secretKey); // 此处需要输出您的regionName info.setRegionName(regionName); return info; } public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, GraphSdkException { GraphInfo info = getGraphInfo(); Map<String, String> iamHeader = HttpRestClient.getIamSignHeaders(info); Class.forName("com.huawei.ges.jdbc.Driver").newInstance(); String url = "jdbc:ges:http://{{graph_ip}}:{{graph_port}}/ges/v1.0/{{project_id}}/graphs/{{graph_name}}/action?action_id=execute-cypher-query"; url = url.replace("{{graph_ip}}", ip).replace("{{graph_port}}", port + "").replace("{{project_id}}", projectId).replace("{{graph_name}}", graphName); 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()) { Object o = null; 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) { logger.info("Execute SQL query error."); } } }