您的位置:首页 > 文旅 > 美景 > 怎样建设网站优化_郑州建设网站设计_免费发帖推广平台有哪些_seo优化专家

怎样建设网站优化_郑州建设网站设计_免费发帖推广平台有哪些_seo优化专家

2025/2/13 19:37:27 来源:https://blog.csdn.net/yang2330648064/article/details/145554879  浏览:    关键词:怎样建设网站优化_郑州建设网站设计_免费发帖推广平台有哪些_seo优化专家
怎样建设网站优化_郑州建设网站设计_免费发帖推广平台有哪些_seo优化专家

文章目录

  • Spring Data Neo4j简介
    • Neo4j-OGM与SDN的区别
  • 开发体验
    • 版本说明
    • 项目地址
    • 项目结构
    • 创建项目
    • 配置连接信息
    • 激活事务管理器
    • 创建实体类
      • Movie类
      • Person类
      • ActedIn关系类
    • 创建Dao层
    • service层
    • 测试案例
      • CRUD Test
      • PersonService Test
      • ActedIn Test
    • 执行结果查询

Spring Data Neo4j简介

  • Spring Data Neo4j官网学习地址
  • Spring Data Neo4j简称SDN,SDN建立在Neo4j OGM基础之上,使用SDN可以帮助简化OGM的使用,更加容易与Spring框架整合应用。
  • SDN 完全依赖于 Neo4j Java 驱动程序,而无需在映射框架和驱动程序之间引入另一个“驱动程序”或“传输”层。Neo4j Java 驱动程序(有时称为 Bolt 或 Bolt 驱动程序)用作协议,与 JDBC 用于关系数据库非常相似。
  • SDN 是一个对象图映射 (OGM) 库。OGM 将图形中的节点和关系映射到域模型中的对象和引用。对象实例映射到节点,而对象引用使用关系进行映射,或序列化为属性(例如,对 Date 的引用)。JVM 原语映射到节点或关系属性。OGM 抽象了数据库,并提供了一种便捷的方法,可以将域模型持久保存在图形中并对其进行查询,而无需直接使用低级驱动程序。它还为开发人员提供了灵活性,可以在 SDN 生成的查询不足的情况下提供自定义查询。
    在这里插入图片描述
  • 驱动程序用于连接数据库。包括三种连接方式:嵌入式、HTTP、和二进制Bolt。
  • Neo4j对象图映射器(neo4j-OGM)
  • Spring Data Neo4j在Neo4j-OGM上提供代码,帮助快速构建基于Spring的Neo4j应用程序。

Neo4j-OGM与SDN的区别

  • Spring Data Neo4i(SDN)使用Neo4j-OGM执行与数据库之间的映射。在Spring Data JPA的上下文中,可以将OGM与Hibernate之类的PA实现在同一级别上看待。

开发体验

版本说明

组件版本
Spring Boot3.4.2
neo4j5.26.1
IDEA2024.2.1
spring-data-neo4j7.4.2

项目地址

  • SpringAndNeo4j

项目结构

.
├── pom.xml
├── src
│   ├── main
│   │   ├── java
│   │   │   └── com
│   │   │       └── yang
│   │   │           └── stu
│   │   │               ├── StuApplication.java
│   │   │               ├── configuration
│   │   │               │   └── Neo4jConfiguration.java
│   │   │               ├── pojo
│   │   │               │   ├── ActedIn.java
│   │   │               │   ├── Movie.java
│   │   │               │   ├── Person.java
│   │   │               │   └── PersonInfo.java
│   │   │               ├── repository
│   │   │               │   ├── ActedRepository.java
│   │   │               │   ├── MovieRepository.java
│   │   │               │   └── PersonRepository.java
│   │   │               └── service
│   │   │                   └── PersonService.java
│   │   └── resources
│   │       └── application.properties
│   └── test
│       └── java
│           └── com
│               └── yang
│                   └── stu
│                       ├── ActedInRepositoryTest.java
│                       ├── PersonServiceTest.java
│                       └── StuApplicationTests.java

创建项目

在这里插入图片描述
在这里插入图片描述

配置连接信息

spring.application.name=Stu
spring.neo4j.uri=bolt://IP:7687
spring.neo4j.authentication.username=neo4j
spring.neo4j.authentication.password=neo4j
spring.neo4j.pool.max-connection-pool-size=1000
spring.neo4j.pool.max-connection-lifetime=2h
logging.level.org.springframework.data.neo4j=ERROR

激活事务管理器

import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;@Configuration
@EnableTransactionManagement //激活事务管理器
public class Neo4jConfiguration {}

创建实体类

Movie类

