zoukankan      html  css  js  c++  java
  • Hello World 之Spring Boot 调用图数据库Neo4j

    1. 明日歌
    2. [清]钱鹤滩
    3. 明日复明日,明日何其多!
    4. 我生待明日,万事成蹉跎

    1. 图数据库Neo4j之爱的初体验 ----与君初相识,犹似故人归

    在如今大数据(big data)横行的时代,传统的关系型数据库如oracle,mysql在大数据量,高并发的场景下显得力不从心。于是乎,NoSQL横空出世,如column-based的cassandra数据库,document-based的MongoDB,还有今天介绍的小众的graph-based的图数据数据库Neo4j。

    图数据库名字的由来其实与其在底层的存储方式有关,图数据库并不表示会存储图形,图片等。Neo4j底层会以图的方式把用户定义的节点(nodes)以及关系(relationships)存储起来,Nodes 和 Relationships 包含key/value形式的属性。Nodes通过Relationships所定义的关系相连起来,形成关系型网络结构。通过这种方式,可是高效的实现从某个节点开始,通过节点与节点间关系,找出两个节点间的联系。

    2. Neo4j之爱的再判断----天生我材必有用

    以金庸先生的《神雕侠侣》为例,这里面的人物关系图很复杂,神雕大侠杨过有很多粉丝,他的粉丝又有自己的粉丝(二度人脉),粉丝粉丝又有自己的粉丝……..假设杨大侠从南宋就开了个博客,到如今必定圈粉无数,如果要找到杨过的粉丝和他的六度七度人脉,运用传统的关系型数据库的话,则需要在关系表里存储很多关系数据,成万上亿,百亿,千亿甚至更多。不论用关系型数据库的分库分表技术还是其他优化手段,在复杂度和性能方面都可能会遇到瓶颈。

    而图数据库neo4j运用了图的遍历算法设计,即从一个节点开始,根据其连接的关系,可以快速和方便地找出它的邻近节点,从而具有简单的存储方式和极高的查询性能。

    关于neo4j的更多细节和neo4j server的安装以及用cypher语言创建节点,关系等内容可以参考网上资料(如:https://blog.csdn.net/victory0508/article/details/78414798),本文着重关注Spring boot 2.0 如何简洁的调用neo4j.

    3. Neo4j执Spring boot之手----窈窕淑女,Spring boot好逑

    在我的第一篇博客里介绍了Spring boot 2.0。本文将Spring boot 结合Spring Data,用极少的代码,基本零配置,不用书写任何查询(queries)语句(这里是cypher)实现了Neo4j的增删改查。

    3.1 Neo4j的连接配置

    Spring boot的配置文件默认在src/main/resources下面,支持传统的application.properties 和application.yml

    application.properties版:

    1. spring.data.neo4j.username=neo4j
    2. spring.data.neo4j.password=helloworld

    application.yml版:      

    1. spring:
    2. data:
    3. neo4j:
    4. username: neo4j
    5. password: helloworld

    3.2 实体类(model 

    1. @NodeEntity
    2. public class Legend {
    3. @Id @GeneratedValue private Long id;
    4. private String name;
    5. private Legend() {
    6. // Empty constructor required as of Neo4j API 2.0.5
    7. };
    8. public Legend(String name) {
    9. this.name = name;
    10. }
    11. /**
    12. * Neo4j doesn't REALLY have bi-directional relationships. It just means when querying
    13. * to ignore the direction of the relationship.
    14. * https://dzone.com/articles/modelling-data-neo4j
    15. */
    16. @Relationship(type = "FANS", direction = Relationship.UNDIRECTED)
    17. public Set<Legend> fans;
    18. public void fansWith(Legend legend) {
    19. if (fans == null) {
    20. fans = new HashSet<>();
    21. }
    22. fans.add(legend);
    23. }
    24. public String toString() {
    25. //java 8 stream and optional
    26. return this.name + "'s fans => "
    27. + Optional.ofNullable(this.fans).orElse(
    28. Collections.emptySet()).stream()
    29. .map(Legend::getName)
    30. .collect(Collectors.toList());
    31. }
    32. public String getName() {
    33. return name;
    34. }
    35. public void setName(String name) {
    36. this.name = name;
    37. }
    38. }

    实体类annotated by 注解@NodeEntity,这样当调用保存这个实体时(save方法),会将它保存到neo4j数据库。

    另一个重要的部分是

            @Relationship(type = "FANS", direction = Relationship.UNDIRECTED)

    用来建立关系,UNDIRECTED表示忽略关系的方向性。

    应用程序通过调用fansWith方法,可以将神雕的人物们联系起来。

    3.3 Spring data neo4j

            Spring Data  属于Spring 大家庭,用于简化对数据库的访问,在很多情况下,甚至都不用写任何queries就可以实现对数据库的各种操作。 

    1. import org.springframework.data.repository.CrudRepository;
    2. public interface LegendRepo extends CrudRepository<Legend, Long> {
    3. Legend findByName(String name);
    4. }

     CrudRepository 是关键,它封装常用的如保存,更新等操作。

    上面的findByName方法表示用name来查询。name必须是实体类的一个属性。在关系型数据库里,spring data会自己将他转化成 select * from table where name=?。而neo4j使用cypher语言,类似转化成查询语句

    1. MATCH (n:`Legend`) WHERE n.`name` = { `name_0` } WITH n RETURN n,
    2. [ [ (n)-[r_f1:`FANS`]-(l1:`Legend`) | [ r_f1, l1 ] ] ], ID(n) with params {name_0=杨过}

    如果要表达Or或者And关系(假设legend有属性level),方法名将会是

    findByNameAndLevel(String name,String level)

    如果要分页,需要继承PagingAndSortingRepository,而不是CrudRepository 。有关springdata的更多细节,笔者将会在以后的博客中详细介绍。

    3.4 Spring boot 启动类 

    1. @SpringBootApplication
    2. @EnableNeo4jRepositories
    3. public class SpringBootNeo4jApplication {
    4. public static void main(String[] args) {
    5. SpringApplication.run(SpringBootNeo4jApplication.class, args);
    6. }
    7. }

    这里的注解@EnableNeo4jRepositories告诉spring boot程序使用neo4j repository。

    3.5 Spring boot 测试类 

     开发工具Spring tool suites自动会生成测试类,添加自己的逻辑代码,保存三个节点:杨过,小龙女和郭襄。

    然后建立她们之间的关系,小龙女和郭襄均是杨过的粉丝。最后查询出杨过的粉丝。

    1. @RunWith(SpringRunner.class)
    2. @SpringBootTest
    3. public class SpringBootNeo4jApplicationTests {
    4. @Autowired
    5. LegendRepo legendRepo;
    6. private final static Logger log = LoggerFactory.getLogger(SpringBootNeo4jApplicationTests.class);
    7. @Test
    8. public void contextLoads() {
    9. legendRepo.deleteAll();
    10. Legend yangguo = new Legend("杨过");
    11. Legend dragonGirl = new Legend("小龙女");
    12. Legend guoxiang = new Legend("郭襄");
    13. List<Legend> team = Arrays.asList(yangguo, dragonGirl, guoxiang);
    14. log.info("Before linking up with Neo4j...");
    15. //java 8 stream
    16. team.stream().forEach(legend -> log.info(" " + legend.toString()));
    17. legendRepo.save(yangguo);
    18. legendRepo.save(dragonGirl);
    19. legendRepo.save(guoxiang);
    20. yangguo = legendRepo.findByName(yangguo.getName());
    21. yangguo.fansWith(dragonGirl);
    22. yangguo.fansWith(guoxiang);
    23. legendRepo.save(yangguo);
    24. dragonGirl = legendRepo.findByName(dragonGirl.getName());
    25. dragonGirl.fansWith(guoxiang);
    26. // We already know that dragonGirl is a fan of yangguo
    27. legendRepo.save(dragonGirl);
    28. // We already know guoxiang fans with yangguo and dragongirl
    29. log.info("Look up yangguo's fans ...");
    30. log.info(legendRepo.findByName("杨过").toString());
    31. }
    32. }

    运行代码查看日志:

    Look up yangguo's fans ...
    Request: MATCH (n:`Legend`) WHERE n.`name` = { `name_0` } WITH n RETURN n,[ [ (n)-[r_f1:`FANS`]-(l1:`Legend`) | [ r_f1, l1 ] ] ], ID(n) with params {name_0=杨过}
     杨过's fans => [郭襄, 小龙女]
    
    4. Neo4j与Spring boot----一生一代一双人

    Neo4j在某些场合能发挥自己的优势,而用spring boot的方式,使得neo4j的使用非常简单,自从有了spring boot,生活变得好轻松。

    关注spring boot,请继续关注我的博客。


    原文地址:https://blog.csdn.net/weixin_41897365/article/details/79835319
  • 相关阅读:
    手把手教你利用create-nuxt-app脚手架创建NuxtJS应用
    初识NuxtJS
    webpack打包Vue应用程序流程
    用选择器代替表格列的筛选功能
    Element-UI
    Spectral Bounds for Sparse PCA: Exact and Greedy Algorithms[贪婪算法选特征]
    Sparse Principal Component Analysis via Rotation and Truncation
    Generalized Power Method for Sparse Principal Component Analysis
    Sparse Principal Component Analysis via Regularized Low Rank Matrix Approximation(Adjusted Variance)
    Truncated Power Method for Sparse Eigenvalue Problems
  • 原文地址:https://www.cnblogs.com/jpfss/p/11231415.html
Copyright © 2011-2022 走看看