由于机缘巧合,原来要接手做一个和图数据库相关的外包项目。但是由于临近毕业,各种压力大,遂放弃。但是自己还是各种翻墙了解了一番Neo4j,我自己理解的Neo4j就是一个图数据库,它存在的目的就是类似一个引擎,使得一些嵌套级别高的,可以以更快的速度来获取结果。仅仅是个人见解,不知道对不对。发现度娘很难找到自己需要的材料。就各种看官网网站,最后在这文章里找到了一点材料,自己总结一下,有不对的地方,请指出。
1、Neo4j简介
什么是图数据库?
图形数据库是专门存储和检索大量信息的存储引擎。它能高效的存储节点和关系,并且支持高效率的查找这些结构。节点和关系中都可以增加属性,一个节点可以没有标签,也可以有多个标签,关系总是有向的,并且必须被命名。
图形数据库非常适合存储大多数类型的实体模型,在几乎所有的实体中,都存在着从一个实体到另外一个实体之间的关系。在其他建模方法中,事情之间的关系被减少到一直有一个单一的连接,并且没有标识和属性。图数据库支持将域内原有的丰富关系完好地保存到数据库中,而不诉诸于将关系建模为“事物”。将现实域映射到图形数据库时,很少有“阻抗不匹配”。
2、概述
入门
我们首先定义一些实体类和一些可选的注解。我们通过使用注解来映射节点和关系到图数据库中。Spring Data Neo4j 4.1(以下简称SDN 4.1)戏剧化的简化了开发过程。但是一些设置自然还是需要的。为了构建应用,我们的构建工具需要包含Spring Data Neo4j的依赖。并且当构建完成之后,我们的Spring应用配置上Spring Data Neo4j。Spring Data Neo4j 4.x版本之后,不支持配置文件来配置,需要引入注解来配置。这里介绍通过使用Maven来构建该应用。先贴上一张自己新建的maven项目,并且相关的SpringMVC的依赖。
Maven依赖
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<sdn.version>4.1.0.RELEASE</sdn.version>
<neo4j-ogm.version>2.1.0</neo4j-ogm.version>
<neo4j.version>3.1.0</neo4j.version>
<spring.version>4.2.5.RELEASE</spring.version>
<neo4j.ogm.version>2.1.0</neo4j.ogm.version>
</properties>
<dependencies>
<!--Spring-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${spring.version}</version>
</dependency>
<!--SDN-->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-neo4j</artifactId>
<version>${sdn.version}</version>
</dependency>
<!--Neo4j-->
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-kernel</artifactId>
<version>${neo4j.version}</version>
</dependency>
<dependency>
<groupId>org.neo4j.app</groupId>
<artifactId>neo4j-server</artifactId>
<version>${neo4j.version}</version>
</dependency>
<!-- Tests -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-ogm-test</artifactId>
<version>${neo4j-ogm.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.neo4j.test</groupId>
<artifactId>neo4j-harness</artifactId>
<version>${neo4j.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
SDN 4.1默认的使用Http驱动来连接到Neo4j服务器,并且你不需要将它声明在一个独立的依赖中。如果想要使用嵌入式的驱动到你的应用中,那么你必须其他依赖,这里就介绍Http驱动,因为嵌入式的就是用来测试的,想了解嵌入式的方式,可是去查看英文文档。
Spring配置
Spring 4.x之后,不支持使用配置文件来配置,可以使用Java bean配置。建议Spring Context继承来Spring Data Neo4j的Neo4jConfiguration类。并且需要覆写getSessionFactory()和getSession(),以便能够提供需要的上下文。
package com.cjzheng.myfood;
import org.neo4j.ogm.session.Session;
import org.neo4j.ogm.session.SessionFactory;
import org.springframework.context.annotation.*;
import org.springframework.data.neo4j.config.Neo4jConfiguration;
import org.springframework.data.neo4j.repository.config.EnableNeo4jRepositories;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@Configuration
@EnableNeo4jRepositories(basePackages = "com.cjzheng.myfood.repository")
@EnableTransactionManagement
@ComponentScan("com.cjzheng.myfood")
public class AppConfiguration extends Neo4jConfiguration {
@Bean
public SessionFactory getSessionFactory() {
return new SessionFactory("com.cjzheng.myfood.domain");// with domain entity base package(s)
}
@Bean
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
public Session getSession() throws Exception {
return super.getSession();
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
驱动程序
SDN 4.1提供了多种不同的驱动程序,包括http driver、Embedded driver、Bolt driver。默认的SDN将会尝试从classpath中一个被命名为ogm.properties的文件里读取驱动的配置。这里就介绍Http driver,通过Http的形式连接到Neo4j服务器,这种形式适用于客户端-服务端模型。
Properties file
driver=org.neo4j.ogm.drivers.http.driver.HttpDriver
URI=http://user:password@localhost:7474
- 1
- 2
域模型
这里就是简单的一个Actor模型,这里要做的就是简单连接上Neo4j服务器,并且将它保存。所以我们这里不用涉及其他操作。
package com.cjzheng.myfood.domain;
import org.neo4j.ogm.annotation.GraphId;
import org.neo4j.ogm.annotation.NodeEntity;
import org.neo4j.ogm.annotation.Property;
import org.neo4j.ogm.annotation.Relationship;
import java.util.List;
@NodeEntity
public class Actor {
@GraphId
private Long nodeId;
String id;
String name;
public Actor() {
}
public Actor(String id, String name) {
this.id = id;
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
持久层
package com.cjzheng.myfood.repository;
import com.cjzheng.myfood.domain.Actor;
import org.springframework.data.neo4j.repository.GraphRepository;
/**
* Created by zhengchaojie on 2017/1/7/0007.
*/
public interface ActorRepository extends GraphRepository<Actor> {
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
业务层
package com.cjzheng.myfood.service;
import org.neo4j.ogm.session.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* Created by zhengchaojie on 2017/1/13/0013.
*/
@Service
public class Neo4jDBCleaner {
@Autowired
Session session;
public void cleanDb() {
session.purgeDatabase();
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
Spring Junit测试
package com.cjzheng.myfood.test;
import com.cjzheng.myfood.PersistenceContext;
import com.cjzheng.myfood.domain.Actor;
import com.cjzheng.myfood.repository.ActorRepository;
import com.cjzheng.myfood.service.Neo4jDBCleaner;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {PersistenceContext.class})
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
public class Neo4jTest {
@Autowired
ActorRepository actorRepository;
@Autowired
Neo4jDBCleaner cleaner;
@Test
public void databaseShouldBeCleared() {
System.out.println(actorRepository.getClass());
Actor tomHanks = new Actor("1", "Tom Hanks");
actorRepository.save(tomHanks);
cleaner.cleanDb();
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
package com.cjzheng.myfood;
import org.neo4j.ogm.session.Session;
import org.neo4j.ogm.session.SessionFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.neo4j.config.Neo4jConfiguration;
import org.springframework.data.neo4j.repository.config.EnableNeo4jRepositories;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@Configuration
@EnableNeo4jRepositories("com.cjzheng.myfood.repository")
@EnableTransactionManagement
@ComponentScan("com.cjzheng.myfood")
public class PersistenceContext extends Neo4jConfiguration {
@Override
public SessionFactory getSessionFactory() {
return new SessionFactory("com.cjzheng.myfood.domain");
}
@Override
@Bean
public Session getSession() throws Exception {
return super.getSession();
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29