Nebula Graph介绍和SpringBoot环境连接和查询( 二 )

添加一个点记录
String insertVertexes = "INSERT VERTEX person(name, age) VALUES "+ "'Bob':('Bob', 10), "+ "'Lily':('Lily', 9), "+ "'Tom':('Tom', 10), "+ "'Jerry':('Jerry', 13), "+ "'John':('John', 11);";ResultSet resp = session.execute(insertVertexes);if (!resp.isSucceeded()) { log.error(String.format("Execute: `%s', failed: %s",insertVertexes, resp.getErrorMessage())); System.exit(1);}查询
String query = "GO FROM \"Bob\" OVER like "+ "YIELD $^.person.name, $^.person.age, like.likeness";ResultSet resp = session.execute(query);if (!resp.isSucceeded()) { log.error(String.format("Execute: `%s', failed: %s",query, resp.getErrorMessage())); System.exit(1);}printResult(resp);在 SpringBoot 项目中使用 Nebula Graphpom.xml 增加包依赖<dependency> <groupId>com.vesoft</groupId> <artifactId>client</artifactId> <version>3.0.0</version></dependency>Session工厂: NebulaSessionFactory.java配合@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<>() {});}}

经验总结扩展阅读