Spring Data Neo4j

问题

使用响应式编程方式来访问Neo4j,这里假设已经准备好Neo4j服务器了。

Spring Initializr

https://start.spring.io/
在这个界面初始化工程:
Spring Data Neo4j_第1张图片

application.properties

spring.neo4j.uri=neo4j://localhost:7687
spring.neo4j.authentication.username=neo4j
spring.neo4j.authentication.password=neo4j
spring.data.neo4j.database=neo4j
logging.level.org.springframework.data.neo4j=DEBUG

这里需要稍微了解一下neo4j的两种协议:

  • neo4j://:这种协议主要针对neo4j集群或neo4j节点;
  • bolt://:主要用于管理neo4j单个节点,不支持集群。
    值得注意的是,neo4j+s://,表示使用证书认证;neo4j+ssc://,表示使用自签名证书认证连接数据库。简单来说,+s,表示使用证书加密连接数据库;+ssc,表示使用自定义证书加密连接数据库。
    我们这里使用的neo4j社区版本不支持集群。

domain

PersonEntity.java

package com.example.neo4j3.domain;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.neo4j.core.schema.GeneratedValue;
import org.springframework.data.neo4j.core.schema.Id;
import org.springframework.data.neo4j.core.schema.Node;

@Node("Person")
@Builder
@Data
@NoArgsConstructor
@AllArgsConstructor
public class PersonEntity {
    @Id
    @GeneratedValue
    private Long id;
    private String name;
    private Integer born;
}

MovieEntity.java

package com.example.neo4j3.domain;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.neo4j.core.schema.*;

import java.util.HashSet;
import java.util.Set;

import static org.springframework.data.neo4j.core.schema.Relationship.Direction.INCOMING;

@Node("Movie")
@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
public class MovieEntity {
    @Id
    @GeneratedValue
    private Long id;
    private String title;
    @Property("tagline")
    private String description;
    @Relationship(type = "ACTED_IN", direction = INCOMING)
    private Set<PersonEntity> actors = new HashSet<>();
    @Relationship(type = "DIRECTED", direction = INCOMING)
    private Set<PersonEntity> directors = new HashSet<>();
}

repository

这主要使用ReactiveNeo4jRepository来进行操作neo4j。

MovieRepository.java

package com.example.neo4j3.repository;

import com.example.neo4j3.domain.MovieEntity;
import org.springframework.data.neo4j.repository.ReactiveNeo4jRepository;
import reactor.core.publisher.Mono;

public interface MovieRepository extends ReactiveNeo4jRepository<MovieEntity, Long> {
    Mono<MovieEntity> findOneByTitle(String title);
}

这里需要注意一下,使用响应式编程,如果返回0或1个对象需要使用Mono类包装,如果是返回一个数组需要使用Flux类包装。

PersonRepository.java

package com.example.neo4j3.repository;

import com.example.neo4j3.domain.PersonEntity;
import org.springframework.data.neo4j.repository.ReactiveNeo4jRepository;

public interface PersonRepository extends ReactiveNeo4jRepository<PersonEntity, Long> {
}

controller

MovieController.java

package com.example.neo4j3.controller;

import com.example.neo4j3.domain.MovieEntity;
import com.example.neo4j3.repository.MovieRepository;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import javax.annotation.Resource;

@RestController
@RequestMapping("/movies")
public class MovieController {
    @Resource
    private MovieRepository movieRepository;
    @PutMapping
    Mono<MovieEntity> createOrUpdateMovie(@RequestBody MovieEntity newMovie) {
        return movieRepository.save(newMovie);
    }

    @GetMapping(value = { "", "/" })
    Flux<MovieEntity> getMovies() {
        return movieRepository.findAll();
    }

    @GetMapping("/by-title")
    Mono<MovieEntity> byTitle(@RequestParam String title) {
        return movieRepository.findOneByTitle(title);
    }

    @DeleteMapping("/{id}")
    Mono<Void> delete(@PathVariable Long id) {
        return movieRepository.deleteById(id);
    }
}

Neo4jConfig.java

package com.example.neo4j3.config;

import org.neo4j.driver.Driver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.neo4j.core.ReactiveDatabaseSelectionProvider;
import org.springframework.data.neo4j.core.transaction.ReactiveNeo4jTransactionManager;
import org.springframework.data.neo4j.repository.config.ReactiveNeo4jRepositoryConfigurationExtension;
import org.springframework.transaction.ReactiveTransactionManager;

@Configuration
public class Neo4jConfig {
    @Bean(ReactiveNeo4jRepositoryConfigurationExtension.DEFAULT_TRANSACTION_MANAGER_BEAN_NAME)
    public ReactiveTransactionManager reactiveTransactionManager(
            Driver driver,
            ReactiveDatabaseSelectionProvider databaseNameProvider) {
        return new ReactiveNeo4jTransactionManager(driver, databaseNameProvider);
    }
}

验证

插入1条数据

curl -X "PUT" "http://localhost:8080/movies" \
     -H 'Content-Type: application/json; charset=utf-8' \
     -d $'{
  "title": "Aeon Flux",
  "description": "Reactive is the new cool"
}'
{"id":3,"title":"Aeon Flux","description":"Reactive is the new cool","actors":[],"directors":[]}%

查询所有数据

curl http://localhost:8080/movies
[{"id":3,"title":"Aeon Flux","description":"Reactive is the new cool","actors":[],"directors":[]}]%

条件查询

curl http://localhost:8080/movies/by-title\?title\=Aeon%20Flux
{"id":3,"title":"Aeon Flux","description":"Reactive is the new cool","actors":[],"directors":[]}%

删除数据

curl -X DELETE http://localhost:8080/movies/3

总结

参考:

  • Spring Data Neo4j
  • Document that a reactive transaction manager is not auto-configured with Spring Data Neo4j
  • Different between neo4j:// and bolt://
  • Client applications

你可能感兴趣的:(Neo4j,Spring,Neo4j)