Neo4j 圖數(shù)據(jù)庫(kù)
善于維護(hù)數(shù)據(jù)間的關(guān)系
數(shù)據(jù)對(duì)象(節(jié)點(diǎn))是一種數(shù)據(jù)奥帘,需要單獨(dú)存儲(chǔ)繁调;數(shù)據(jù)節(jié)點(diǎn)間的關(guān)系(邊)也是一種數(shù)據(jù)馁菜,也需要維護(hù)存儲(chǔ)茴扁;
適用于:
存儲(chǔ)維護(hù)數(shù)據(jù)間復(fù)雜的關(guān)系網(wǎng)絡(luò),便于按關(guān)系查詢相應(yīng)數(shù)據(jù)節(jié)點(diǎn)汪疮;
廢話不多說峭火,具體圖論、相關(guān)理論智嚷、應(yīng)用場(chǎng)景介紹...見其它資料卖丸;
開整應(yīng)用干貨
spring-boot 項(xiàng)目 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() {
// 默認(rèn)為bolt,只有從配置文件修改后會(huì)變成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);
}
}
項(xiàng)目結(jié)構(gòu)
image.png
維護(hù)一個(gè)節(jié)點(diǎn)對(duì)象
// 節(jié)點(diǎn)基礎(chǔ)屬性 (這里所有繼承BaseNode的節(jié)點(diǎn)會(huì)自動(dòng)帶上 BaseNode 標(biāo)簽)
public class BaseNode {
@Id
@GeneratedValue
private Long id;
@Labels // 節(jié)點(diǎn)的標(biāo)簽(代表什么類型的節(jié)點(diǎn)) 可以自定義添加多個(gè)
private Set<String> labels = new HashSet<>();
...
// Person節(jié)點(diǎn)
@NodeEntity(label = "Person") // 節(jié)點(diǎn)默認(rèn)標(biāo)簽名為Person
public class Person extends BaseNode {
private Integer userId;
private String userName;
private String userPhone;
...
維護(hù)一個(gè)關(guān)系(邊)對(duì)象
// 所有Neo4j中的節(jié)點(diǎn)、(關(guān)系)邊 都需要有一個(gè)默認(rèn)的id屬性盏道,保存的是Neo4j中自己的數(shù)據(jù)主鍵稍浆,與業(yè)務(wù)無關(guān)
public class BaseRelation {
@Id
@GeneratedValue
private Long id;
...
// 維護(hù)一個(gè)Lover的人(節(jié)點(diǎn))與人(節(jié)點(diǎn))之間關(guān)系
// (p1:Person) -[r:Lover]-> (p2:Person)
@RelationshipEntity(type = "Lover")
public class Lover extends BaseRelation {
@StartNode // 關(guān)系開始的節(jié)點(diǎn)
private Person startNode;
@EndNode // 關(guān)系目標(biāo)的節(jié)點(diǎn)
private Person endNode;
...
節(jié)點(diǎn)的存儲(chǔ)的spring-data 的Repository
public interface LoverRepository extends Neo4jRepository<Lover, Long> {
}
關(guān)系的存儲(chǔ)的spring-data的Repository
public interface PersonRepository extends Neo4jRepository<Person, Long> {
}
測(cè)試一波
@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 結(jié)果
image.png
image.png
testAddNodes結(jié)果
image.png
image.png
來來來,是時(shí)候給他們添加一波復(fù)雜的關(guān)系了
// 先需要把節(jié)點(diǎn)查出來(該方式中規(guī)中矩猜嘱,不太方便衅枫,后邊改進(jìn))
public interface PersonRepository extends Neo4jRepository<Person, Long> {
// 自定義按userName查詢Person節(jié)點(diǎn)的方法 注意方法名稱 findBy**** 必須跟節(jié)點(diǎn)屬性名稱保持一致
public Person findByUserName(String userName);
}
//測(cè)試代碼
@Autowired
private LoverRepository loverRepository;
@Autowired
private PersonRepository personRepository;
@Test
public void addLoverRelations() {
// 為了不重復(fù)創(chuàng)建小紅、小明.... 需要先查詢
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);
}
結(jié)果
image.png
image.png