欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 教育 > 锐评 > Neo4j图数据库入门与Spring Boot整合案例

Neo4j图数据库入门与Spring Boot整合案例

2026/2/1 12:06:23 来源:https://blog.csdn.net/qq_40366738/article/details/141786981  浏览:    关键词:Neo4j图数据库入门与Spring Boot整合案例

文章目录

  • 简介
    • 特性
    • 对比
  • 安装(docker容器)
  • 连接数据库
  • Neo4j-CQL语句使用
  • Neo4j整合SpringBoot
    • 创建maven项目并引入依赖
    • 编写数据库层 PersonRepository
    • 编写 PersonService
    • 编写测试类
  • 多标签、多关系、多类型节点使用
    • 创建实体类
    • 编写dao数据库层
    • 编写测试用例

简介

Neo4j是一个开源的NoSQL数据库,使用scala和Java开发。

  • 是世界上最先进的图数据库之一,提供原生的图数据存储、检索、处理
  • 采用属性图模型,极大的完善和丰富图数据模型
  • 专属查询语言Cypher,直观、高效

在这里插入图片描述

特性

1.

对比

为了解决关系型数据库中表示关系需要创建中间表且查询效率低的问题。思想,每个用户看成一个节点,节点和节点之间是有关系的。
在这里插入图片描述
在这里插入图片描述

安装(docker容器)

docker run -d -p 7474:7474 -p 7687:7687 --name neo4j -e "NEO4J_AUTH=neo4j/admin123" -v D/dockerv/neo4j/data:/mydata/data -v D/dockerv/neo4j/logs:/mydata/logs -v D/dockerv/neo4j/conf:/var/lib/neo4j/conf -v D/dockerv/neo4j/import:/var/lib/neo4j/import neo4j

连接数据库

  1. 访问,并输入密码
    http://localhost:7474/browser/
    在这里插入图片描述
  2. 连接成功
    在这里插入图片描述

Neo4j-CQL语句使用

Neo4j的Cypher语言是为处理图形数据而创建的,CQL代表Cypher查询语句。

  • 是Neo4j图形数据库的查询语句
  • 是一种声明式的模糊匹配语句
  • 遵循SQL语法
  • 简单、人性化、可读性高
    在这里插入图片描述

()里面的是节点,[]里面的是关系,{}里面的是属性,>表示关系的方向

-- 创建一个数据模型,A与B是朋友,B与C是朋友,但A听说了C,C不知道A
create (A:Person{name:'huathy'})-[:Friend]->(B:Person{name:'DY'})-[:Friend]->(C:Person{name:'JJ'}), (A)-[:Know]->(C)

在这里插入图片描述

-- 查询A的朋友,名字叫DY的
match (a)-:[:Friend]->(b)
where b.name = 'DY'
return b

在这里插入图片描述

-- 删除标签为Person的
MATCH (p:Person) DETACH DELETE p
-- Deleted 3 nodes, deleted 3 relationships

Neo4j整合SpringBoot

创建maven项目并引入依赖

<dependencies><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.25</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-neo4j</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.34</version><scope>provided</scope></dependency>
</dependencies>

编写数据库层 PersonRepository

package com.hx.neo4j.dao;import com.hx.neo4j.pojo.Person;
import com.hx.neo4j.vo.PersonVo;
import org.springframework.data.neo4j.repository.Neo4jRepository;
import org.springframework.data.neo4j.repository.query.Query;
import org.springframework.stereotype.Repository;
import java.util.List;@Repository
public interface PersonRepository extends Neo4jRepository<Person, Long> {@Query("MATCH (p:user)-[:Friend]->(f:user) WHERE p.name = $name RETURN f")List<Person> findFriendsByName(String name);@Query("MATCH (p:user)-[:Friend]->(f:user) RETURN p.name as personName, collect(f.name) as friends")List<PersonVo> listAllFriendRelationships();}

编写 PersonService

