springboot2.X 使用spring-data组件对MongoDB做CURD

使用背景

基于快速开发,需求不稳定的情况, 我决定使用MongoDB作为存储数据库,搭配使用spring-data

因为快速开发,使用spring data可以直接在类上建表等其他操作,而且对于复合数据模型,MongoDB可以直接存储

代码地址

gitee

github

入门普通级别

1.引入maven依赖

  1. <dependencies>
  2. <!--###############时间日期操作################-->
  3. <dependency>
  4. <groupId>joda-time</groupId>
  5. <artifactId>joda-time</artifactId>
  6. </dependency>
  7. <dependency>
  8. <groupId>org.springframework.boot</groupId>
  9. <artifactId>spring-boot-starter-data-mongodb</artifactId>
  10. </dependency>
  11. <dependency>
  12. <groupId>cn.hutool</groupId>
  13. <artifactId>hutool-all</artifactId>
  14. </dependency>
  15. <dependency>
  16. <groupId>org.springframework.boot</groupId>
  17. <artifactId>spring-boot-starter</artifactId>
  18. </dependency>
  19. <!--###############springboot-aop模块################-->
  20. <dependency>
  21. <groupId>org.springframework.boot</groupId>
  22. <artifactId>spring-boot-starter-aop</artifactId>
  23. </dependency>
  24. <!--###############test模块################-->
  25. <dependency>
  26. <groupId>org.springframework.boot</groupId>
  27. <artifactId>spring-boot-starter-test</artifactId>
  28. <scope>test</scope>
  29. </dependency>
  30. <!--###############web模块################-->
  31. <dependency>
  32. <groupId>org.springframework.boot</groupId>
  33. <artifactId>spring-boot-starter-web</artifactId>
  34. </dependency>
  35. <!--###############lombok################-->
  36. <dependency>
  37. <groupId>org.projectlombok</groupId>
  38. <artifactId>lombok</artifactId>
  39. </dependency>
  40. <!--fast json-->
  41. <dependency>
  42. <groupId>com.alibaba</groupId>
  43. <artifactId>fastjson</artifactId>
  44. </dependency>
  45. <dependency>
  46. <groupId>com.google.guava</groupId>
  47. <artifactId>guava</artifactId>
  48. </dependency>
  49. </dependencies>

基于maven dependencyManagement 版本控制如下:

  1. <dependencyManagement>
  2. <dependencies>
  3. <dependency>
  4. <groupId>org.springframework.boot</groupId>
  5. <artifactId>spring-boot-dependencies</artifactId>
  6. <version>2.1.2.RELEASE</version>
  7. <type>pom</type>
  8. <scope>import</scope>
  9. </dependency>
  10. <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
  11. <dependency>
  12. <groupId>mysql</groupId>
  13. <artifactId>mysql-connector-java</artifactId>
  14. <version>5.1.48</version>
  15. </dependency>
  16. <dependency>
  17. <groupId>cn.hutool</groupId>
  18. <artifactId>hutool-all</artifactId>
  19. <version>4.5.16</version>
  20. </dependency>
  21. <!--mybatis-->
  22. <dependency>
  23. <groupId>org.mybatis.spring.boot</groupId>
  24. <artifactId>mybatis-spring-boot-starter</artifactId>
  25. <version>2.0.0</version>
  26. </dependency>
  27. <!--fast json-->
  28. <dependency>
  29. <groupId>com.alibaba</groupId>
  30. <artifactId>fastjson</artifactId>
  31. <version>1.2.56</version>
  32. </dependency>
  33. <!-- druid -->
  34. <dependency>
  35. <groupId>com.alibaba</groupId>
  36. <artifactId>druid-spring-boot-starter</artifactId>
  37. <version>1.1.9</version>
  38. </dependency>
  39. <dependency>
  40. <groupId>com.google.guava</groupId>
  41. <artifactId>guava</artifactId>
  42. <version>19.0</version>
  43. </dependency>
  44. </dependencies>
  45. </dependencyManagement>

2.使用docker启动MongoDB

  1. docker run --restart="always" \
  2. -d \
  3. --name mongo\
  4. -p 27017:27017\
  5. -v /docker/mongo/data/db:/data/db\
  6. mongo:latest --storageEngine wiredTiger

