sqlg rdbms 上实现的Apache TinkerPop

sqlg 可以让关系型数据库支持Apache TinkerPop,当前支持的数据库有postgresql,hsqldb,h2,mariadb,mysql,mssqlserver
以下是一个简单的使用

环境准备

  • postgresql
version: "3"
services:
  postgres:
    image: postgres:9.6.11
    ports:
    - "5432:5432"
    environment:
    - "POSTGRES_PASSWORD:dalong"

代码

简单测试,了解下实现处理

  • maven pom文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.dalong</groupId>
    <artifactId>tinkerpop-postgresql</artifactId>
    <version>1.0-SNAPSHOT</version>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <encoding>UTF-8</encoding>
        <java.version>1.8</java.version>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.umlg</groupId>
            <artifactId>sqlg-postgres</artifactId>
            <version>2.0.0</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.8</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>
 
 
  • 代码结构
├── README.md
├── docker-compose.yaml
├── pom.xml
├── src
├── main
├── java
└── com
└── dalong
└── Application.java
└── resources
└── datasource.properties
└── test
└── java
└── InsertTest.java
 
  • 测试代码
    InsertTest.java
 
import org.apache.tinkerpop.gremlin.structure.Graph;
import org.apache.tinkerpop.gremlin.structure.T;
import org.apache.tinkerpop.gremlin.structure.Vertex;
import org.junit.Before;
import org.junit.Test;
import org.umlg.sqlg.structure.SqlgGraph;
import java.time.LocalDate;
import java.util.List;
import static junit.framework.Assert.assertEquals;
public class InsertTest {
    Graph sqlgGraph = null;
    public InsertTest(){
        sqlgGraph = SqlgGraph.open("datasource.properties");
    }
    @Test
    public void useAsPerNormal() {
        Vertex person = this.sqlgGraph.addVertex(T.label, "Person", "name", "John");
        Vertex address = this.sqlgGraph.addVertex(T.label, "Address", "street", "13th");
        person.addEdge("livesAt", address, "since", LocalDate.of(2010, 1, 21));
        this.sqlgGraph.tx().commit();
        List<Vertex> addresses = this.sqlgGraph.traversal().V().hasLabel("Person").out("livesAt").toList();
        assertEquals(3, addresses.size());
    }
    @Test
    public void testElementsInSchema() {
        Vertex john = this.sqlgGraph.addVertex(T.label, "Manager", "name", "john");
        Vertex palace1 = this.sqlgGraph.addVertex(T.label, "continent.House", "name", "palace1");
        Vertex corrola = this.sqlgGraph.addVertex(T.label, "fleet.Car", "model", "corrola");
        palace1.addEdge("managedBy", john);
        corrola.addEdge("owner", john);
        this.sqlgGraph.tx().commit();
        assertEquals(1, this.sqlgGraph.traversal().V().hasLabel("Manager").count().next().intValue());
        assertEquals(0, this.sqlgGraph.traversal().V().hasLabel("House").count().next().intValue());
        assertEquals(1, this.sqlgGraph.traversal().V().hasLabel("continent.House").count().next().intValue());
        assertEquals(0, this.sqlgGraph.traversal().V().hasLabel("Car").count().next().intValue());
        assertEquals(1, this.sqlgGraph.traversal().V().hasLabel("fleet.Car").count().next().intValue());
        assertEquals(1, this.sqlgGraph.traversal().E().hasLabel("managedBy").count().next().intValue());
        assertEquals(1, this.sqlgGraph.traversal().E().hasLabel("owner").count().next().intValue());
    }
}
 
 
  • 启动&&运行
    使用junt 运行测试
  • 效果

 

 

  • sql 生成处理
    官方包含了关于sql生成的处理过程
    如下以下处理:
 
@Test
public void showVertexStep() {
    Vertex a1 = this.sqlgGraph.addVertex(T.label, "A", "name", "a1");
    Vertex b1 = this.sqlgGraph.addVertex(T.label, "B", "name", "b1");
    Vertex b2 = this.sqlgGraph.addVertex(T.label, "B", "name", "b2");
    Vertex c1 = this.sqlgGraph.addVertex(T.label, "C", "name", "c1");
    Vertex c2 = this.sqlgGraph.addVertex(T.label, "C", "name", "c2");
    a1.addEdge("ab", b1);
    a1.addEdge("ab", b2);
    b1.addEdge("bc", c1);
    b2.addEdge("bc", c2);
    this.sqlgGraph.tx().commit();
    GraphTraversal<Vertex, Vertex> traversal = this.sqlgGraph.traversal().V()
            .hasLabel("A")
            .out()
            .out();
    System.out.println(traversal);
    traversal.hasNext();
    System.out.println(traversal);
    List<Vertex> c = traversal.toList();
    assertEquals(2, c.size()); 

生成的sql

SELECT
    "public"."V_C"."ID" AS "alias1",
    "public"."V_C"."name" AS "alias2"
FROM
    "public"."V_A" INNER JOIN
    "public"."E_ab" ON "public"."V_A"."ID" = "public"."E_ab"."public.A__O" INNER JOIN
    "public"."V_B" ON "public"."E_ab"."public.B__I" = "public"."V_B"."ID" INNER JOIN
    "public"."E_bc" ON "public"."V_B"."ID" = "public"."E_bc"."public.B__O" INNER JOIN
    "public"."V_C" ON "public"."E_bc"."public.C__I" = "public"."V_C"."ID"
 

以上只是部分,实际上sqlg 也做了很多的优化处理

说明

facebook 开源的ent 也是一个类似的,但是ent 从性能以及使用上就很简单了,ent支持代码生成(主要基于模版)
ent 对于图遍历的各种模型的支持还是比较全的,只是当前支持的数据库比较少,mysql,sqlite 以及gremlin,计划
线路有支持postgresql,同时代码中也包含了,部分关于pg 的处理。

参考资料

https://github.com/apache/tinkerpop/
http://sqlg.org/docs/2.0.0-SNAPSHOT/#_introduction
https://github.com/facebookincubator/ent

posted on 2019-10-16 16:38  荣锋亮  阅读(868)  评论(0编辑  收藏  举报

导航