暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Springboot+Neo4j 分页怎么做?

Neo4j权威指南 2021-05-16
4909
:在neo4j里存在两种分页的方法。第一种是基于Cypher语句,第二种是基于spring data neo4j内置方法,两种方式哪种好,根据自己业务进行选择判断。文末中也会给出两种方式的优缺点。
一、基于Cypher语句分页

需求就是页面分页展示数据,每页多少条,总共多少条数据,总共多少页。我们需要返回总条数total和当前页的数据rows,所以定义接收类结构:

    @Data
    public class Paged<T> {
    private List<T> rows;
    private int total;
    }

    第一种可能大家都会想到,就是利用cypher的skip,limit关键字来分页,和sql分页的原理是一样的。具体写法来看一下,按照创建时间倒排序查询第1页的数据,每页展示10条。获取rows的cypher语句:

      @Query(" match(n) return n " +
      " order by n.createTime desc" +
      " skip 0 limit 10 ")
      List<String> getPagedList();

      然后获取总条数:

        /**
        * 获取总条数,如果有条件需要加上过滤条件
        * @return
        */
        @Query(" match(n) return count(n) ")
        int getTotal();

        这样分别返回结果就可以了,在service层在组装一下,两个结果放在结构体Paged返回就行了。

        二、基于Spring data neo4j 语句分页

        在讲解这种分页方式前,先看下上边的方法@Query(" match(n) return count(n) ")注解里的结构:
          @Retention(RetentionPolicy.RUNTIME)
          @Target({ElementType.METHOD})
          @QueryAnnotation
          @Documented
          public @interface Query {
          String CLASS = "org.springframework.data.neo4j.annotation.Query";
              String VALUE = "value";
              String value() default "";
          String countQuery() default "";
          }
          可以看到这里有个value()参数,同时有一个countQuery()。value()是我们默认写入的参数,countQuery()这个是计算总数的。还记得在文章Springboot+Neo4j 初级增删改查(二)中提到过Neo4j内置提供的一些操作类,包含了分页Page的封装,所以直接引用Page方法,具体实现如下:
            import org.springframework.data.domain.Page;
            import org.springframework.data.domain.Pageable;
            import org.springframework.data.neo4j.annotation.Query;
            import org.springframework.data.neo4j.repository.Neo4jRepository;
            import org.springframework.stereotype.Repository;


            @Repository
            public interface BaseSearchRepository extends Neo4jRepository<CompanyEntryNode, String> {
            /**
            * @param pageable 页码参数
            * @return
            */
            @Query(value = "match(n) return n",
            countQuery = "match(n) return count(n) ")
                Page<String> getPagedList(Pageable pageable);
                }
            从代码中可以看到,没有了第一种的skip、limit,order by 也没有了。因为这些参数通通放在了pageable里了,就是spring data neo4j已经封装好了,只需要在service层把这个参数设置好,并传递给dao层就可以了,service层写法:
               private Page<String> getFullTextSearch(SearchCondition searchCondition) {
                      Pageable pageable=PageRequest.of(searchCondition.getPage,searchCondition.getSize,Sort.by(Sort.Direction.DESC,"createTime"))
                      return baseSearchRepository.getPagedList(pageable);
              }
              返回的数据结构就不需要自己定义paged了。返回的结果如下:
                {
                "code"200,
                "message": "成功响应",
                "data": {
                "content": [//content这个key,对应的就是查询结果,是个数组
                {
                        "id"337  
                }],
                "pageable": { //这个pageable就是我查询时候的那个参数
                      "sort": {//排序条件,如果参数传了分页相关的
                "sorted": false,
                "unsorted": true,
                "empty": true
                },
                "offset": 0,
                "pageNumber": 0,//这个就是页码,从0开始
                "pageSize": 5,//这是每页记录条数
                "unpaged": false,
                "paged": true
                },
                //这里往下就是Page这个接口所含的分页属性,前端取值取这个应该更方便
                "totalElements": 2,//总记录条数
                "totalPages": 1,//总页数
                "last": true,
                "number": 0,//这里跟上面pageable里面是一样的,页码
                "size": 5,//每页记录条数
                "sort": {
                "sorted": false,
                "unsorted": true,
                "empty": true
                },
                "numberOfElements": 2,
                "first": true,
                "empty": false
                },
                "date": 1566197748209
                }
                可以看到pageable就是对应的页码结果,注释说明了一些参数的意思,大家自己看下。
                到此两种方式就讲解完了。优缺点来对比一下:
                Cypher分页:
                优点:返回结构自己定义,比较简单;参数可以封装设置;
                缺点:每次要写两个函数;传参包括页码等信息比较多;
                Spring Data neo4j分页:
                优点:参数传入比较少;只需要定义一个函数;
                缺点:返回结果数据太多,好多不关心数据也返回来出来;还有一个问题是参数的问题,在@Query里面可以使用:#{#对象名.属性名}的方式来传一个对象类型的参数,用这种写法获取到对象中的属性作为参数。这种写法在@Query(value="xxxxx")里面可以用,但在countQuery中是不行的。所以当使用这种方式分页查询时,只能一个一个的传参数进去,用最简单的#{参数名}来匹配参数。

                  

                好了今天的文章就到这里,拜拜!!!


                关于前期引用,注解找不到等问题,参考Springboot+Neo4j maven仓库版本这篇文章。


                - 本期完 -


                有疑问请点赞哈,我会及时回复。由于微信限制了公众号留言功能,有问题你可以直接发公众号聊天,我会在下期文章末尾解答你的问题。


                为方便看最新内容,长按下图图片记得关注哦  


                文章转载自Neo4j权威指南,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                评论