3.创建Mongo的实体类

  • @Document(collection="female")

  • 设置id: @Id

  • 设置属性

  • 构建索引

  • getter/setter

Female.java

  1. @Document(collection = "female")
  2. @Data
  3. public class Female {
  4. /**
  5. * 主键
  6. */
  7. @Id
  8. private String id;
  9. /**
  10. * 姓名
  11. */
  12. private String name;
  13. /**
  14. * 年龄
  15. */
  16. private String age;
  17. /**
  18. * 哪种类型的女人;FemaleTypeEnums
  19. */
  20. private Integer type;
  21. /**
  22. * 舔狗
  23. */
  24. private List<Male> dogs;
  25. /**
  26. * 男朋友们
  27. */
  28. @Indexed
  29. private List<Male> boyFriends;
  30. /**
  31. * 男神们
  32. */
  33. @Indexed
  34. private List<Male> dreamers;
  35. /**
  36. * 创建时间
  37. */
  38. @Indexed
  39. private Date createTime;
  40. /**
  41. * 修改时间
  42. */
  43. private Date modifiedTime;
  44. }

4.创建Dao层

  • 创建Repository 继承于MongoRepository

  • 根据规则来编写接口方法, spring data mongodb的dao 方法规则详细查看点这里,理论上用idea会提示出来的.

  • 编写单元测试方法

创建Repository 继承于MongoRepository,编写接口方法

FemaleRepository.java

  1. public interface FemaleRepository extends MongoRepository<Female,String> {
  2. Page<Female> findAllByCreateTimeBetweenAndNameContaining(Date createTime, Date createTime2, String name, Pageable pageable);
  3. Page<Female> findAllByCreateTimeBefore(Date createTime, Pageable pageable);
  4. Page<Female> findAllByCreateTimeAfter(Date createTime, Pageable pageable);
  5. Page<Female> findAllByCreateTimeBetween(Date start, Date end, PageRequest pageRequest);
  6. }

单元测试方法

FemaleRepositoryTest.java

  1. /**
  2. * description: 添加测试数据
  3. * author: suwenguang
  4. * date: 2019-09-01
  5. */
  6. @Test
  7. public void addTestData() {
  8. for (int i = 0; i < 1000; i++) {
  9. Female entity = new Female();
  10. entity.setName(RandomUtil.randomString(12));
  11. LocalDate now = LocalDate.now();
  12. LocalDate localDate = now.minusDays(RandomUtil.randomInt(4));
  13. entity.setCreateTime(localDate.toDate());
  14. femaleRepository.save(entity);
  15. }
  16. }
  17. /**
  18. * description: 测试查询构造器
  19. * author: suwenguang
  20. * date: 2019-09-01
  21. */
  22. public void matching(){
  23. //精确匹配和模糊匹配
  24. Female probe = new Female();
  25. ExampleMatcher matching = ExampleMatcher.matching()
  26. .withMatcher("name", ExampleMatcher.GenericPropertyMatcher.of(ExampleMatcher.StringMatcher.CONTAINING))//模糊匹配
  27. .withIgnorePaths("id")//忽略匹配id
  28. ;
  29. PageRequest of = PageRequest.of(0, 10);
  30. Page<Female> all = femaleRepository.findAll(Example.of(probe, matching), of);
  31. System.out.println(JSON.toJSONString(all));
  32. }
  33. /**
  34. * description: 测试范围查询
  35. * author: suwenguang
  36. * date: 2019-09-01
  37. */
  38. @Test
  39. public void findAllByCreateTimeAfter() {
  40. LocalDate yesteday = new LocalDate().minusDays(3);
  41. PageRequest of = PageRequest.of(0, 10);
  42. List<Female> byCreateTimeAfter = femaleRepository.findAllByCreateTimeAfter(yesteday.toDate(), of);
  43. System.out.println(JSON.toJSONString(byCreateTimeAfter));
  44. }
  45. /**
  46. * description: 测试范围查询
  47. * author: suwenguang
  48. * date: 2019-09-01
  49. */
  50. @Test
  51. public void findByCreateTimeBetween() {
  52. LocalDate localDate = new LocalDate();
  53. Page<Female> byCreateTimeBetween = femaleRepository.findByCreateTimeBetween(localDate.minusDays(2).toDate(), localDate.toDate(), PageRequest.of(0, 10));
  54. System.out.println(JSON.toJSONString(byCreateTimeBetween.getContent()));
  55. }