package com.hx.neo4j.service;import com.hx.neo4j.dao.PersonRepository;
import com.hx.neo4j.pojo.Person;
import lombok.RequiredArgsConstructor;
import org.springframework.data.neo4j.core.Neo4jClient;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;import java.util.List;@Service
@RequiredArgsConstructor
public class PersonService {private final PersonRepository personRepository;private final Neo4jClient neo4jClient;@Transactionalpublic void createPersonWithFriend(Person person, Person friend) {person.setFriends(List.of(friend));personRepository.save(friend);// 如果失败,事务会回滚throw new RuntimeException("test rollback");}public List<String> findPersonNamesByCustomLogic() {return (List<String>) neo4jClient.query("MATCH (p:User) WHERE size((p)-[:Friend]->()) >= 1 RETURN p.name").fetchAs(String.class).mappedBy((typeSystem, record) -> record.get("p.name").asString()).all();}
}

编写测试类

package com.hx.neo4j;import cn.hutool.json.JSONUtil;
import com.hx.neo4j.dao.PersonRepository;
import com.hx.neo4j.pojo.KnowShip;
import com.hx.neo4j.pojo.Person;
import com.hx.neo4j.service.PersonService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.Example;import java.util.List;
import java.util.Map;@SpringBootTest
class Neo4jApplicationTests {@Autowiredprivate PersonRepository personRepository;@Autowiredprivate PersonService personService;/*** 测试创建用户与关系*/@Testvoid createUser() {Person personC = Person.builder().name("JJ").build();Person personB = Person.builder().name("DY").friends(List.of(personC)).build();Person personA = Person.builder().name("Huathy").age(18).friends(List.of(personB)).build();personA.setKnowshipList(List.of(KnowShip.builder().person(personC).build()));personRepository.saveAll(List.of(personA, personB));}/*** 测试删除*/@Testvoid deleteUser() {Person personB = Person.builder().name("DY").build();Person personA = Person.builder().name("Huathy").build();personRepository.deleteAll(List.of(personA, personB));}/*** 测试删除所有*/@Testvoid deleteUserAll() {personRepository.deleteAll();}/*** 测试查询所有关系*/@Testvoid listAllFriendRelationships() {Object maps = personRepository.listAllFriendRelationships();System.out.println("maps ==> " + JSONUtil.toJsonPrettyStr(maps));}/*** 测试查询用户*/@Testvoid findUser() {// 采用Spring Data JPA的Example方式,会自动的返回Friends关系Example<Person> example = Example.of(Person.builder().name("Huathy").build());List<Person> all = personRepository.findAll(example);System.out.println("user ==> " + JSONUtil.toJsonPrettyStr(all));// 采用手写CQL语句的方式不会返回关系List<Person> all2 = personRepository.findFriendsByName("Huathy");System.out.println("user2 ==> " + JSONUtil.toJsonPrettyStr(all2));}/*** 测试事务回滚*/@Testvoid createPersonWithFriend() {Person person1 = Person.builder().name("张三").build();Person person2 = Person.builder().name("李四").build();personService.createPersonWithFriend(person1,person2);}/*** Neo4JClient 自定义测试*/@Testvoid findPersonNamesByCustomLogic() {List<String> list = personService.findPersonNamesByCustomLogic();System.out.println("list ==> " + JSONUtil.toJsonPrettyStr(list));}}

多标签、多关系、多类型节点使用

创建实体类

@Node("Company")
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class Company {@Id@GeneratedValueprivate Long id;private String name;
}@Node("Customer")
@Data
public class Customer extends Person {private String contactInfo;@Relationship(type = "BUYS", direction = Relationship.Direction.OUTGOING)private List<Product> products;@Relationship(type = "ASSIGNED_EMPLOYEE", direction = Relationship.Direction.INCOMING)private Employee accountManager; // 反向关系
}@Node({"Person", "Employee"})
@Data
@Accessors(chain = true)
public class Employee extends Person {private String position;@Relationship(type = "WORKS_FOR")private Company company;@Relationship(type = "SERVES", direction = Relationship.Direction.OUTGOING)private List<Customer> customers;}@Node("Product")
@Data
public class Product {@Id@GeneratedValueprivate Long id;private String name;
}

编写dao数据库层

package com.hx.neo4j.dao;import com.hx.neo4j.pojo.Company;
import org.springframework.data.neo4j.repository.Neo4jRepository;
import org.springframework.stereotype.Repository;@Repository
public interface CompanyRepository extends Neo4jRepository<Company, Long> {
}@Repository
public interface CustomerRepository extends Neo4jRepository<Customer, Long> {
}
@Repository
public interface EmployeeRepository extends Neo4jRepository<Employee, Long> {
}
@Repository
public interface ProductRepository extends Neo4jRepository<Product, Long> {
}

编写测试用例

package com.hx.neo4j;import cn.hutool.json.JSONUtil;
import com.hx.neo4j.dao.*;
import com.hx.neo4j.pojo.*;
import com.hx.neo4j.service.PersonService;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.core.annotation.Order;
import org.springframework.data.domain.Example;import java.util.Collections;
import java.util.List;@SpringBootTest
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
class Neo4jApplicationTests2 {@Autowiredprivate ProductRepository productRepository;@Autowiredprivate CompanyRepository companyRepository;@Autowiredprivate CustomerRepository customerRepository;@Autowiredprivate EmployeeRepository employeeRepository;private static Long employeeId;private static Long customerId;/*** 创建公司*/@Test@Order(1)public void testCreateCompany() {Company company = new Company();company.setName("OpenAI");Company saved = companyRepository.save(company);System.out.println(saved.getId());Assertions.assertNotNull(saved.getId());}/*** 员工入职*/@Test@Order(2)public void testEmployeeOnboarding() {Example<Company> companyExample = Example.of(Company.builder().name("OpenAI").build());Company company = companyRepository.findOne(companyExample).orElseThrow();Employee employee = new Employee();employee.setName("Alice");employee.setPosition("Engineer");employee.setCompany(company);Employee saved = employeeRepository.save(employee);employeeId = saved.getNodeId();Assertions.assertNotNull(employeeId);Assertions.assertEquals("Engineer", saved.getPosition());}/*** 创建客户*/@Test@Order(3)public void testAddCustomer() {Customer customer = new Customer();customer.setName("Bob");customer.setContactInfo("bob@example.com");Customer saved = customerRepository.save(customer);customerId = saved.getNodeId();Assertions.assertNotNull(customerId);}/*** 分配客户给员工*/@Test@Order(4)public void testAssignCustomerToEmployee() {Employee employeeParam = new Employee();employeeParam.setName("Alice");Employee employee = employeeRepository.findOne(Example.of(employeeParam)).get();Customer customerParam = new Customer();customerParam.setName("Bob");Customer customer = customerRepository.findOne(Example.of(customerParam)).get();employee.setCustomers(Collections.singletonList(customer));employeeRepository.save(employee);Employee updated = employeeRepository.findOne(Example.of(employeeParam)).get();Assertions.assertFalse(updated.getCustomers().isEmpty());Assertions.assertEquals("Bob", updated.getCustomers().get(0).getName());}/*** 客户购买产品*/@Test@Order(5)public void testCreateProductAndCustomerBuy() {Product product = new Product();product.setName("GPT Box");Product savedProduct = productRepository.save(product);Customer customer = customerRepository.findById(customerId).orElseThrow();customer.setProducts(Collections.singletonList(savedProduct));customerRepository.save(customer);Customer updated = customerRepository.findById(customerId).orElseThrow();Assertions.assertFalse(updated.getProducts().isEmpty());Assertions.assertEquals("GPT Box", updated.getProducts().get(0).getName());}
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词