IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 【Neo4j权威指南】SpringBoot 集成 Neo4j 教程SDN -> 正文阅读

[Java知识库]【Neo4j权威指南】SpringBoot 集成 Neo4j 教程SDN

一、Neo4j 介绍

Neo4j 采用 JAVA 语言开发,是一个高性能的图形数据库,NOSQL 中的一种,它将结构化数据存储在网络上而不是表中。它是一个嵌入式的、基于磁盘的、具备完全的事务特性的Java持久化引擎。

二、Neo4j 安装

单机版的 Neo4j 安装简单,从官网下载安装包,在 conf 目录下找到 neo4j.conf 配置修改如下配置信息,将注释去掉即可:

dbms.default_listen_address=0.0.0.0
dbms.connector.bolt.enabled=true
dbms.connector.bolt.listen_address=:7687
dbms.connector.http.enabled=true
dbms.connector.http.listen_address=:7474

运行命令启动服务:

./bin/neo4j start    # 启动
./bin/neo4j stop     # 停止服务
./bin/neo4j restart  # 重启服务
./bin/neo4j status   # 查看状态

三、SpringBoot 整合

  1. 引入关键的 Neo4j Maven 坐标
<dependency>
   <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-neo4j</artifactId>
    <exclusions>
        <exclusion>
            <artifactId>neo4j-java-driver</artifactId>
            <groupId>org.neo4j.driver</groupId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>org.neo4j.driver</groupId>
    <artifactId>neo4j-java-driver</artifactId>
    <version>4.4.5</version>
</dependency>
  1. 编写实体和关系类

这里主要用到注解 @Node@Relationship@Property@RelationshipProperties@Id@TargetNode,分别对应的含义是,定义节点、定义关系、定义节点或关系属性、定义关系属性集合、定义SDN的主键、定义关系的另一端节点对象。如下所示:

/**
 * 电影实体类
 * @author ouyangrongtao
 * @since 2022-05-04 12:17
 */
@Data
@NoArgsConstructor
@Node("Movie")
public class MovieEntity {
    @Id
    private String title;

    @Property("description")
    private String description;

    @Relationship(type = "ACTED_IN", direction = Relationship.Direction.OUTGOING)
    private List<Roles> roles;

    @Relationship(type = "DIRECTED", direction = Relationship.Direction.INCOMING)
    private List<PersonEntity> directors;

    public MovieEntity(String title, String description) {
        this.title = title;
        this.description = description;
    }
}

/**
 * 人员实体类
 * @author ouyangrongtao
 * @since 2022-05-04 12:17
 */
@Data
@NoArgsConstructor
@Node("Person")
public class PersonEntity {
    @Id
    private String name;

    @Property("born")
    private Integer born;

    public PersonEntity(Integer born, String name) {
        this.born = born;
        this.name = name;
    }
}

/**
 * 电影-人员关系类
 * @author ouyangrongtao
 * @since 2022-05-04 12:13
 */
@Data
@NoArgsConstructor
@RelationshipProperties
public class Roles {
    @Property("id")
    private Long id;

    @Property("roles")
    private List<String> roleList;

    @TargetNode
    private PersonEntity person;

    public Roles(Long id, PersonEntity person, List<String> roleList) {
        this.id = id;
        this.person = person;
        this.roleList = roleList;
    }
}
  1. 编写repository
    repository 优点类似 jpa,就是继承的类不同。
/**
 * @author ouyangrongtao
 * @since 2022-05-04 12:30
 */
@Repository
public interface MovieRepository extends Neo4jRepository<MovieEntity, String> {

}
  1. 使用 repository 进行操作

/**
 * @author ouyangrongtao
 * @since 2022-05-04 12:50
 */
public interface MovieService {
    void add();
    
    MovieEntity findMovie();
    
    MovieEntity testNeo4jTemplate();
    
    Long count();
}
/**
 * @autho
 * r ouyangrongtao
 * @since 2022-05-04 12:51
 */
@Service
public class MovieServiceImpl implements MovieService {

    private final MovieRepository movieRepository;

    private final Neo4jTemplate neo4jTemplate;

    @Autowired
    public MovieServiceImpl(MovieRepository movieRepository, Neo4jTemplate neo4jTemplate) {
        this.movieRepository = movieRepository;
        this.neo4jTemplate = neo4jTemplate;
    }