进阶Querydsl扩展复杂查询

(基于单表的复杂查询,多表复杂查询暂时不纳入讨论范围)

如果按照以上的用法,动态扩展多条件查询仍然不能够完美支持,会导致代码冗余,当然你如果使用mongoTemlate进行自己封装,另当别论.

那么为了实现动态扩展多条件查询,我去查看对应版本的官方文档,跳转点这里,看到可以集成querydsl作为扩展.

步骤

  • 整合querydsl

  • 使用dsl

1.整合querydsl

1.Querydsl官网

2.querydsl集成文档

pom.xml配置引入依赖

  1. <!--###############复杂查询querydsl jpa################-->
  2. <dependency>
  3. <groupId>com.querydsl</groupId>
  4. <artifactId>querydsl-apt</artifactId>
  5. <version>${querydsl.version}</version>
  6. <scope>provided</scope>
  7. </dependency>
  8. <dependency>
  9. <groupId>com.querydsl</groupId>
  10. <artifactId>querydsl-jpa</artifactId>
  11. <version>${querydsl.version}</version>
  12. </dependency>
  13. <!-- <dependency>-->
  14. <!-- <groupId>org.slf4j</groupId>-->
  15. <!-- <artifactId>slf4j-log4j12</artifactId>-->
  16. <!-- <version>1.6.1</version>-->
  17. <!-- </dependency>-->

为什么要注释掉slf4j?

因为我的springboot项目已经引入了slf4j,没必要重复声明,自己可以通过idea的maven dependence查看是否有引入,没有则需要重新引入

2.使用dsl

  • daorepository中继承QuerydslPredicateExecutor<T>

    1. public interface FemaleRepository extends MongoRepository<Female,String>, QuerydslPredicateExecutor<Female> {
    2. }
  • 编写单元测试FemaleRepositoryTest.java

    1. /**
    2. * description: 多条件
    3. * author: suwenguang
    4. * date: 2019-09-01
    5. */
    6. @Test
    7. public void querydsl() {
    8. PageRequest of = PageRequest.of(0, 10);
    9. QFemale female = QFemale.female;
    10. BooleanExpression createTimeBetween = female.createTime.between(LocalDate.now().minusDays(2).toDate(), LocalDate.now().minusDays(1).toDate());
    11. BooleanBuilder builder = new BooleanBuilder(createTimeBetween);
    12. BooleanExpression contains = female.name.contains("3");
    13. builder.and(contains);
    14. Page<Female> all = femaleRepository.findAll(builder,of);
    15. System.out.println(all.getTotalElements());
    16. System.out.println(JSON.toJSONString(all.getContent()));
    17. }

如上所示, 这样子可以动态构造所需要的条件,多个范围查询也可以支持了!!!那么对于后台的搜索数据只需要一个接口就可以了

至于怎么实现,后面再继续整合 X-admin 2.2这个后端模板, 另外出一篇文章吧.

如果对上诉代码有问题或者有其他的扩展性问题,欢迎留下你的评论.

补充

  • BooleanBuilder的类图, 可以通过idea查看,因为findAll是通过父类继承下来的接口, 里面的Predicate也是一个接口,而BooleanExpression和BooleanBuilder都是实现了Predicate的;

