Neo4j 图数据库
善于维护数据间的关系
数据对象(节点)是一种数据,需要单独存储;数据节点间的关系(边)也是一种数据,也需要维护存储;
适用于:
存储维护数据间复杂的关系网络,便于按关系查询相应数据节点;
废话不多说,具体图论、相关理论、应用场景介绍...见其它资料;
开整应用干货
spring-boot 项目 spring-data jpa 使用neo4j
pom主要依赖
...
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.1.RELEASE</version>
<relativePath />
</parent>
...
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-neo4j</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-ogm-http-driver</artifactId>
</dependency>
...
application.yml配置
spring:
data:
neo4j:
username: neo4j
password: ******(密码)
uri: http://127.0.0.1:7474
Neo4jConfig
package com.fc.neo4j_demo.config;
import org.neo4j.ogm.session.SessionFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.neo4j.repository.config.EnableNeo4jRepositories;
import org.springframework.data.neo4j.transaction.Neo4jTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.support.TransactionTemplate;
@Configuration
@EnableAutoConfiguration
@EnableNeo4jRepositories(basePackages = "com.fc.neo4j_demo.dao.repository")
@EnableTransactionManagement
public class Neo4jConfiguration {
@Bean
public SessionFactory sessionFactory() {
// 默认为bolt,只有从配置文件修改后会变成http
return new SessionFactory(configuration(), "com.fc.neo4j_demo.entity.neo4j");
}
@Value("${spring.data.neo4j.uri}")
private String uri;
@Value("${spring.data.neo4j.username}")
private String name;
@Value("${spring.data.neo4j.password}")
private String password;
@Bean
public org.neo4j.ogm.config.Configuration configuration() {
System.out.println();
org.neo4j.ogm.config.Configuration configuration = new org.neo4j.ogm.config.Configuration.Builder().uri(uri)
.credentials(name, password).build();
return configuration;
}
@Bean("transactionManager")
public Neo4jTransactionManager transactionManager() throws Exception {
return new Neo4jTransactionManager(sessionFactory());
}
@Bean("neo4jTransactionTemplate")
public TransactionTemplate neo4jTransactionTemplate(
@Qualifier("transactionManager") Neo4jTransactionManager neo4jTransactionManager) {
return new TransactionTemplate(neo4jTransactionManager);
}
}
项目结构

image.png
维护一个节点对象
// 节点基础属性 (这里所有继承BaseNode的节点会自动带上 BaseNode 标签)
public class BaseNode {
@Id
@GeneratedValue
private Long id;
@Labels // 节点的标签(代表什么类型的节点) 可以自定义添加多个
private Set<String> labels = new HashSet<>();
...
// Person节点
@NodeEntity(label = "Person") // 节点默认标签名为Person
public class Person extends BaseNode {
private Integer userId;
private String userName;
private String userPhone;
...
维护一个关系(边)对象
// 所有Neo4j中的节点、(关系)边 都需要有一个默认的id属性,保存的是Neo4j中自己的数据主键,与业务无关
public class BaseRelation {
@Id
@GeneratedValue
private Long id;
...
// 维护一个Lover的人(节点)与人(节点)之间关系
// (p1:Person) -[r:Lover]-> (p2:Person)
@RelationshipEntity(type = "Lover")
public class Lover extends BaseRelation {
@StartNode // 关系开始的节点
private Person startNode;
@EndNode // 关系目标的节点
private Person endNode;
...
节点的存储的spring-data 的Repository
public interface LoverRepository extends Neo4jRepository<Lover, Long> {
}
关系的存储的spring-data的Repository
public interface PersonRepository extends Neo4jRepository<Person, Long> {
}
测试一波
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Neo4jDemoApplication.class)
public class AppTest {
@Autowired
private PersonRepository personRepository;
@Test
public void testAddNode() {
Person save = personRepository.save(new Person(1, "小明", "155***"));
System.out.println(save);
}
@Test
public void testAddNodes() {
Iterable<Person> saveAll = personRepository.saveAll(Arrays.asList(new Person(2, "小伟", "133***"), new Person(3, "小红", "188***"),
new Person(4, "小芳", "186***")));
saveAll.forEach(System.out::println);
}
testAddNode 结果

image.png

image.png
testAddNodes结果

image.png

image.png
来来来,是时候给他们添加一波复杂的关系了
// 先需要把节点查出来(该方式中规中矩,不太方便,后边改进)
public interface PersonRepository extends Neo4jRepository<Person, Long> {
// 自定义按userName查询Person节点的方法 注意方法名称 findBy**** 必须跟节点属性名称保持一致
public Person findByUserName(String userName);
}
//测试代码
@Autowired
private LoverRepository loverRepository;
@Autowired
private PersonRepository personRepository;
@Test
public void addLoverRelations() {
// 为了不重复创建小红、小明.... 需要先查询
Person xm = personRepository.findByUserName("小明");
Person xw = personRepository.findByUserName("小伟");
Person xh = personRepository.findByUserName("小红");
Person xf = personRepository.findByUserName("小芳");
Lover xmLoverxw = new Lover(xm, xw);
Lover xwLoverxh = new Lover(xw, xh);
Lover xhLoverxm = new Lover(xh, xm);
Lover xfLoverxh = new Lover(xf, xh);
Iterable<Lover> saveAll = loverRepository.saveAll(Arrays.asList(xmLoverxw,xwLoverxh,xhLoverxm,xfLoverxh));
saveAll.forEach(System.out::println);
}
结果

image.png

image.png