@Bean(destroyMethod = "close")
, 创建一个工厂类, 接收pool并实现close()方法
public class NebulaSessionFactory {private final NebulaPool pool;private final String username;private final String password;public NebulaSessionFactory(NebulaPool pool, String username, String password) {this.pool = pool;this.username = username;this.password = password;}public Session getSession() {try {return pool.getSession(username, password, false);} catch (NotValidConnectionException|IOErrorException|AuthFailedException|ClientServerIncompatibleException e) {throw new RuntimeException("Nebula session exception", e);}}public void close() {pool.close();}}
为什么不直接将 NebulaPool 配置为Bean? 因为 Session 每次创建时需要带用户名密码, 将密码作为config注入到每个Service中肯定是大家都不愿意看到的.
配置修改: application.yml
- 这里的值如果不打算使用profile配置, 可以直接写入
- hosts是逗号分隔的地址端口列表, 例如
10.22.33.33:9669,10.22.33.34:9669
myapp:nebula:hosts: @nebula.hosts@username: @nebula.username@password: @nebula.password@max-conn: @nebula.max-conn@
Spring启动配置: NebulaGraphConfig.java应用启动时读取配置, 创建 NebulaPool, 并实例化 NebulaSessionFactory, destroyMethod = "close"
, 这个表示在项目shutdown时会调用Bean的close方法释放资源.@Configurationpublic class NebulaGraphConfig {@Value("${myapp.nebula.hosts}")private String hosts;@Value("${myapp.nebula.max-conn}")private int maxConn;@Value("${myapp.nebula.username}")private String username;@Value("${myapp.nebula.password}")private String password;@Bean(destroyMethod = "close")public NebulaSessionFactory nebulaSessionFactory() {List<HostAddress> hostAddresses = new ArrayList<>();String[] hostList = hosts.split(",[ ]*");for (String host : hostList) {String[] hostParts = host.split(":");if (hostParts.length != 2 || !hostParts[1].matches("\\d+")) {throw new RuntimeException("Invalid host name set for Nebula: " + host);}hostAddresses.add(new HostAddress(hostParts[0], Integer.parseInt(hostParts[1])));}NebulaPoolConfig poolConfig = new NebulaPoolConfig();poolConfig.setMaxConnSize(maxConn);NebulaPool pool = new NebulaPool();try {pool.init(hostAddresses, poolConfig);} catch (UnknownHostException e) {throw new RuntimeException("Unknown Nebula hosts");}return new NebulaSessionFactory(pool, username, password);}}
Service调用在 Service 中进行调用@Service@Slf4jpublic class GraphServiceImpl implements GraphService {@Autowiredprivate NebulaSessionFactory sessionFactory;@Overridepublic <T> NebulaResult<T> query(String graphSpace, String gql) {Session session = null;try {log.info("GQL: {}", gql);session = sessionFactory.getSession();NebulaResult<Void> res = query(session, "USE " + graphSpace);if (!res.isSuccess() || res.getResults() == null || res.getResults().size() == 0) {log.error("Failed to use space:{}", graphSpace);return null;}if (!graphSpace.equals(res.getResults().get(0).getSpaceName())) {log.error("Failed to use space:{}, result:{}", graphSpace, res.getResults().get(0).getSpaceName());return null;}return query(session, gql);} catch (IOErrorException e) {log.error(e.getMessage(), e);return null;} finally {if (session != null) {session.release();}}}private <T> NebulaResult<T> query(Session session, String gql) throws IOErrorException {String json = session.executeJson(gql);return JacksonUtil.extractByType(json, new TypeReference<>() {});}}
辅助类 NebulaResult.java 等外层结构这里定义了 json 格式响应的外层结构@Datapublic class NebulaResult<T> implements Serializable {private List<Error> errors;private List<Result<T>> results;@JsonIgnorepublic boolean isSuccess() {return (errors != null && errors.size() == 1 && errors.get(0).getCode() == 0);}@Datapublic static class Error implements Serializable {private int code;}@Data@JsonIgnoreProperties(ignoreUnknown = true)@JsonInclude(JsonInclude.Include.NON_NULL)public static class Result<T> implements Serializable {private String spaceName;private List<Element<T>> data;private List<String> columns;private Error errors;private long latencyInUs;}@Datapublic static class Element<T> implements Serializable {private List<Meta<T>> meta;private List<Serializable> row;}@Datapublic static class Meta<T> implements Serializable {private String type;private T id;}}
内层因为区分Edge和Vertex, 结构不一样. 如果是混合返回的结果, 可以用 SerializableString gql = "match (v:ADDR)-[e]-() where id(v)==\"ADD:123123\" return v,e limit 100";NebulaResult<Serializable> res = graphService.query("insurance", gql);log.info(JacksonUtil.compress(res));Assertions.assertThat(res).isNotNull();
对于边, 需要使用结构化的ID@Data@JsonIgnoreProperties(ignoreUnknown = true)@JsonInclude(JsonInclude.Include.NON_NULL)public class EdgeId implements Serializable {private int ranking;private int type;private String dst;private String src;private String name;}
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- iqoou3详细参数_iqoou3参数详细参数配置
- 三国杀玩法及卡牌介绍(三国杀108张牌明细)
- Go Micro介绍与入门
- 荣耀magic3有超级终端功能吗_超级终端功能介绍
- 我的世界信标怎么用,信标功能详细介绍(我的世界中的信标是怎么用的)
- 华为mate40的优点和缺点_华为mate40的优缺点介绍
- Go_Channel详解
- Docker 部署Kibana
- 谣言检测《Data Fusion Oriented Graph Convolution Network Model for Rumor Detection》
- Go的网络编程详解