本文首发于 Nebula Graph Community 公众号
我最近注意到很多同学对于 ORM 框架的需求比较迫切,而且有热心的同学已经捐赠了自己开发的项目,Nebula 社区也在 working on it。下面主要介绍一下我们在使用 MyBatis 操作 Nebula Graph 方面的一些经验,希望能够帮助到大家。
MyBatisJava 开发的同学想必对 MyBatis 都比较熟悉了。MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射,并且免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。
实现途径主要通过 MyBatis 结合 nebula-jdbc 来实现参数返回值映射以及语句执行。
Demo 示例完整代码参见 GitHub。
Nebula SchemaCREATE SPACE basketballplayer(partition_num=10,replica_factor=1,vid_type=fixed_string(32)); CREATE TAG IF NOT EXISTS player(name string, age int); CREATE EDGE IF NOT EXISTS follow(degree int);工程结构 application.yaml
spring:
datasource:
driver-class-name: com.vesoft.nebula.jdbc.NebulaDriver
url: jdbc:nebula://localhost:9669/basketballplayer
username: nebula
password: nebula
hikari:
maximum-pool-size: 20
mybatis:
mapper-locations: classpath:mapper
private String id;
private String name;
private Long age;
}
Dao
public interface PlayerDao {
int insert(PlayerDO entity);
int update(PlayerDO entity);
int insertBatch(List batch);
PlayerDO select(String id);
List selectBatch(List batch);
int delete(String id);
int deleteBatch(List batch);
//以上代码自动生成
PlayerDO selectReturnV(String id);
}
Mapper
Tag 操作insert vertex `player` ( ) values #{id} :( name, age, ) #{name}, #{age}, insert vertex `player` name, age, values#{item.id} : #{item.name}, #{item.age}, UPDATE vertex ON `player` #{id} name = #{name}, age = #{age}, delete vertex #{id} delete vertex #{item}
@SpringBootTest
public class PlayerDaoTest {
@Resource
private PlayerDao playerDao;
@Test
public void operation() {
//insert
PlayerDO player = PlayerDO.builder().id("daiyi").name("daiyi").age(22l).build();
playerDao.insert(player);
//insertBatch
PlayerDO playerBatch = PlayerDO.builder().id("daiyi").name("daiyi").age(22l).build();
PlayerDO joe = PlayerDO.builder().id("joe").name("joe").age(24l).build();
playerDao.insertBatch(Lists.newArrayList(playerBatch, joe));
//update
playerDao.update(PlayerDO.builder().id("daiyi").name("daiyiupdate").build());
//select
PlayerDO playerDO = playerDao.select("daiyi");
//selectBatch
List players = playerDao.selectBatch(Lists.newArrayList("daiyi", "joe"));
//selectReturnV
playerDao.selectReturnV("daiyi");
//delete
playerDao.delete("daiyi");
//deleteBatch
playerDao.deleteBatch(Lists.newArrayList("daiyi", "joe"));
}
}
Edge 及 Path 操作
篇幅有限,详情可以参见github。
版本适配目前仅支持了 Nebula 2.5 版本,后续版本的支持还在适配中。
总结优点
- 使用简单,消除了使用 JDBC 或 nebula-client 带来的冗余代码。
- 可以使用配套连接池管理连接,并且可以与 Spring Boot 无缝衔接。
- nGQL 与代码解耦,方便管理。
- 大量便捷标签,免除了代码拼接语句的烦恼。
存在的问题
- 针对返回值为 Vertex(类似MATCH v RETURN v)、Edge、无属性 Path 的类型目前采用在 MyBatis 中的 Interceptor 做拦截处理,也能满足使用。但这种实现方式感觉不是很好,后期有待优化。
- 对于返回值类型为带属性 Path、多 Tag 查询以及 GET SUBGRAPH 语句的情况,因为返回的结果中实体以及边的类型可能有多种,目前没有想到比较好的映射方式也就没有支持。
- 上述示例中使用的 JDBC 驱动是我们自己开发的版本(详见 https://github.com/DA1Y1/nebula-jdbc),与社区版的主要区别在 URL 上服务地址的指定以及⼀些转义字符的处理,后续也希望能将这些 Feature 合并到社区版本中,统⼀使⽤。
为了方便使用我们还开发了类似 mybatis-generator 这种工具来生成一些基础代码,提供基本的增删改查功能。感兴趣的同学可以在 IDEA 的 Plugins 中搜索 Nebula Generator 下载,使用方式参见:https://plugins.jetbrains.com/plugin/18026-nebula-generator
最后感谢 @DA1Y1 以及其他几位小伙伴的贡献!
交流图数据库技术?加入 Nebula 交流群请先填写下你的 Nebula 名片,Nebula 小助手会拉你进群~~



