zoukankan      html  css  js  c++  java
  • Neo4j学习笔记(1)——使用Java API实现简单的增删改查

    项目的创建及配置

    因为Neo4j依赖的jar包比较多,所以推荐使用Maven来管理。

    首先创建一个Maven Project,添加依赖:

    复制代码
    <dependency>
        <groupId>org.neo4j</groupId>
        <artifactId>neo4j</artifactId>
        <version>3.2.6</version>
    </dependency>
    复制代码

    使用的是3.2.6版本,对应版本的Neo4j安装地址摸我

    使用嵌入式数据库

    配置好之后,就可以开始了,第一步是学习开启和关闭数据库。

    无论是创建一个新的数据库,还是打开一个已有的数据库,首先都需要创建一个GraphDatabaseService实例。

    graphDb = new GraphDatabaseFactory().newEmbeddedDatabase( DB_PATH );

    GraphDatabaseService实例可以被多个线程共享,但是一个数据库只允许有一个Service实例。

    关闭数据库可以调用shutdown()方法。

    为了确保数据库正确地关闭,可以添加一个ShutdownHook来实现关闭数据库的动作。

    复制代码
    private static void registerShutdownHook(final GraphDatabaseService graphDb) {
            Runtime.getRuntime().addShutdownHook(new Thread() {
                @Override
                public void run() {
                    graphDb.shutdown();
                }
            });
        }
    复制代码

    还可以通过API对数据库的一些配置进行设置。

    一种方法是加载.conf配置文件。

    GraphDatabaseService graphDb = new GraphDatabaseFactory()
        .newEmbeddedDatabaseBuilder( testDirectory.graphDbDir() )
        .loadPropertiesFromFile( pathToConfig + "neo4j.conf" )
        .newGraphDatabase();

    另一种方法就是通过方法来添加。

    复制代码
    GraphDatabaseService graphDb = new GraphDatabaseFactory()
        .newEmbeddedDatabaseBuilder( testDirectory.graphDbDir() )
        .setConfig( GraphDatabaseSettings.pagecache_memory, "512M" )
        .setConfig( GraphDatabaseSettings.string_block_size, "60" )
        .setConfig( GraphDatabaseSettings.array_block_size, "300" )
        .newGraphDatabase();
    复制代码

    创建一个只读的数据库,数据库必须已经存在。

    graphDb = new GraphDatabaseFactory().newEmbeddedDatabaseBuilder( dir )
            .setConfig( GraphDatabaseSettings.read_only, "true" )
            .newGraphDatabase(); 

    更多配置信息可以看GraphDatabaseSettings类的文档

    创建节点和关系

    图数据库是一个有向图,由通过关系Relationships连接的节点Nodes构成,节点和关系可以有自己的属性Properties。 

    关系的类型可以通过枚举enum创建(Label也可以):

    private static enum RelTypes implements RelationshipType
    {
        RELEASED;
    }

     在Neo4j中,对于数据库的操作需要在一个事务transaction中执行。

    复制代码
    try ( Transaction tx = graphDb.beginTx() )
    {
        // 数据库操作写在事务提交之前
        tx.success();
    }
    复制代码

    下面是一个简单的实例,实现了节点和关系的创建。

    复制代码
    try (Transaction tx = graphDb.beginTx()) {
                // 创建标签
                label1 = Label.label("Musician");
                label2 = Label.label("Album");
                // 创建节点
                node1 = graphDb.createNode(label1);
                node1.setProperty("name", "Jay Chou");
                node2 = graphDb.createNode(label2);
                node2.setProperty("name", "Fantasy");
                // 创建关系及属性
                relationship = node1.createRelationshipTo(node2, RelTypes.RELEASED);
                relationship.setProperty("date", "2001-09-14");
                // 结果输出
                System.out.println("created node name is" + node1.getProperty("name"));
                System.out.println(relationship.getProperty("date"));
                System.out.println("created node name is" + node2.getProperty("name"));
                // 提交事务
                tx.success();
            }
    复制代码

     对于节点,除了设置属性,还可以添加标签Labels。添加标签之后就相当于对节点进行了分组,使节点的查询和管理更加清晰和方便,并且提高了查询的性能。标签是一个可选项,没有标签也是可以的。

    与关系数据库相比,标签相当于表名。一个节点相当于表中的一行数据,节点的属性就是字段。区别是,一个节点可以有多个标签

    可以看到我们创建了两个节点,名字是“周杰伦”和“《范特西》”,对应的标签分别是音乐家和专辑。

    他们之间通过“发行”这个关系连接,其中发行的属性为发行日期。

    打开Neo4j数据库,输入查询语句match (n) return n,可以看到数据被写入了进来。

    查询及更新

    知道了节点的标签和一条属性,就可以通过findNode()方法查询节点。

    然后使用setProperty()方法来更新和添加属性。 

    复制代码
    try (Transaction tx = graphDb.beginTx()) {
                // 查询节点
                Label label = Label.label("Musician");
                Node node = graphDb.findNode(label, "name", "Jay Chou");
                System.out.println("query node name is " + node.getProperty("name"));
                // 更新节点
                node.setProperty("birthday", "1979-01-18");
                System.out.println(node.getProperty("name") + "'s birthday is " + node.getProperty("birthday", new String()));
                // 提交事务
                tx.success();
            }
    复制代码

    打开Neo4j查看结果:

    删除关系和节点

    删除数据时,只需要执行相关实体对应的delete()方法即可。

    执行删除操作时,需要遵守如下规则:删除节点时,如果该节点存在关系,则必须先删除关系。这么做的目的是保证一条关系永远有起始和结束节点。

    复制代码
    try (Transaction tx = graphDb.beginTx()) {
                // 获得节点
                Label label = Label.label("Album");
                Node node = graphDb.findNode(label, "name", "Fantasy");
                // 获得关系
                Relationship relationship = node.getSingleRelationship(RelTypes.Released, Direction.INCOMING);
                // 删除关系和节点
                relationship.delete();
                relationship.getStartNode().delete();
                node.delete();
                tx.success();
            }
    复制代码

    完整代码

    复制代码
      1 package edu.heu.kg.graphdb;
      2 
      3 import java.io.File;
      4 
      5 import org.neo4j.graphdb.Direction;
      6 import org.neo4j.graphdb.GraphDatabaseService;
      7 import org.neo4j.graphdb.Label;
      8 import org.neo4j.graphdb.Node;
      9 import org.neo4j.graphdb.Relationship;
     10 import org.neo4j.graphdb.RelationshipType;
     11 import org.neo4j.graphdb.Transaction;
     12 import org.neo4j.graphdb.factory.GraphDatabaseFactory;
     13 
     14 /**
     15  * @ClassName: GraphDatabaseHelloWorld
     16  * @Description: TODO
     17  * @author LJH
     18  * @date 2017年12月22日 下午4:09:33
     19  */
     20 public class GraphDatabaseHelloWorld {
     21 
     22     private static final File DB_PATH = new File("D:\Neo4jDb");
     23     private static GraphDatabaseService graphDb;
     24 
     25     private static void registerShutdownHook(final GraphDatabaseService graphDb) {
     26         Runtime.getRuntime().addShutdownHook(new Thread() {
     27             @Override
     28             public void run() {
     29                 graphDb.shutdown();
     30             }
     31         });
     32     }
     33 
     34     private static enum RelTypes implements RelationshipType {
     35         RELEASED;
     36     }
     37 
     38     @SuppressWarnings("unused")
     39     private static void addData() {
     40         Node node1;
     41         Node node2;
     42         Label label1;
     43         Label label2;
     44         Relationship relationship;
     45 
     46         try (Transaction tx = graphDb.beginTx()) {
     47             // 创建标签
     48             label1 = Label.label("Musician");
     49             label2 = Label.label("Album");
     50             // 创建节点
     51             node1 = graphDb.createNode(label1);
     52             node1.setProperty("name", "Jay Chou");
     53             node2 = graphDb.createNode(label2);
     54             node2.setProperty("name", "Fantasy");
     55             // 创建关系及属性
     56             relationship = node1.createRelationshipTo(node2, RelTypes.Released);
     57             relationship.setProperty("date", "2001-09-14");
     58             // 结果输出
     59             System.out.println("created node name is " + node1.getProperty("name"));
     60             System.out.println(relationship.getProperty("date"));
     61             System.out.println("created node name is " + node2.getProperty("name"));
     62             // 提交事务
     63             tx.success();
     64         }
     65         graphDb.shutdown();
     66     }
     67 
     68     @SuppressWarnings("unused")
     69     private static void queryAndUpdate() {
     70         try (Transaction tx = graphDb.beginTx()) {
     71             // 查询节点
     72             Label label = Label.label("Musician");
     73             Node node = graphDb.findNode(label, "name", "Jay Chou");
     74             System.out.println("query node name is " + node.getProperty("name"));
     75             // 更新节点
     76             node.setProperty("birthday", "1979-01-18");
     77             System.out
     78                     .println(node.getProperty("name") + "'s birthday is " + node.getProperty("birthday", new String()));
     79             // 提交事务
     80             tx.success();
     81         }
     82         graphDb.shutdown();
     83     }
     84 
     85     @SuppressWarnings("unused")
     86     private static void delete() {
     87         try (Transaction tx = graphDb.beginTx()) {
     88             // 获得节点
     89             Label label = Label.label("Album");
     90             Node node = graphDb.findNode(label, "name", "Fantasy");
     91             // 获得关系
     92             Relationship relationship = node.getSingleRelationship(RelTypes.RELEASED, Direction.INCOMING);
     93             // 删除关系和节点
     94             relationship.delete();
     95             relationship.getStartNode().delete();
     96             node.delete();
     97             tx.success();
     98         }
     99         graphDb.shutdown();
    100     }
    101 
    102     public static void main(String[] args) {
    103         graphDb = new GraphDatabaseFactory().newEmbeddedDatabase(DB_PATH);
    104         registerShutdownHook(graphDb);
    105         addData();
    106         // queryAndUpdate();
    107         // delete();
    108 
    109     }
    110 
    111 }
    复制代码

    转载请注明原文链接:http://www.cnblogs.com/justcooooode/p/8179202.html

    参考资料

     https://neo4j.com/docs/java-reference/3.2

    《Neo4j 实战》

  • 相关阅读:
    一个WPF程序UnitTest发生错误的解决办法
    静态代码分析工具
    编程的苦恼
    error: access denied for user to path
    SortableObservableCollection<T>
    OBIEE Reporting Guidelines
    WPF 刷新画面
    编程为什么有趣?
    MultiMediaTimer
    php 序列化 与 反序列化
  • 原文地址:https://www.cnblogs.com/jpfss/p/11231362.html
Copyright © 2011-2022 走看看