文章目录
- 前言
- 一、neo4j是什么
- 二、开始编码
-
* [1\. yml 配置](about:blank#1_yml__32) - 总结
前言
图数据库先驱者 neo4j:neo4j官网地址
-
可以选择桌面版安装等多种方式,我这里采用的是docker安装
-
直接执行docker安装命令:
docker run -d -p 7474:7474 -p 7687:7687 --name neo4j -e "NEO4J_AUTH=neo4j/password" neo4jchina/neo4j-chs
如果无法下载的话,请更新下docker仓库镜像源地址
- 可以参考 docker镜像源地址
一、neo4j是什么
- Neo4j 是一个高性能、开源的图数据库管理系统,主要用于存储、管理和查询具有复杂关系的数据。它采用属性图模型来处理数据,其中数据被表示为节点(Nodes)和关系(Relationships)的集合,形成了图(Graph)结构。
- Neo4j 使用 Cypher 查询语言,是一种图形查询语言。写的比较好的一遍关于 Cypher语法 的文章
二、开始编码
| 组件 | 版本 |
|---|---|
| springboot | 2.7.6 |
| spring-boot-starter-data-neo4j | 2.7.6 |
| hutool-all | 5.8.4 |
1. yml 配置
server:
port: 8080
spring:
neo4j:
uri: bolt://localhost:7687
authentication:
username: neo4j
password: password
data:
neo4j:
database: neo4j
logging:
level:
org.springframework.data.neo4j: DEBUG
这里连接的是我本地docker 安装的neo4j
有多个端口默认7474为管理页面,7687为服务端口,所以yml这里用7687端口
- 桌面安装也很好用,这里采用windows安装
可以自己新建数据库,而docker中是无法自己创建数据库的
2. crud 测试
- 构思graph 的结构
- 确定多个relation 关系
- 确定各个关系的两个node 节点
首先要规划好这些关系,然后构造出一幅图出来
例如:
这是一个电影关系
- 导演拍摄电影白蛇传
- 白蛇传中有主演 小青 法海
- 主演的穿着
3. node
relation 与java中对象的关系
- 我想构造 node 节点的 人(导演) ,电影(白蛇传) ; 人和电影的 “关系”
分析如下: 人和电影有关系,人和衣服有关系
由于人中的关系较多,所以这里分散下,我把人和电影的关系,放到电影中
这个图中,只有三个node,即是 人 电影 衣服
有三个关系 关系 关系1 穿着
- 我现在构造下 人和电影的关系
-
node 人
@Node("Person")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Person extends BaseNode {
@Id
@GeneratedValue
private Long id;
@Property
private Integer born;
@Property
private String name;
public Person(Integer born, String name) {
this.born = born;
this.name = name;
}
}
2. node 电影
@Data
@Node("Movie")
@NoArgsConstructor
@AllArgsConstructor
public class Movie extends BaseNode {
@Id
@GeneratedValue
private Long id;
@Property
private Integer released;
@Property
private String tagline;
@Property
private String title;
@Relationship(type = "关系", direction = Relationship.Direction.INCOMING)
private List<Relation> relations;
@Relationship(type = "关系1", direction = Relationship.Direction.OUTGOING)
private List<Relation> relationList;
}
将关系放在电影中,电影和人有两种关系, 导演和主演两种关系(这个是relatio 的意义)
“关系” “关系1” 是relation 的type
有两种关系类型,而且每种关系可能有多种,所以这里用集合,如果确认关系为单个,用单个对象也可以
-
relation 关系/ 关系1
@Data
@RelationshipProperties
public class Relation extends BaseRelation {
@Id
@GeneratedValue
private Long id;
private List<String> roles;
@TargetNode
private Person person;
}
这个是关系的定义 relation
由于是任何电影的对应关系,我将关系放到了电影中,所以这里要声明一下目标节点为人 person
-
开始定义人和衣服的关系
@Data
@Node("Clothe")
@NoArgsConstructor
@AllArgsConstructor
public class Clothe extends BaseNode {
@Id
@GeneratedValue
private Long id;
@Property
private String remark;
public Clothe(String name) {
this.remark = name;
}
}
衣服是节点 人是节点 人和衣服是关系
@Node("Person")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Person extends BaseNode {
@Id
@GeneratedValue
private Long id;
@Property
private Integer born;
@Property
private String name;
public Person(Integer born, String name) {
this.born = born;
this.name = name;
}
@Relationship(type = "穿着", direction = Relationship.Direction.OUTGOING)
private List<Chuan> chuanList;
}
改造之前的人,将关系放到人中 chuanList type 为穿着,这里确定一定是多个,一个人可能穿很多件衣服
接下来是 Chuan 的relation 所以内容中应该有目标节点
-
穿的relation
@Data
@RelationshipProperties
public class Chuan extends BaseRelation {
@Id
@GeneratedValue
private Long id;
@Property
private String brand;
@TargetNode
private Clothe clothe;
public Chuan(String brand, Clothe clothe) {
this.brand = brand;
this.clothe = clothe;
}
}
是的,这里有目标节点 Clothe
- 构造完毕
大家可以仔细体会下,这个图和java对象的对应关系,只要理解了,那么后续的图就可以自己构造了~~
4. 编码测试
-
dao层,给出一个示例,剩下都一样,与spring-data-jpa一样
@Repository public interface ClotheRepository extends Neo4jRepository<Clothe, Long> { }
-
测试用例
import cn.hutool.core.collection.CollUtil; import cn.hutool.json.JSONUtil; import com.xuni.neo4j.entity.Clothe; import com.xuni.neo4j.entity.Movie; import com.xuni.neo4j.entity.Person; import com.xuni.neo4j.relation.Chuan; import com.xuni.neo4j.relation.Relation; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest;
import java.util.Arrays; import java.util.List;
/**
- @author fulin
- @since 2024/8/13 9:32
-
- 参考文档
- Spring Data Neo4j
*/ @SpringBootTest @Slf4j class MovieRepositoryTest {
@Autowired private MovieRepository movieRepository; @Autowired private PersonRepository personRepository; @Autowired private RelationRepository relationRepository; /** * // * @see 数据库效果.png * 初始化数据 */ @Test void initData() { Movie movie = new Movie(); movie.setTagline("民间故事"); movie.setTitle("白蛇传"); movie.setReleased(2024); // 吴家骀>>>导演了>>> 白蛇传 Relation relation = new Relation(); relation.setRoles(Arrays.asList("导演", "编剧")); movie.setRelations(Arrays.asList(relation)); Person person = new Person(34, "吴家骀"); relation.setPerson(person); // 白蛇传的主演是法海 Person person1 = new Person(35, "法海"); Relation relation1 = new Relation(); relation1.setRoles(Arrays.asList("主演")); relation1.setPerson(person1); movie.setRelationList(Arrays.asList(relation1)); personRepository.save(person1); personRepository.save(person); movieRepository.save(movie); addRelationship(); } void addRelationship() { Person person1 = new Person(18, "小青"); personRepository.save(person1); Movie movie = movieRepository.findAll().get(0); List<Relation> relationList = movie.getRelationList(); Relation relation1 = new Relation(); relation1.setRoles(Arrays.asList("主演")); relation1.setPerson(person1); relationList.add(relation1); movieRepository.save(movie); addClothe(); } @Autowired private ClotheRepository clotheRepository; void addClothe() { List<Clothe> clotheList = CollUtil.newArrayList(); clotheList.add(new Clothe("T恤")); clotheList.add(new Clothe("牛仔")); clotheList.add(new Clothe("衬衫")); clotheList.add(new Clothe("帽子")); clotheRepository.saveAll(clotheList); Person person = personRepository.findAll().get(2); List<Chuan> chuanList = CollUtil.newArrayList(); chuanList.add(new Chuan("阿迪", clotheRepository.findAll().get(1))); chuanList.add(new Chuan("安踏", clotheRepository.findAll().get(2))); person.setChuanList(chuanList); personRepository.save(person); } /** * 查询所有数据 */ @Test void movieQuery() { List<Movie> movieList = movieRepository.findAll(); log.info("movieList:{}", JSONUtil.toJsonPrettyStr(movieList)); } /** * 删除所有数据 */ @Test void deleteAll() { movieRepository.deleteAll(); personRepository.deleteAll(); relationRepository.deleteAll(); clotheRepository.deleteAll(); } @Test void 单步自定义查询() { // MATCH (n:Movie)-[r:`关系`|`关系1`]-(p:Person) return n,p; // MATCH (n:Movie)-[r:`关系`]-(p:Person) return n,p; List<Movie> movieList = movieRepository.queryMovie(); log.info("movieList:{}", JSONUtil.toJsonPrettyStr(movieList.get(0))); } @Test void 关系自定义查询() { // MATCH ()-->() RETURN count(*); Long count = movieRepository.queryRelations(); log.info("count:{}", count); }}
总结
spring-boot-starter-data-neo4j 2.7.6 与之前的版本使用还是有很多区别的,在网上找了很多,没有找到合适的,自己摸索了两天,搞了一个出来,希望可以帮助到你
本文转自 jimolvxing.blog.csdn.net/article/det…,如有侵权,请联系删除。