import lombok.*;
import org.springframework.data.neo4j.core.schema.*;import java.io.Serializable;
import java.util.List;@Node //spring-data-neo4j 7.4.2中使用Node注解标记实体类
@NoArgsConstructor
@ToString
@Data 
public class Movie implements Serializable {@Id@GeneratedValueprivate Long id;private String title;private Long released;@Property("tagline")private String tagLine;//设置关系并且指定方向@Relationship(type = "ACTED_IN",direction = Relationship.Direction.INCOMING)private List<ActedIn> actedIns;
}    

Person类

import lombok.*;
import org.springframework.data.neo4j.core.schema.*;
import java.io.Serializable;
import java.util.List;@Node
@Data
@ToString
public class Person implements Serializable {@Id@GeneratedValueprivate Long id;private String name;private Long born;private String sex;@Relationship(type = "ACTED_IN",direction = Relationship.Direction.OUTGOING)private List<ActedIn> actedIns;//导演关系@Relationship(type = "DIRECTED")private List<Movie> directedMovies;//出品关系@Relationship(type = "PRODUCED")private List<Movie> producedMovies;//写作关系@Relationship(type = "WROTE")private List<Movie> wroteMovies;
}

ActedIn关系类

  • 使用
import lombok.*;
import org.springframework.data.neo4j.core.schema.GeneratedValue;
import org.springframework.data.neo4j.core.schema.Id;
import org.springframework.data.neo4j.core.schema.RelationshipProperties;
import org.springframework.data.neo4j.core.schema.TargetNode;@RelationshipProperties
@ToString(exclude = {"person","movie"})
@Data
public class ActedIn {@Id@GeneratedValueprivate Long id;//关系中的开始节点 自动推断不用注解private Person person;@TargetNode  //关系中的结束节点 使用注解TargetNodeprivate Movie movie;private String[] roles;
}    

创建Dao层

  • Repository 是一个重要的组件,用于定义与 Neo4j 数据库的交互。管理实体的 CRUD(创建、读取、更新、删除)操作。
  • Dao层的作用:
    • 数据访问层:Repository 作为一个接口,负责定义数据访问层,其中的方法通常与实体的数据库操作(例如存储、查找、更新和删除)相关联。
    • 自动化 CRUD 操作:通过继承 Neo4jRepository<ActedIn, Long>,XRepository 自动获得一些基本的 CRUD 方法,如 save(), findById(), delete(), 以及可以通过定义其他方法实现查询功能。
    • 自定义查询:除了继承基本的 CRUD 方法,还可以在 XRepository 中定义查询方法
  • @Repository 注解:这个注解表明这是一个 DAO(数据访问对象) 类;Spring 会自动识别这个类,并进行相关的异常转换。
import com.yang.stu.pojo.ActedIn;
import org.springframework.data.neo4j.repository.Neo4jRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface ActedRepository extends Neo4jRepository<ActedIn,Long> {}
import com.yang.stu.pojo.Movie;
import org.springframework.data.neo4j.repository.Neo4jRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface MovieRepository extends Neo4jRepository<Movie, Long> {Movie findByTitle(String 西红柿首富);
}

import com.yang.stu.pojo.Person;
import com.yang.stu.pojo.PersonInfo;
import org.springframework.data.neo4j.repository.Neo4jRepository;
import org.springframework.data.neo4j.repository.query.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;import java.util.List;@Repository
public interface PersonRepository extends Neo4jRepository<Person,Long> {Person findByName(String name);List<Person> findByNameContains(String tom);@Query("match (m:Movie) <-[:ACTED_IN]-(p) where m.title=$movieName return p")List<Person> findByMovie(@Param("movieName") String movieName);@Query("match (n:Person {name:$name})-[:ACTED_IN]->(x) return n.name as name,$year-n.born as age,collect(x) as movies")PersonInfo findAgeAndMovieCountByName(@Param("name") String name, @Param("year") Integer year);
}

service层

import com.yang.stu.pojo.Person;
import com.yang.stu.repository.PersonRepository;
import jakarta.annotation.Resource;
import jakarta.transaction.Transactional;
import org.springframework.stereotype.Service;import java.util.List;
import java.util.Random;@Service
public class PersonService {@Resourceprivate PersonRepository personRepository;@Transactional //使用事务注解 确保操作的原子性public void addSexToAllPerson(){List<Person> personList = personRepository.findAll();String[] sexs = {"man", "woman"};for (Person person : personList) {person.setSex(sexs[new Random().nextInt(2)]);personRepository.save(person);}}
}

测试案例

CRUD Test

  • 普通的CRUD操作