springboot2.X 使用spring-data组件对MongoDB做CURD的更多相关文章

  1. 使用Spring访问Mongodb的方法大全——Spring Data MongoDB查询指南

    1.概述 Spring Data MongoDB 是Spring框架访问mongodb的神器,借助它可以非常方便的读写mongo库.本文介绍使用Spring Data MongoDB来访问mongod ...

  2. 使用Spring访问Mongodb的方法大全——Spring Data MongoDB

    1.概述 Spring Data MongoDB 是Spring框架访问mongodb的神器,借助它可以非常方便的读写mongo库.本文介绍使用Spring Data MongoDB来访问mongod ...

  3. 如何在Spring Data MongoDB 中保存和查询动态字段

    原文: https://stackoverflow.com/questions/46466562/how-to-save-and-query-dynamic-fields-in-spring-data ...

  4. spring data jpa实现多条件查询(分页和不分页)

    目前的spring data jpa已经帮我们干了CRUD的大部分活了,但如果有些活它干不了(CrudRepository接口中没定义),那么只能由我们自己干了.这里要说的就是在它的框架里,如何实现自 ...

  5. MongoDB和Java(4):Spring Data整合MongoDB(XML配置)

    最近花了一些时间学习了下MongoDB数据库,感觉还是比较全面系统的,涉及了软件安装.客户端操作.安全认证.副本集和分布式集群搭建,以及使用Spring Data连接MongoDB进行数据操作,收获很 ...

  6. MongoDB分组汇总操作,及Spring data mongo的实现

    转载请在页首注明作者与出处 一:分组汇总 1.1:SQL样例 分组汇总的应用场景非常多,比如查询每个班级的总分是多少,如果用关系形数据库,那么sql是这样子的 ),class from score g ...

  7. spring data mongodb 配置遇到的几个问题

    一. mongodb 2.2版本以上的配置 spring.data.mongodb.uri = mongodb://newlook:newlook@192.168.0.109:27017/admin ...

  8. mongodb java spring data

    关于如何集成spring-data-mongodb到项目中,已经有很多人介绍了,这里只给出几个链接. GETTING STARTED Accessing Data with MongoDB: http ...

  9. spring data mongodb中,如果对象中的属性不想加入到数据库字段中

    spring data mongodb中,如果对象中的属性不想加入到数据库字段中,可加@Transient注解,声明为透明属性 spring data mongodb 官网帮助文档 http://ww ...

随机推荐

  1. sqlserver清除日志

    在一次处理数据库日志已满的过程中,发现有的时候数据库日志不能清除,经实验,可以通过以下方式来完成. 使用exec sp_cycle_errorlog 来清除sql系统本身的临时日志. dump tra ...

  2. jsp的简介(2)

    JSP(JavaServer Pages )是什么? JavaServer Pages(JSP)是一种支持动态内容开发的网页技术它可以帮助开发人员通过利用特殊的JSP标签,其中大部分以<%开始并 ...

  3. 谈谈用Boox Max 2 阅读A4纸文献的体验

    首先说说选择Boox的几个原因: 护眼.这个不用多说,之所以除了电脑,还要电子阅读器,主要是为了护眼. 减少纸质书籍购买.纸质书籍拿在手上是有质感,读起来也更舒服,可一则一些外文书买纸质的是很贵的,相 ...

  4. CentOS7安装高版本gcc

    CentOS7安装高版本gcc 下载 从hust镜像站下载gcc源码包. http://mirror.hust.edu.cn/gnu/gcc/ 我选择的是gcc-8.3.0.tar.gz. cd mk ...

  5. [AI开发]目标检测之素材标注

    算力和数据是影响深度学习应用效果的两个关键因素,在算力满足条件的情况下,为了到达更好的效果,我们需要将海量.高质量的素材数据喂给神经网络,训练出高精度的网络模型.吴恩达在深度学习公开课中提到,在算力满 ...

  6. sed流编辑器

    一.前言 (一).sed 工作流程 sed 是一种在线的.非交互式的流编辑器,它一次处理一行内容.处理时,把当做前处理的行存储在临时缓存区中,成为“模式空间”(pattern space),接着用se ...

  7. 【kafka】一、消息队列

    在高并发的应用场景中,由于来不及同步处理请求,接收到的请求往往会发生阻塞.例如,大量的插入.更新请求同时到达数据库,这会导致行或表被锁住,最后会因为请求堆积过多而触发“连接数过多的异常” 的错误.因此 ...

  8. WEB基础(一)--JSP的9个内置对象

    1.request request 对象是 javax.servlet.httpServletRequest类型的对象. 该对象代表了客户端的请求信息,主要用于接受通过HTTP协议传送到服务器的数据. ...

  9. java并发编程(三)----线程的同步

    在现实开发中,我们或多或少的都经历过这样的情景:某一个变量被多个用户并发式的访问并修改,如何保证该变量在并发过程中对每一个用户的正确性呢?今天我们来聊聊线程同步的概念. 一般来说,程序并行化是为了获得 ...

  10. C++这么难,为什么还要学习C++呢?如何学?

    在大多数开发或者准开发人员的认识中,C/C++ 是一门非常难的编程语言,很多人知道它的强大,但因为认为“难”造成的恐惧让很多人放弃. 这个世界本来就是残酷的,所以你不能怪C++向你展示了世界的本质 大 ...