• MongoRepository查询数据常用语法


    安装

    查看mongo可用版本

    docker search mongo

    安装指定版本的mogo或者拉取最新版本的镜像

    docker pull mongo:latest

    或者官网下载安装包
    https://www.mongodb.com/try/download/community-kubernetes-operator
    下载完成解压至自己的目录

    tar -zxvf mongodb-macos-x86_64-4.2.18.tgz

    创建mongo数据持久化目录

    sudo mkdir -p /usr/local/var/mongodb

    创建mongo数据库日志目录

    sudo mkdir -p /usr/local/var/log/mongodb

    分配权限

    sudo chown my_mongodb_user /usr/local/var/mongodb
    sudo chown my_mongodb_user /usr/local/var/log/mongodb

    运行mongod服务

    mongod --dbpath /usr/local/var/mongodb --logpath /usr/local/var/log/mongodb/mongo.log --fork

    查看是否启动成功

    ps aux | grep -v grep | grep mongod

    shell操作mongo

    mongo

    初次安装,只有几个默认的数据库

    这里使用spring-boot2.9.4版本.mongo4.2.18
    springboot程序查询mongo可以借助MongoRepository或者MongoTemplate,
    这里的MongoRepository跟spring data jpa很像,由于继承了CrudRepository或者ListCrudRepository和QueryByExampleExecutor所以基本的增删改查操作都可以直接调用方法来实现
    如果使用MongoRepository多字段条件查询时可能会很复杂,使用MongoTemplate查询更为方便,这两者的使用得依靠自己来区分哪种方式更为方便
    比如一般的分页以及排序查询MongoRepository更为方便一些


    而mongoTemplate只能靠mongoTemplate.query()来实现分页的查询

    基础查询

    解析查询的方法名称分为主语和谓语find…By,exists…By),第二部分形成谓词,可以进一步操作如,find(或其他引入关键字)和By之间的任何文本可认为形容词,除非使用结果限制关键字,如Distinct在要创建的查询上设置不同的标志,如根据用户名去重复(findDistinctByUsername)或者使用Top/First来限制查询结果(findFirstByUsername),排序之后取前3条数据(findTop3ByOrderByCreateTimeDesc),多个属性表达式也可以用运算符进行连接AND或者OR,如果比较大小也可以用Between、LessThan、GreaterThan来查询,模糊查询Like

    interface PersonRepository extends Repository {
    
      // 多字段and查询
      List findByEmailAddressAndLastname(EmailAddress emailAddress, String lastname);
    
     // 多字段or查询
      List findByEmailAddressOrPhone(EmailAddress emailAddress, String phone);
    
     // 根据username模糊查询
     List findByUsernameLike(String username);
    
      // 根据lastname或者firstname查询,people属性去重
      List findDistinctPeopleByLastnameOrFirstname(String lastname, String firstname);
      List findPeopleDistinctByLastnameOrFirstname(String lastname, String firstname);
    
      // 忽略大小写
      List findByLastnameIgnoreCase(String lastname);
    
      // 所有属性忽略大小写
      List findByLastnameAndFirstnameAllIgnoreCase(String lastname, String firstname);
    
      // 根据firsetname排序
      List findByLastnameOrderByFirstnameAsc(String lastname);
      List findByLastnameOrderByFirstnameDesc(String lastname);
    
     // 时间范围查询 $lt
      BookInfo findTopByCreateTimeLessThan(LocalDateTime localDateTime);
    
     // 条数查询
      long countByAuthor(String authorName);
    }
    

    如果是多条件查询不想使用jpa一直and,又不想使用mongoTemplate的criteria一直添加条件,可以使用注解org.springframework.data.mongodb.repository.@Query注解进行查询

    /**
         * 自定义查询
         * @param showName
         * @return
         */
        @Query("{showName: ?0}")
        List customQuery(String showName);
    

    Repository中的特殊参数
    除了基本类型参数,还可以支持Pageable和 Sort来进行分页和排序

    Page findByLastname(String lastname, Pageable pageable);
    
    Slice findByLastname(String lastname, Pageable pageable);
    
    List findByLastname(String lastname, Sort sort);
    
    List findByLastname(String lastname, Pageable pageable);
    

    分页查询

    使用Pageable参数来进行分页,使用sort来排序,因为page分页需要根据总数来进行分页计算,判断总共多少页,是否有下一页等等,如果只想分页,不需要知道总共多少页,可使用slice实现,根据属性hasNext判断是否有下一次分页即可,因为计算总页数需要总条数,使用page来接受会额外花费一次count查询


    如果只需要排序,可以在方法参数添加sort,可以使用page也可以使用list接受

    在jpa查询中,如果添加了pageable,但是不想分页查询,最好使用Pageable.unpaged(),如果不想使用排序可以使用Sort.unsorted()

    排序

    定义排序表达式,可以多个条件同时排序

    Sort sort = Sort.by("firstname").ascending().and(Sort.by("lastname").descending());
    

    lambda条件表达式

    TypedSort person = Sort.sort(Person.class);
    Sort sort = person.by(Person::getFirstname).ascending().and(person.by(Person::getLastname).descending());
    

    条数限制

    查询的结果集除了使用分页属性控制返回条数之外我们也可以手动限制指定条数,在find...By中间可以使用其他限制词,比如first或者top关键词来限制查询结果的条数,如果只写first或者top,默认为1条,即findByFirst1 = findByFirst = findByTop

    User findFirstByOrderByLastnameAsc();
    
    User findTopByOrderByAgeDesc();
    
    Page queryFirst10ByLastname(String lastname, Pageable pageable);
    
    Slice findTop3ByLastname(String lastname, Pageable pageable);
    
    List findFirst10ByLastname(String lastname, Sort sort);
    
    List findTop10ByLastname(String lastname, Pageable pageable);
    

    如果是单条查询,如findFirstByOrderByLastnameAsc可以将返回结果使用实体类接受也可以使用Optional来包装

    Optional findFirstByOrderByLastnameAsc();
    

    常用关键词

    关键词 描述
    find…By,read…By,get…By,query…By,search…By,stream…By 一般查询方法通常返回存储库类型
    exists…By 是否存在,返回boolean或Boolean|
    count…By 统计条数|
    delete…By,remove…By 删除方法,无返回结果(void)
    …First…,…Top 将查询结果限制为结果的第一个。此关键字可以出现在主题的任何地方,介于find(和其他关键字)和by。如前两条findTop2By
    …Distinct… 使用不同的查询仅返回唯一的结果介于find(和其他关键字)和by。

    谓词关键词

    逻辑关键字 jpa关键词
    AND And
    OR Or
    AFTER After,IsAfter
    BEFORE Before,IsBefore
    CONTAINING Containing,IsContaining,Contains
    BETWEEN Between,IsBetween
    ENDING_WITH EndingWith,IsEndingWith,EndsWith
    EXISTS Exists
    FALSE False,IsFalse
    GREATER_THAN GreaterThan,IsGreaterThan
    GREATER_THAN_EQUALS GreaterThanEqual,IsGreaterThanEqual
    IN In,IsIn
    IS Is,Equals
    IS_EMPTY IsEmpty,Empty
    IS_NOT_EMPTY IsNotEmpty,NotEmpty
    IS_NOT_NULL NotNull,IsNotNull
    IS_NULL Null,IsNull
    LESS_THAN LessThan,IsLessThan
    LESS_THAN_EQUAL LessThanEqual,IsLessThanEqual
    LIKE Like,IsLike
    NEAR Near,IsNear
    NOT Not,IsNot
    NOT_IN NotIn,IsNotIn
    NOT_LIKE NotLike,IsNotLike
    REGEX Regex,MatchesRegex,Matches
    STARTING_WITH StartingWith,IsStartingWith,StartsWith
    TRUE True,IsTrue
    WITHIN Within,IsWithin

    谓词修饰符关键词

    关键词 描述
    gnoreCase,IgnoringCase 与谓词关键字一起使用,用于不区分大小写的比较
    AllIgnoreCase,AllIgnoringCase 忽略所有合适属性的案例。在查询方法谓词的某个地方使用
    OrderBy… 指定静态排序顺序,然后是属性路径和方向(例如OrderByFirstnameAscLastnameDesc)。

    常用返回类型

    返回类型 描述
    void 没有返回值
    T 一个独特的实体。期望查询方法最多返回一个结果。如果没有找到结果,则返回null。多个结果触发IncorrectResultSizeDataAccessException。
    Iterator
    Collection
    List
    Optional Java 8或GuavaOptional。期望查询方法最多返回一个结果。如果没有找到结果,则返回Optional.empty()或Optional.absent()。多个结果触发IncorrectResultSizeDataAccessException。
    Stream
    Streamable Iterable的便利扩展,直接将方法公开到流、映射和过滤结果,将它们串联等
    Slice 分片
    Page 分页

    repository与mongoTemplate区别

    MongoRepository继承了CRUDCrudRepositorys对于查询操作有默认的抽象类方法,查询或者分页操作使用方便,但是对于修改或者删除数据扩展不太好
    Repository: 仅仅是一个标识,表明任何继承它的均为仓库接口类
    CrudRepository: 继承 Repository,实现了一组 CRUD 相关的方法 
    PagingAndSortingRepository: 继承 CrudRepository,实现了一组分页排序相关的方法 
    MongoRepository: 继承 PagingAndSortingRepository,实现一组 mongodb规范相关的方法
    MongoRepository的缺点是不够灵活,也不能够灵活了,所以但是对于稍微复杂的查询,使用mongoTemplate更为方便,代码更易读

    如果控制台需要打印mogodb查询语句可在配置文件中添加日志级别为debug:

    logging:
      level:
        org:
          springframework:
            data:
              mongodb:
                core: DEBUG
    

    ⚠️注意事项
    1、如果查询结果使用实体类接受如BookInfo或者Optional一定要确保结果唯一,如果有多条会抛出returned non unique result异常,如果不确定多条,可以排序之后使用Top或者First进行条数限制

    2、分页查询PageRequest.of(1, 10)表示查询第二页的10条数据,要注意这里的page实际上是从0开始的,如查询第一页10条PageRequest.of(0, 10),如果一般情况下不需要第二页了简介写法为PageRequest.of(4),表示所有分页前四条结果

    3、像客户端查询接口不需要知道总共有多少页,只需要知道是否有下一页,可以使用Slice接受,减少count查询

    4、如果查询出来的结果为List,且需要对这个list进行进一步的循环操作,请直接使用Iterable<>或Streamable<>接受,减少循环次数

    参考文档
    https://www.mongodb.com/
    https://docs.mongoing.com/mongodb-crud-operations
    https://docs.spring.io/spring-data/mongodb/docs/current/reference/html/#repositories.custom-implementations

    测试案例
    https://github.com/LiuFqiang/mongodb-case.git


    __EOF__

  • 本文作者: 木马不是马
  • 本文链接: https://www.cnblogs.com/LiuFqiang/p/17201345.html
  • 关于博主: 评论和私信会在第一时间回复。或者直接私信我。
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
  • 声援博主: 如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。
  • 相关阅读:
    DevOps 如何帮助前端提升研发效率?
    Text2Cypher:大语言模型驱动的图查询生成
    元学习在小样本学习任务中的应用
    适用Unreal的本地资源检测功能发布
    【学习记录】调试千寻服务+DTU+导远RTK过程的记录
    【微信小程序】scroll-view的基本使用
    Linux常用命令:find、grep、vim、cat、less、more
    为什么计算机对浮点型数字计算存在误差
    带支付的客服系统2.0源码|多语言客服|Saas客服|多商户
    SCI图片制作排版全流程及论文配图规范
  • 原文地址:https://www.cnblogs.com/LiuFqiang/p/17201345.html