[Microservices] Detailed explanation of the use of springboot integrated neo4j

I. Introduction

In the previous article, we learned about the use of neo4j in detail, from construction to related grammatical operations. This article follows the previous content to talk in detail about how to integrate and use neo4j in springboot applications.

2. Spring Data Neo4j

Similar to many other middleware, they all provide jpa-like methods for integrating with springboot, such as the familiar springdata-jpa, jpa for operating es, jpa for operating mongo, etc. Neo4j also provides a jpa method for integrating with springboot. , that is, Spring Data Neo4j. Next, we will demonstrate how to integrate and use Spring Data Neo4j in springboot.

3. Environmental preparation

To build the neo4j service in advance, refer to the previous article for detailed building steps;

springboot version, 2.3.5;

Prepare a springboot project in advance;

4. Integration steps

Follow the steps below

4.1 Import necessary maven dependencies

    <dependencies>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.15</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>${boot-web.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-neo4j</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>${lomok.version}</version>
        </dependency>
    </dependencies>

4.2 Add configuration file

For more configurations, please refer to the official website. The basic continuous configuration is given below.

server.port=8088

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

4.3 Custom node and entity class mapping

For example, in this demonstration case, there are two node operation objects, namely Person and PersonRelation. There is a certain relationship between the two, and then the relevant crud operations are completed through the program.

Custom Person class

@Data
@Builder
@NodeEntity("person")
public class Person implements Serializable {
    @Id
    @GeneratedValue
    private Long id;

    @Property("name")
    private String name;
}

PersonRelation class

@Data
@NoArgsConstructor
@RelationshipEntity(type = "徒弟")
public class PersonRelation implements Serializable {
    @Id
    @GeneratedValue
    private Long id;
    @StartNode
    private Person parent;
    @EndNode
    private Person child;
    @Property
    private String relation;
    
    public PersonRelation(Person parent, Person child, String relation) {
        this.parent = parent;
        this.child = child;
        this.relation = relation;
    }
}

4.4 Custom jpa

Customize the Repository of the two operation node objects respectively and inherit the Neo4jRepository interface. Students who have developed using jpa should be familiar with this.

PersonRepository 

public interface PersonRepository extends Neo4jRepository<Person,Long> {

    /**
     * 查询某个节点的所有子节点
     * @param pId
     * @return
     */
    @Query("Match (p:person) -[*]->(s:person) where id(p)={0} return s")
    List<Person> findChildList(Long pId);

    @Query("Match (p:person {name:{0}}) -[*]->(s:person) return s")
    List<Person> findChildList(String name);

    /**
     * 查询当前节点的父节点
     * @param name
     * @return
     */
    @Query("Match (p:person) -[*]->(s:person {name:{0}}) return p")
    List<Person> findParentList(String name);

    List<Person> findByName(String name);

}

PersonRelationRepository

public interface PersonRelationRepository  extends Neo4jRepository<PersonRelation,Long> {

}

5. Integration testing

Next, write a unit test to test the effect of the above code.

5.1 Save Person and relational data

import com.congge.entity.Person;
import com.congge.entity.PersonRelation;
import com.congge.repository.PersonRelationRepository;
import com.congge.repository.PersonRepository;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;

@SpringBootTest
@RunWith(SpringRunner.class)
public class PersonTest {

    @Autowired
    private PersonRepository personRepository;

    @Autowired
    private PersonRelationRepository personRelationRepository;

    @Test
    public void testSave() {
        Person person = Person.builder().name("唐僧").build();
        Person person2 = Person.builder().name("孙悟空").build();
        Person person3 = Person.builder().name("猪八戒").build();
        Person person4 = Person.builder().name("沙僧").build();
        Person person5 = Person.builder().name("白龙马").build();
        List<Person> personList = new ArrayList<>(Arrays.asList(
                person, person2, person3, person4, person5));
        personRepository.saveAll(personList);
        System.out.println("person 数据保存成功");

        PersonRelation personRelation = new PersonRelation(person, person2, "徒弟");
        PersonRelation personRelation2 = new PersonRelation(person, person3, "徒弟");
        PersonRelation personRelation3 = new PersonRelation(person, person4, "徒弟");
        PersonRelation personRelation4 = new PersonRelation(person, person5, "徒弟");
        List<PersonRelation> personRelationList = new ArrayList<>(Arrays.asList(
                personRelation, personRelation2, personRelation3,
                personRelation4
        ));
        // 保存关系数据
        personRelationRepository.saveAll(personRelationList);
        System.out.println("person 关系数据保存成功");
    }

}

Run the above code

After successful execution, you can go to the web interface to check the data you just saved.

5.2 Query data

@Test
    public void testDelete(){
        // 删除所有person节点
        personRepository.deleteAll();
        // 删除所有personRelation关系数据
        personRelationRepository.deleteAll();
        //根据id删除
        personRepository.deleteById(0l);
    }

    /**
     * 查询所有
     */
    @Test
    public void testFindAll() {
        Iterable<Person> allPerson = personRepository.findAll();
        allPerson.forEach(item -> {
            System.out.println(item.getId());
            System.out.println(item.getName());
            System.out.println();
        });
    }

    /**
     * 根据id查询
     */
    @Test
    public void testFindById() {
        Optional<Person> personOptional = personRepository.findById(0l);
        if (personOptional.isPresent()) {
            System.out.println(personOptional.get().getName());
        }
    }

    /**
     * 分页查询
     */
    @Test
    public void testPage() {
        //设置分页、排序条件,page从0开始
        PageRequest pageRequest = PageRequest.of(1, 2, Sort.by(Sort.Order.desc("id")));
        Page<Person> page = personRepository.findAll(pageRequest);
        page.getContent().forEach(person -> {
            System.out.println(person.getId() + ":" + person.getName());
        });
    }


    @Test
    public void testFindByName() {
        List<Person> personList = personRepository.findByName("唐僧");
        for(Person p : personList){
            System.out.println(p.getName());
        }
    }

If the commonly used methods in jpa still cannot meet the requirements, you can try to write custom statements for implementation.

5.3 JPA custom method rules

Use the rules in jpa to perform custom queries. The following summarizes some commonly used jpa usage rules. You can use these APIs to complete the development of some more advanced business scenarios.

Keyword Sample Cypher snippet
After findByLaunchDateAfter(Date date) n.launchDate > date
Before findByLaunchDateBefore(Date date) n.launchDate < date
Containing (String) findByNameContaining(String namePart) n.name CONTAINS namePart
Containing (Collection) findByEmailAddressesContains(Collection  addresses) findByEmailAddressesContains(String  address) ANY(collectionFields IN [addresses] WHERE  collectionFields in n.emailAddresses) ANY(collectionFields IN address WHERE collectionFields  in n.emailAddresses)
In findByNameIn(Iterable  names) n.name IN names
Between findByScoreBetween(double min, double  max) findByScoreBetween(Range  range) n.score >= min AND n.score <=  max Depending on the Range definition n.score >=  min AND n.score <= max or n.score > min AND n.score <  max
StartingWith findByNameStartingWith(String  nameStart) n.name STARTS WITH nameStart
EndingWith findByNameEndingWith(String nameEnd) n.name ENDS WITH nameEnd
Exists findByNameExists() EXISTS(n.name)
True findByActivatedIsTrue() n.activated = true
False findByActivatedIsFalse() NOT(n.activated = true)
Is findByNameIs(String name) n.name = name
NotNull findByNameNotNull() NOT(n.name IS NULL)
Null findByNameNull() n.name IS NULL
GreaterThan findByScoreGreaterThan(double score) n.score > score
GreaterThanEqual findByScoreGreaterThanEqual(double  score) n.score >= score
LessThan findByScoreLessThan(double score) n.score < score
LessThanEqual findByScoreLessThanEqual(double score) n.score <= score
Like findByNameLike(String name) n.name =~ name
NotLike findByNameNotLike(String name) NOT(n.name =~ name)
Near findByLocationNear(Distance distance, Point  point) distance( point(n),point({latitude:lat,  longitude:lon}) ) < distance
Regex findByNameRegex(String regex) n.name =~ regex
And findByNameAndDescription(String name, String  description) n.name = name AND n.description =  description
Or findByNameOrDescription(String name, String  description) n.name = name OR n.description = description  (Cannot be used to OR nested properties)

6. Write at the end of the article

This article summarizes in detail how to integrate and use neo4j in springboot, and demonstrates how to use it through code. Students who are interested in more usages can also study it in depth.

Guess you like

Origin blog.csdn.net/congge_study/article/details/133250138