1.NEO4J简介

NEO4J,NoSql家族中的一员,最早发行的图形数据库,目前依然是主流图形数据库。优点是:图论的数据库实现,对各种图算法做了简易封装,使开发者不再关注于算法的具体实现,可以集中精力于业务的实现。采用java编写,社区版开源,企业版闭源。

2.传统关系型数据库与图形数据库的纠葛

上世纪软硬件的限制使oracle\mysql等一大批数据库应运而生,建立在集合论基础上实现的数据库,通过外键理论在实际上勉强完成了简单的关系。而最早的NEO4J等图形数据库还在开发者的肚子里,关系型数据库之名就这样被抢走了。

3.怎么把neo4j怎么集成到我们的程序中?

场景:A同学被老大安排开发一个关于社交关系的需求,根据A同学多年的开发经验,mysql是肯定做不了的(因为关系型数据库的数学基础是集合论,依靠外键来实现简单的关系,对于深层关系的查询递归将会慢到一个让人无法接受的程度)。百度一下,NEO4J——以图论为基础的数据库,就它了。开始百度怎么往项目中集成NEO4J,A同学发现一个看上去不错的demo,这么多人转发and不要脸的抄袭,应该不错,上去鼓捣一阵,最后发现:咦?怎么报错了,一模一样的啊;卧槽,这锤子不发maven依赖,版本用的不对啊......几小时就这么浪费了,还打击了自己的信心。

引入的方法有很多种,但是spring提供的办法绝对是最简单方便的。怎么看?当然是看官网提供的15min的案例,地址:https://spring.io/guides/gs/accessing-data-neo4j/。怎么找,看下面的截图。

springboot集成neo4j_图形数据库

springboot集成neo4j_NEO4J_02

4.集成步骤截图:

前置条件

1.电脑已正确安装maven、jdk、Eclipse|IDEA

(1)下载neo4j的window解压包。地址:https://neo4j.com/,下载下来的解压包如下:

springboot集成neo4j_图形数据库_03

(2)配置NEO4J_HOME的环境变量。

springboot集成neo4j_图形数据库_04

springboot集成neo4j_NEO4J_05

(3)安装neo4J的服务

cmd命令:

1.neo4j install-service

2.neo4j start

springboot集成neo4j_NEO4JNoSq_06

springboot集成neo4j_图形数据库_07

假如neo4j服务安装失败,也可以用以下命令启动:

neo4j.bat console

springboot集成neo4j_图形数据库_08

查看http://localhost:7474/browser/,账号和密码都是:neo4j,然后修改密码,进入如下页面:

springboot集成neo4j_NEO4J_09

(4)springboot集成neo4j,对比官网demo,下面就放我自己的代码上来:

1.pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>neo4j</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>neo4j</name>
    <description>Demo project for Spring neo4j</description>
 
    <properties>
        <java.version>1.8</java.version>
    </properties>
 
    <dependencies>
        <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>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>
 
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
 
</project>
  1.  

2.application.properties

spring.data.neo4j.uri=bolt://localhost:7687
spring.data.neo4j.username=neo4j
spring.data.neo4j.password=neo4j
  1.  

3.Person实体类

package com.example.neo4j.entity;
 
import java.util.Collections;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
 
import org.neo4j.ogm.annotation.GeneratedValue;
import org.neo4j.ogm.annotation.Id;
import org.neo4j.ogm.annotation.NodeEntity;
import org.neo4j.ogm.annotation.Relationship;
 
@NodeEntity
public class Person {
 
    @Id @GeneratedValue private Long id;
 
    private String name;
 
    private Person() {
        // Empty constructor required as of Neo4j API 2.0.5
    };
 
    public Person(String name) {
        this.name = name;
    }
 
    /**
     * Neo4j doesn't REALLY have bi-directional relationships. It just means when querying
     * to ignore the direction of the relationship.
     * https://dzone.com/articles/modelling-data-neo4j
     */
    @Relationship(type = "TEAMMATE", direction = Relationship.UNDIRECTED)
    public Set<Person> teammates;
 
    public void worksWith(Person person) {
        if (teammates == null) {
            teammates = new HashSet<>();
        }
        teammates.add(person);
    }
 
    public String toString() {
 
        return this.name + "'s teammates => "
                + Optional.ofNullable(this.teammates).orElse(
                Collections.emptySet()).stream()
                .map(Person::getName)
                .collect(Collectors.toList());
    }
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
}
  1.  

4.dao层调用neo4j,jpa的方式:

package com.example.neo4j.repository;
 
import java.util.List;
 
import com.example.neo4j.entity.Person;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.neo4j.annotation.Query;
import org.springframework.data.neo4j.repository.Neo4jRepository;
 
public interface PersonRepository extends Neo4jRepository<Person, Long> {
 
    Person findByName(String name);
 
    List<Person> findByTeammatesName(String name);
 
    @Query(value = "match (Greg:Person) return Greg",
            countQuery= "match (Greg:Person) return count(Greg)")
    Page<Person> getActorsThatActInAmoviesFromTitle( Pageable pageable );
 
    @Query(value ="",countQuery = "")
    List<Person> getAllById();
}
  1.  

5.springboot启动类

package com.example.neo4j;
 
import com.example.neo4j.entity.Person;
import com.example.neo4j.repository.PersonRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.neo4j.repository.config.EnableNeo4jRepositories;
 
import java.util.Arrays;
import java.util.List;
 
 
@SpringBootApplication
@EnableNeo4jRepositories
public class Neo4jApplication {
 
    private final static Logger log = LoggerFactory.getLogger(Neo4jApplication.class);
 
 
    public static void main(String[] args) {
        SpringApplication.run(Neo4jApplication.class, args);
        System.exit(0);
    }
 
    @Bean
    CommandLineRunner demo(PersonRepository personRepository) {
        return args -> {
 
            personRepository.deleteAll();
 
            Person greg = new Person("Greg");
            Person roy = new Person("Roy");
            Person craig = new Person("Craig");
 
            List<Person> team = Arrays.asList(greg, roy, craig);
 
            log.info("Before linking up with Neo4j...");
 
            team.stream().forEach(person -> log.info("\t" + person.toString()));
 
            personRepository.save(greg);
            personRepository.save(roy);
            personRepository.save(craig);
 
            greg = personRepository.findByName(greg.getName());
            greg.worksWith(roy);
            greg.worksWith(craig);
            personRepository.save(greg);
 
            roy = personRepository.findByName(roy.getName());
            roy.worksWith(craig);
            // We already know that roy works with greg
            personRepository.save(roy);
 
            // We already know craig works with roy and greg
 
            log.info("Lookup each person by name...");
            team.stream().forEach(person -> log.info(
                    "\t" + personRepository.findByName(person.getName()).toString()));
 
            List<Person> teammates = personRepository.findByTeammatesName(greg.getName());
            log.info("The following have Greg as a teammate...");
            teammates.stream().forEach(person -> log.info("\t" + person.getName()));
            Page<Person> grag=personRepository.getActorsThatActInAmoviesFromTitle(PageRequest.of(0,5));
            log.info("\t" + grag);
        };
    }
 
}
  1.  

6.启动截图

springboot集成neo4j_图形数据库_10

7.在neo4j控制台查询结果:

springboot集成neo4j_NEO4JNoSq_11