    @Override
    public void add() {
        MovieEntity movie = new MovieEntity("我爱我的祖国", "该片讲述了新中国成立70年间普通百姓与共和国息息相关的故事");

        List<Roles> rolesList = new ArrayList<>(8);
        rolesList.add(new Roles(1L, new PersonEntity(1974, "黄渤"), List.of("林治远")));
        rolesList.add(new Roles(2L, new PersonEntity(1978, "张译"), List.of("高远")));
        rolesList.add(new Roles(3L, new PersonEntity(1974, "吴京"), List.of("陈冬冬")));
        rolesList.add(new Roles(4L, new PersonEntity(1985, "杜江"), List.of("朱涛")));
        rolesList.add(new Roles(5L, new PersonEntity(1957, "葛优"), List.of("张北京")));
        rolesList.add(new Roles(6L, new PersonEntity(1997, "刘昊然"), List.of("沃德乐")));

        movie.setRoles(rolesList);
        movie.setDirectors(Collections.singletonList(new PersonEntity(1952, "陈凯歌")));

        movieRepository.save(movie);
    }

    @Override
    public MovieEntity findMovie() {
        return movieRepository.findById("我爱我的祖国").orElse(null);
    }

    @Override
    public MovieEntity testNeo4jTemplate() {
        return neo4jTemplate.findById("我爱我的祖国", MovieEntity.class).orElse(null);
    }

    @Override
    public Long count() {
        return movieRepository.count();
    }
}

四、整合测试

  1. 使用接口进行测试
@GetMapping("/addMovie")
public void addMovie() {
    movieService.add();
}
  1. 单元测试
@SpringBootTest
class MovieServiceImplTest {

    @Autowired
    private MovieService movieService;

    @Test
    void add() {
        movieService.add();
    }

    @Test
    void count() {
        Long count = movieService.count();
        Assertions.assertTrue(count > 0);
    }

    @Test
    void findMovie() {
        MovieEntity movie = movieService.findMovie();
        Assertions.assertNotNull(movie);
    }

    @Test
    void testNeo4jTemplate() {
        MovieEntity movie = movieService.testNeo4jTemplate();
        Assertions.assertNotNull(movie);
    }
}

五、结果验证

  1. 查看 neo4j 数据库结果如下,从图可以看出插入正常;测试用例执行正常表示断言正确,查询返回的内容是期望的。
    在这里插入图片描述

六、过程中遇到的问题记录

org.neo4j.driver.exceptions.DatabaseException: Index traversal aborted due to being stuck in infinite loop. This is most likely caused by an inconsistency in the index. Loop occurred when restarting search from root from page 5. | GB+Tree[file:/mnt/d/tmp/neo4j-community-4.4.6/data/databases/neo4j/neostore.labelscanstore.db, layout:TokenScanLayout[version:0.1, identifier:21483684112629824, fixedSize:true], generation:22/23]
	at org.neo4j.driver.internal.util.Futures.blockingGet(Futures.java:143)
	at org.neo4j.driver.internal.InternalResult.blockingGet(InternalResult.java:128)
	at org.neo4j.driver.internal.InternalResult.hasNext(InternalResult.java:64)
	at org.springframework.data.neo4j.core.DefaultNeo4jClient$DefaultRecordFetchSpec.one(DefaultNeo4jClient.java:329)
	... 98 more
	Suppressed: org.neo4j.driver.internal.util.ErrorUtil$InternalExceptionCause
		at org.neo4j.driver.internal.util.ErrorUtil.newNeo4jError(ErrorUtil.java:85)
		at org.neo4j.driver.internal.async.inbound.InboundMessageDispatcher.handleFailureMessage(InboundMessageDispatcher.java:105)
		at org.neo4j.driver.internal.messaging.common.CommonMessageReader.unpackFailureMessage(CommonMessageReader.java:83)
		at org.neo4j.driver.internal.messaging.common.CommonMessageReader.read(CommonMessageReader.java:59)
		at org.neo4j.driver.internal.async.inbound.InboundMessageHandler.channelRead0(InboundMessageHandler.java:83)
		at org.neo4j.driver.internal.async.inbound.InboundMessageHandler.channelRead0(InboundMessageHandler.java:35)
		at org.neo4j.driver.internal.shaded.io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:99)
		at org.neo4j.driver.internal.shaded.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
		at org.neo4j.driver.internal.shaded.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
		at org.neo4j.driver.internal.shaded.io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
		at org.neo4j.driver.internal.shaded.io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:324)
		at org.neo4j.driver.internal.shaded.io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:296)
		at org.neo4j.driver.internal.async.inbound.MessageDecoder.channelRead(MessageDecoder.java:47)
		at org.neo4j.driver.internal.shaded.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
		at org.neo4j.driver.internal.shaded.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
		at org.neo4j.driver.internal.shaded.io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
		at org.neo4j.driver.internal.shaded.io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:324)
		at org.neo4j.driver.internal.shaded.io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:296)
		at org.neo4j.driver.internal.shaded.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
		at org.neo4j.driver.internal.shaded.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
		at org.neo4j.driver.internal.shaded.io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
		at org.neo4j.driver.internal.shaded.io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
		at org.neo4j.driver.internal.shaded.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
		at org.neo4j.driver.internal.shaded.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
		at org.neo4j.driver.internal.shaded.io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
		at org.neo4j.driver.internal.shaded.io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166)
		at org.neo4j.driver.internal.shaded.io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:719)
		at org.neo4j.driver.internal.shaded.io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:655)
		at org.neo4j.driver.internal.shaded.io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:581)
		at org.neo4j.driver.internal.shaded.io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493)
		at org.neo4j.driver.internal.shaded.io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)
		at org.neo4j.driver.internal.shaded.io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
		at org.neo4j.driver.internal.shaded.io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
		at java.base/java.lang.Thread.run(Thread.java:834)
