Neo4j-spring data 基本使用一

Neo4j 圖數(shù)據(jù)庫

善于維護(hù)數(shù)據(jù)間的關(guān)系

數(shù)據(jù)對象(節(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)用場景介紹...見其它資料;

開整應(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)對象

// 節(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)系(邊)對象

// 所有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> {

}

測試一波

@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);
}
//測試代碼
    @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

會(huì)存在一個(gè)問題?

如何在保存節(jié)點(diǎn)或者關(guān)系的時(shí)候,做到不重復(fù)(按某個(gè)屬性區(qū)分)創(chuàng)建節(jié)點(diǎn)跟關(guān)系呢?

請聽下回分解...

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容