@SpringBootTest
class StuApplicationTests {@Autowiredprivate PersonRepository personRepository;@Resourceprivate MovieRepository movieRepository;@Testpublic void existPersonById() {boolean exists = personRepository.existsById(34L);System.out.println(exists);}@Testpublic void queryPersonAll() {List<Person> personList = personRepository.findAll();personList.forEach(x-> System.out.println(x.toString()));}@Testpublic void queryPersonById() {Optional<Person> optionalPerson = personRepository.findById(34L);System.out.println(optionalPerson.get().getName());}@Testpublic void queryPersonByName() {String name = "Tom Hanks";  // 假设我们要查询的名字是“张三”Person person = personRepository.findByName(name);System.out.println(person);}@Testpublic void queryMovieById() {Optional<Movie> optionalMovie = movieRepository.findById(32L);System.out.println(optionalMovie.get().getTitle());}@Testpublic void findByNameContains() {List<Person> personList = personRepository.findByNameContains("Tom");personList.forEach(x-> System.out.println(x.toString()));}@Testpublic void testFindPage(){PageRequest pageRequest = PageRequest.of(0, 10, Sort.by(Sort.Order.asc("name")));Page<Person> page = personRepository.findAll(pageRequest);List<Person> personList = page.getContent();System.out.println("数据总量 :"+page.getTotalElements());System.out.println("总页数 :"+page.getTotalPages());personList.forEach(x-> System.out.println(x.toString()));}@Testpublic void fineActorsByMovieName(){List<Person> actors = personRepository.findByMovie("Johnny Mnemonic");actors.forEach(x-> System.out.println(x.toString()));}@Testpublic void findAgeAndMovieCountByName(){PersonInfo result = personRepository.findAgeAndMovieCountByName("Tom Hanks", 2025);System.out.println(result);}@Testpublic void savePerson(){Person person = new Person();person.setName("沈崇");person.setBorn(1980L);Person savedPerson = personRepository.save(person);System.out.println(savedPerson);}@Testpublic void SaveMovie(){Movie movie = new Movie();movie.setTitle("西红柿首富");movie.setReleased(2019L);movie.setTagLine("搞笑");Movie savedMovie = movieRepository.save(movie);System.out.println(savedMovie);}@Testpublic void findByName(){Movie movie = movieRepository.findByTitle("西红柿首富");System.out.println(movie);}@Testpublic void UpdataMovie(){Movie movie = movieRepository.findByTitle("西红柿首富");movie.setReleased(2018L); //更新值Movie saved = movieRepository.save(movie);System.out.println(saved);}/*** 根据id删除*/@Testpublic void deleteMovieById(){movieRepository.deleteById(32L);}/*** 根据实体删除*/@Testpublic void deleteMovieByTitle(){Movie movie = movieRepository.findByTitle("西红柿首富");movieRepository.delete(movie);}
}

PersonService Test

  • 测试PersonService添加性别的方法
@SpringBootTest
public class PersonServiceTest {@Resourceprivate PersonService personService;@Testpublic void testAddSex() {personService.addSexToAllPerson();}
}

ActedIn Test

  • 测试级联保存和批量保存
@SpringBootTest
public class ActedInRepositoryTest {@Resourceprivate PersonRepository personRepository;@Resourceprivate MovieRepository movieRepository;@Testpublic void saveActed() {// 查询 Person 和 Movie 节点Person person = personRepository.findByName("沈崇");Movie movie = movieRepository.findByTitle("西红柿首富");// 创建关系ActedIn actedIn = new ActedIn();actedIn.setPerson(person);actedIn.setMovie(movie);actedIn.setRoles(new String[]{"王多鱼"});// 将 ActedIn 添加到 Person 的关系列表中List<ActedIn> actedIns = person.getActedIns();actedIns.add(actedIn);person.setActedIns(actedIns);// 保存 Person,实现级联保存personRepository.save(person);}@Testpublic void saveAll(){Movie movie = movieRepository.findByTitle("西红柿首富");List<Person> personList=new ArrayList<>();Person person = new Person();person.setName("艾伦");person.setBorn(1981L);ActedIn actedIn = new ActedIn();actedIn.setPerson(person);actedIn.setMovie(movie);actedIn.setRoles(new String[]{"高然"});person.setActedIns(Arrays.asList(actedIn));personList.add(person);Person person2 = new Person();person2.setName("张一鸣");person2.setBorn(1986L);ActedIn actedIn2 = new ActedIn();actedIn2.setPerson(person2);actedIn2.setMovie(movie);actedIn2.setRoles(new String[]{"庄强"});person2.setActedIns(Arrays.asList(actedIn2));personList.add(person2);List<Person> saveAll = personRepository.saveAll(personList);saveAll.forEach(System.out::println);}
}

执行结果查询

  • 查看参演西红柿首富的演员
match (n:Person)-->(m:Movie) where m.title="西红柿首富" return *

在这里插入图片描述

  • 删除节点和关系
match (n:Movie)<-[r]-(m) where n.title="西红柿首富" delete m,r,n

版权声明:

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

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