org.neo4j.driver.exceptions.ServiceUnavailableException: Connection to the database terminated. Please ensure that your database is listening on the correct host and port and that you have compatible encryption settings both on Neo4j server and driver. Note that the default encryption setting has changed in Neo4j 4.0.
		at org.neo4j.driver.internal.util.ErrorUtil.newConnectionTerminatedError(ErrorUtil.java:56) ~[neo4j-java-driver-4.4.0.jar:4.4.0-a44346cddc3aac335fd3d98cf18e489b3790ebee]
		at org.neo4j.driver.internal.util.ErrorUtil.newConnectionTerminatedError(ErrorUtil.java:49) ~[neo4j-java-driver-4.4.0.jar:4.4.0-a44346cddc3aac335fd3d98cf18e489b3790ebee]
		at org.neo4j.driver.internal.async.inbound.ChannelErrorHandler.channelInactive(ChannelErrorHandler.java:74) ~[neo4j-java-driver-4.4.0.jar:4.4.0-a44346cddc3aac335fd3d98cf18e489b3790ebee]
		at org.neo4j.driver.internal.shaded.io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:262) ~[neo4j-java-driver-4.4.0.jar:4.4.0-a44346cddc3aac335fd3d98cf18e489b3790ebee]
		at org.neo4j.driver.internal.shaded.io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:248) ~[neo4j-java-driver-4.4.0.jar:4.4.0-a44346cddc3aac335fd3d98cf18e489b3790ebee]
		at org.neo4j.driver.internal.shaded.io.netty.channel.AbstractChannelHandlerContext.fireChannelInactive(AbstractChannelHandlerContext.java:241) ~[neo4j-java-driver-4.4.0.jar:4.4.0-a44346cddc3aac335fd3d98cf18e489b3790ebee]
		at org.neo4j.driver.internal.shaded.io.netty.handler.codec.ByteToMessageDecoder.channelInputClosed(ByteToMessageDecoder.java:389) ~[neo4j-java-driver-4.4.0.jar:4.4.0-a44346cddc3aac335fd3d98cf18e489b3790ebee]
		at org.neo4j.driver.internal.shaded.io.netty.handler.codec.ByteToMessageDecoder.channelInactive(ByteToMessageDecoder.java:354) ~[neo4j-java-driver-4.4.0.jar:4.4.0-a44346cddc3aac335fd3d98cf18e489b3790ebee]
		at org.neo4j.driver.internal.shaded.io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:262) ~[neo4j-java-driver-4.4.0.jar:4.4.0-a44346cddc3aac335fd3d98cf18e489b3790ebee]
		at org.neo4j.driver.internal.shaded.io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:248) ~[neo4j-java-driver-4.4.0.jar:4.4.0-a44346cddc3aac335fd3d98cf18e489b3790ebee]
		at org.neo4j.driver.internal.shaded.io.netty.channel.AbstractChannelHandlerContext.fireChannelInactive(AbstractChannelHandlerContext.java:241) ~[neo4j-java-driver-4.4.0.jar:4.4.0-a44346cddc3aac335fd3d98cf18e489b3790ebee]
		at org.neo4j.driver.internal.shaded.io.netty.handler.codec.ByteToMessageDecoder.channelInputClosed(ByteToMessageDecoder.java:389) ~[neo4j-java-driver-4.4.0.jar:4.4.0-a44346cddc3aac335fd3d98cf18e489b3790ebee]
		at org.neo4j.driver.internal.shaded.io.netty.handler.codec.ByteToMessageDecoder.channelInactive(ByteToMessageDecoder.java:354) ~[neo4j-java-driver-4.4.0.jar:4.4.0-a44346cddc3aac335fd3d98cf18e489b3790ebee]
		at org.neo4j.driver.internal.shaded.io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:262) ~[neo4j-java-driver-4.4.0.jar:4.4.0-a44346cddc3aac335fd3d98cf18e489b3790ebee]
		at org.neo4j.driver.internal.shaded.io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:248) ~[neo4j-java-driver-4.4.0.jar:4.4.0-a44346cddc3aac335fd3d98cf18e489b3790ebee]
		at org.neo4j.driver.internal.shaded.io.netty.channel.AbstractChannelHandlerContext.fireChannelInactive(AbstractChannelHandlerContext.java:241) ~[neo4j-java-driver-4.4.0.jar:4.4.0-a44346cddc3aac335fd3d98cf18e489b3790ebee]
		at org.neo4j.driver.internal.shaded.io.netty.channel.DefaultChannelPipeline$HeadContext.channelInactive(DefaultChannelPipeline.java:1405) ~[neo4j-java-driver-4.4.0.jar:4.4.0-a44346cddc3aac335fd3d98cf18e489b3790ebee]
		at org.neo4j.driver.internal.shaded.io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:262) ~[neo4j-java-driver-4.4.0.jar:4.4.0-a44346cddc3aac335fd3d98cf18e489b3790ebee]
		at org.neo4j.driver.internal.shaded.io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:248) ~[neo4j-java-driver-4.4.0.jar:4.4.0-a44346cddc3aac335fd3d98cf18e489b3790ebee]
		at org.neo4j.driver.internal.shaded.io.netty.channel.DefaultChannelPipeline.fireChannelInactive(DefaultChannelPipeline.java:901) ~[neo4j-java-driver-4.4.0.jar:4.4.0-a44346cddc3aac335fd3d98cf18e489b3790ebee]
		at org.neo4j.driver.internal.shaded.io.netty.channel.AbstractChannel$AbstractUnsafe$8.run(AbstractChannel.java:831) ~[neo4j-java-driver-4.4.0.jar:4.4.0-a44346cddc3aac335fd3d98cf18e489b3790ebee]
		at org.neo4j.driver.internal.shaded.io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:164) ~[neo4j-java-driver-4.4.0.jar:4.4.0-a44346cddc3aac335fd3d98cf18e489b3790ebee]
		at org.neo4j.driver.internal.shaded.io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:469) ~[neo4j-java-driver-4.4.0.jar:4.4.0-a44346cddc3aac335fd3d98cf18e489b3790ebee]
		at org.neo4j.driver.internal.shaded.io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:497) ~[neo4j-java-driver-4.4.0.jar:4.4.0-a44346cddc3aac335fd3d98cf18e489b3790ebee]
		at org.neo4j.driver.internal.shaded.io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:986) ~[neo4j-java-driver-4.4.0.jar:4.4.0-a44346cddc3aac335fd3d98cf18e489b3790ebee]
		at org.neo4j.driver.internal.shaded.io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[neo4j-java-driver-4.4.0.jar:4.4.0-a44346cddc3aac335fd3d98cf18e489b3790ebee]
		at org.neo4j.driver.internal.shaded.io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) ~[neo4j-java-driver-4.4.0.jar:4.4.0-a44346cddc3aac335fd3d98cf18e489b3790ebee]
		... 1 common frames omitted

在集成的过程中遇到如上的报错信息,特别是org.neo4j.driver.exceptions.DatabaseException: Index traversal aborted due to being stuck in infinite loop. This is most likely caused by an inconsistency in the index 异常,在查询问题所在时发现大家遇到这个问题的人几乎没有,也没有解决方案,但实际是因为neo4j驱动 neo4j-java-driver 的版本与数据库的版本不兼容导致;在遇到第二个问题的时候,也是因为驱动版本的原因,但需要注意配置 spring.neo4j.security.encrypted 需要等于 false

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-05-05 11:04:09  更:2022-05-05 11:06:45 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 0:15:27-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码