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

使用背景

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

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

代码地址

gitee

github

入门普通级别

1.引入maven依赖

<dependencies>
<!--###############时间日期操作################-->
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency> <dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!--###############springboot-aop模块################-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<!--###############test模块################-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--###############web模块################-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency> <!--###############lombok################-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency> <!--fast json-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency> <dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency> </dependencies>

基于maven dependencyManagement 版本控制如下:

    <dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.1.2.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency> <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.48</version>
</dependency> <dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>4.5.16</version>
</dependency> <!--mybatis-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.0.0</version>
</dependency> <!--fast json-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.56</version>
</dependency> <!-- druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.9</version>
</dependency> <dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>19.0</version>
</dependency>
</dependencies>
</dependencyManagement>

2.使用docker启动MongoDB

docker run --restart="always" \
-d \
--name mongo\
-p 27017:27017\
-v /docker/mongo/data/db:/data/db\
mongo:latest --storageEngine wiredTiger

3.创建Mongo的实体类

  • @Document(collection="female")

  • 设置id: @Id

  • 设置属性

  • 构建索引

  • getter/setter

Female.java

@Document(collection = "female")
@Data
public class Female {
/**
* 主键
*/
@Id
private String id; /**
* 姓名
*/
private String name; /**
* 年龄
*/
private String age; /**
* 哪种类型的女人;FemaleTypeEnums
*/
private Integer type; /**
* 舔狗
*/
private List<Male> dogs; /**
* 男朋友们
*/
@Indexed
private List<Male> boyFriends; /**
* 男神们
*/
@Indexed
private List<Male> dreamers; /**
* 创建时间
*/
@Indexed
private Date createTime; /**
* 修改时间
*/
private Date modifiedTime;
}

4.创建Dao层

  • 创建Repository 继承于MongoRepository

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

  • 编写单元测试方法

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

FemaleRepository.java

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

单元测试方法

FemaleRepositoryTest.java

	/**
* description: 添加测试数据
* author: suwenguang
* date: 2019-09-01
*/
@Test
public void addTestData() {
for (int i = 0; i < 1000; i++) {
Female entity = new Female();
entity.setName(RandomUtil.randomString(12));
LocalDate now = LocalDate.now();
LocalDate localDate = now.minusDays(RandomUtil.randomInt(4));
entity.setCreateTime(localDate.toDate());
femaleRepository.save(entity);
}
} /**
* description: 测试查询构造器
* author: suwenguang
* date: 2019-09-01
*/
public void matching(){
//精确匹配和模糊匹配
Female probe = new Female();
ExampleMatcher matching = ExampleMatcher.matching()
.withMatcher("name", ExampleMatcher.GenericPropertyMatcher.of(ExampleMatcher.StringMatcher.CONTAINING))//模糊匹配
.withIgnorePaths("id")//忽略匹配id
;
PageRequest of = PageRequest.of(0, 10);
Page<Female> all = femaleRepository.findAll(Example.of(probe, matching), of);
System.out.println(JSON.toJSONString(all));
} /**
* description: 测试范围查询
* author: suwenguang
* date: 2019-09-01
*/
@Test
public void findAllByCreateTimeAfter() {
LocalDate yesteday = new LocalDate().minusDays(3);
PageRequest of = PageRequest.of(0, 10);
List<Female> byCreateTimeAfter = femaleRepository.findAllByCreateTimeAfter(yesteday.toDate(), of);
System.out.println(JSON.toJSONString(byCreateTimeAfter));
} /**
* description: 测试范围查询
* author: suwenguang
* date: 2019-09-01
*/
@Test
public void findByCreateTimeBetween() {
LocalDate localDate = new LocalDate();
Page<Female> byCreateTimeBetween = femaleRepository.findByCreateTimeBetween(localDate.minusDays(2).toDate(), localDate.toDate(), PageRequest.of(0, 10));
System.out.println(JSON.toJSONString(byCreateTimeBetween.getContent()));
}

进阶Querydsl扩展复杂查询

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

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

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

步骤

  • 整合querydsl

  • 使用dsl

1.整合querydsl

1.Querydsl官网

2.querydsl集成文档

pom.xml配置引入依赖

       <!--###############复杂查询querydsl jpa################-->
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
<version>${querydsl.version}</version>
<scope>provided</scope>
</dependency> <dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-jpa</artifactId>
<version>${querydsl.version}</version>
</dependency> <!-- <dependency>-->
<!-- <groupId>org.slf4j</groupId>-->
<!-- <artifactId>slf4j-log4j12</artifactId>-->
<!-- <version>1.6.1</version>-->
<!-- </dependency>-->

为什么要注释掉slf4j?

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

2.使用dsl

  • daorepository中继承QuerydslPredicateExecutor<T>

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

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

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

至于怎么实现,后面再继续整合 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. linux初学者-系统服务的控制

      linux系统中系统服务的控制是比较重要的一部分,这也直接影响到计算机的使用,以下将会介绍一些系统服务的控制. 1.系统服务命令 系统的初始化程序是系统开始的第一个进程,pid为1.可以通过以下命 ...

  2. win7 磁盘碎片整理

    最近每天早上开机,都出现开机正常,但是所有软件都没法点开,性能特别差: 咨询了运维小伙伴,提示可以整理下电脑磁盘碎片试试.那么如何整理呢,如下详细说明 1.先整理C盘,打开我的电脑,在C盘上,右击-- ...

  3. Bean Validation完结篇:你必须关注的边边角角(约束级联、自定义约束、自定义校验器、国际化失败消息...)

    每篇一句 没有任何技术方案会是一种银弹,任何东西都是有利弊的 相关阅读 [小家Java]深入了解数据校验:Java Bean Validation 2.0(JSR303.JSR349.JSR380)H ...

  4. ES2019 / ES10有什么新功能?

    ECMAScript(简称ES)是ECMA International在ECMA-262和ISO / IEC 16262中标准化的脚本语言规范.它是为了标准化JavaScript语言而创建的,以便从浏 ...

  5. window下打jar包

    比如我的项目在 F/Myjar F:\Myjar>ll'll' 不是内部或外部命令,也不是可运行的程序或批处理文件. F:\Myjar>cd mian系统找不到指定的路径. F:\Myja ...

  6. UEM“探针”技术及用户体验管理

    随着互联网产品越来越多,用户群体越来越庞大以及用户品位的多样性增加,我们会发现这样的一个规律,就是相同类型的产品,比如播放器中的QQ影音和暴风影音,再比如小游戏平台中的腾讯游戏和联众等等,他们的功能是 ...

  7. JAVA jobs

    Java岗位1, SpringMVC, spring, mybaits2, 高并发编程3, mysql或者oracle SQL调优及函数,存储过程,JOB调度

  8. JNDI----数据连接池

    JNDI:提供了查找和访问各种命名和目录服务的通用,统一的接口 常用的配置属性:   name:表示以后要查找的名称.通过此名称可以找到DataSource,此名称任意更换,但是程序中最终要查找的就是 ...

  9. Go标准库--net/http学习

    Go中对网络的支持提供了标准库,net包提供了可移植的网络I/O接口,包括TCP/IP.UDP.域名解析和Unix域socket. http包提供了HTTP客户端和服务端的实现. 一般我们用http肯 ...

  10. 图片格式:gif / png / pg / webp 介绍

    本文引自:https://www.cnblogs.com/changyangzhe/articles/5718285.html GIF介绍 GIF 意为Graphics Interchange for ...