文章目录

  • 前言
  • 参考链接
  • 时间线
  • MongoRepository简介
  • 使用前的准备
    • Maven
    • application.properties配置
  • 使用
    • 使用流程
      • 设计好collections格式
      • 编写实体类
      • 实现MongoRepository接口
      • 创建Service层
      • 简单的增删改查
    • 一些需求
  • Page分页
    • Repository层
    • Service层
  • @Query
    • value
      • 匹配查询
      • 模糊查询
      • 条件查询
      • 对象查询
      • 更多
    • fields
    • sort
  • 总结

前言

之前写过一篇关于MongoDB的总结

其中就已经包含了SpringBoot操作MongoDB之MongoRepository了

但是因为觉得单单与Springboot内容就比较多,而且开发时还会进行多次补充总结,

觉得独立出来一篇是非常必要的,所以就有这篇的出现。

参考链接

NoSQL_MongoDB
Spring data Mongodb Query以分页

时间线

20200825-完成初稿

MongoRepository简介

关于springboot操作mongodb,使用spring-data其实有两种方式:MongoRepository 和 MongoTemplate

但是日常使用中,与MongoRepository相比,MongoTemplate需要进行相关配置,而MongoRepository能够满足一般的需求开发,而且拿来即用即可。非常方便

使用前的准备

Maven

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>

application.properties配置

#### 链接数据库
# 备注:user=root,password=123456,host=192.168.1.100,port=27017,db=admin
# url配置方式,如果有设置密码的话,这种方式非常简洁
# 但找不到资料,当没有设置密码时,如何处理
spring.data.mongodb.uri=mongodb://root:123456@192.168.1.100:27017/admin
# 逐一配置,适合未设置密码的MongoDB
spring.data.mongodb.database=test
spring.data.mongodb.host=host
spring.data.mongodb.port=27017
# mongodb开启Debug模式
# MongoRepository
logging.level.org.springframework.data.mongodb.repository=DEBUG
# MongoTemplate
logging.level.org .springframework.data.mongodb.core= DEBUG

使用

使用流程

对于一门框架的使用,其使用顺序是非常关键的,因为有了大概的使用顺序,才能够处理好许多问题

设计好collections格式

这里的设计好指的是对一个实体类有大致的想法,而且能够满足需求,特别是一些细节的需求。

例如需要根据时间排序,那么这个collections就需要有一个时间戳Field

例如以下内容:

{"id":1,"name":"zhj","age":18,"detail":"a good man","timeStamp":"123"
}
//其中id是主键

编写实体类

实体类是非常关键的,Java作为一门面向对象语言,可以说哪里需要就需要new一个对象出来

这个实体类可以根据上一步的collections格式进行编写

@Document("user")
public class User implements Serializable {@Indexed(unique = true)@Field("id")private int id;@Field("name")private String name;@Field("age")private int age;@Field("detail")private String detail;//setter && getter
//toString
}

关于这部分,有2个地方需要注意

  1. 其中有3个注解,分别是:

    @Document表示集合的名称,即集合user

    @Indexed表示主键,上面是以id为主键

    @Field](mailto:Indexed@Field)表示集合中的字段的键名,而private int id的值将会是字段id的值

  2. "_id"和"id"的区别

如果在实体类重定义了Field"_id"的话,如下:

@Document("user")
public class User implements Serializable {//不需要这个了:@Indexed(unique = true)@Field("_id")private int id;//setter && getter//toString
}

如果没有重定义Field“_id”的话,则每一次执行增加操作时,会自动生成一个字段,且其值是根据MongoDB的生成规则,如下:

"_id" : ObjectId("5f2ce4d3ad90594600115535")

这里不建议使用MongoDB的生成规则,因为有一些操作是需要主键的,例如删除,更新操作,如果使用MongoDB的生成规则,将无法进行获取并使用

所以建议选择第一种方式——先入为主

而且建议使用随机字符串+时间戳作为_id的值

实现MongoRepository接口

public interface UserRepository extends MongoRepository<User, String>{}

创建Service层

@Service
public class UserService {@Autowiredprivate UserRepository userRepository;
}

简单的增删改查

//repository层
//不用实现//使用自带的
//service层
// 增
public User saveOne(User user){try {return userRepository.save(user);} catch (Exception e) {e.printStackTrace();return null;}
}
//test层
@Test
void save() {User user = new User();user.setId(1);user.setName("zhj");user.setDetail("我是好人");user.setAge(21);User result = userService.saveOne(user);if(result!=null){System.out.println(result.toString());} else{System.out.println("插入失败");}
}
//结果//数据库会产生以下记录
{ "_id" : ObjectId("5f2eb009dd289611253d8cf8"), "id" : 1, "name" : "zhj", "age" : 21, "detail" : "我是好人","_class" : "pro.zhj.model.User"
}
//注意以下返回值是int类型
//repository层
public int deleteOneById(int id);
//service层
// 删
public int deleteOne(int id){return userRepository.deleteOneById(id);
}
//test层
@Test
void delete() {int flag;flag = userService.deleteOne(2);System.out.println(flag);
}
//结果
1
//repository层
//无需实现
//service层
public User updateOne(User user){return userRepository.save(user);
}
//test层
@Test
void update() {User user = new User();user.setId(2);user.setName("小丑");user.setDetail("其实我也不是个坏人");user.setAge(25);User result = userService.updateOne(user);if(result!=null){System.out.println(result.toString());}else{System.out.println("更改失败");}
}
//结果
//原
{ "_id" : ObjectId("5f2eb24e1c3e41794ecbd89a"), "id" : 2, "name" : "小丑", "age" : 25, "detail" : "我是个坏人", "_class": "pro.zhj.model.User" }//更改后{ "_id" : ObjectId("5f2eb3829591964c8d347f51"), "id" : 2, "name" : "小丑", "age" : 25, "detail" : "其实我也不是个坏人",
"_class" : "pro.zhj.model.User" }
//repository层
public User findOneById(int id);
//service层
// 查
public User findOne(int id){return userRepository.findOneById(id);
}
//test层
@Test
void find() {User result = userService.findOne(1);if(result!= null){System.out.println(result.toString());}else{System.out.println("查找失败");}
}
//结果//控制台
//User{id=1, name='zhj', age=21, detail='我是好人'}

一些需求

基本上一些简单的增删改查就是上面的部分了。

当然实际开发中并不会这么简单,例如根据某个Field排序或者模糊查询等等。

或者分页的概念,那么就很需要下面的内容了。

Page分页

MongoRepository实现分页非常简单,使用Pageable即可

Repository层

@Query (...)
public Page<ItemLost> findAllUsers(Pageable pageable);

Service层

public List<ItemLost> findAllUsers(int page){int pageSize = 10;//每页10个元素Pageable pageable = PageRequest.of(page,pageSize);return userRepository.findAllUsers(pageable).getContent();
}
//注意:方法的返回类型

@Query

@Query注解可以说使用频繁了,一些复杂查询都可以使用@Query实现

例如上面说的模糊查询,比较查询,排序显示等等。

那么@Query注解下面有6个属性,其中3个:value、field和sort可以说是常用的

当然剩下3个也有用,但没有使用过,以后再进行补充。

value

属性value可以实现复杂查询,例如匹配查询、模糊查询、条件查询等等

匹配查询

@Query (value = "{'_id':?0}",fields = "{}")
public User findUserById(String id);
//以上内容表示根据 _id 进行查询
//其中?0表示的是第0个参数,就是方法内的第1个参数
//如果不设置,即表示查询全部
@Query (value = "{}",fields = "{}")
public User findUserById(String id);

模糊查询

@Query (value = "{'fileHead':?#{{$regex:[0]}}}",fields = "{}",sort = "{}")
public Page<FileDocument> findFileListByFileNameLike(String fileName,Pageable pageable);
//以上内容表示 根据fileHead进行模糊查询
//原本需求是:根据传入的文件名参数对collections的字段fileHead进行匹配
//其中关键词是:$regex
//为什么会这么写呢:是因为也是通过查询资料知道可以这样实现模糊查询,
//也即是参考链接中的@Query的使用,其中用到了EL表达式

条件查询

以上可以说是 只要知道需求,就可以根据上面的例子,直接进行书写
但是,有时一些需求就需要进行整理
例如 什么时候使用交集和并集的概念,即and 或者 or


//一个and
@Query (value="{'$and': [{'id':?0},{ 'timeStamp':{'$gte':?1}},{'iseffect':{'$lte':'2'}}]}")
public Page<User> findUserById(String id,String timeStamp,Pageable pageable);
//上面的内容表示的是:
//and的概念,即必须满足以下内容:
//1.id==参数id
//2.timeStamp >=  参数timeStamp//gte大于等于
//3.iseffect <= 2//lte表示小于等于//and 和 or 同时使用
@Query (value = "{'$and': [{'$or': [{ 'lostName':?#{{$regex:[0]}}},{ 'lostAdress':?#{{$regex:[0]}}}]},{ 'timeStamp':{'$gte':?1}},{'iseffect':'3'}]}")
public Page<ItemLost> findItemsByKeyWord(String keyWord,String timeStamp,Pageable pageable);
//其实只要掌握了其中的一种之后,复杂的就是组合,就是所谓的组装。
//首先完成 一个or 完成之后,将or看成是一个条件 然后和另一个条件完成and

对象查询

为什么会提到这个呢,是因为Java是一门面向对象语言,往往有时是定义collections不仅仅只是使用到一些基本的数据类型,还会可以使用到自定义的对象,例如:

//联系
class Call{private String type;//联系方式private String call;//联系号码
}
@Document("user")
public class User{@Field("_id")private String id;@Field('call')private Call call;...
}

那么如果有一个需求:获取联系方式为callType的所有用户,则可以这样写

@Query (value = "{'call.type':?0}",fields = "{}")
public Page<User> findUserByCallType(String callType);
//即使用call.type表示call对象的type属性

如果参数是一个对象,则可以这么写

@Query (value = "{'call.type':?0.call.type}",fields = "{}")
public Page<User> findUserByCallType(User user);
//即使用call.type表示call对象的type属性
//即找到跟参数user对象相同的联系方式的所有用户

更多

当然以后可能会遇到更加复杂的需求,那么关键在于value属性值的添加。

一般而言,可以根据上面的例子进行组装,当然如果无法获取解决方案,

那么如何知道呢,其实可以去看MongoDB的一些查询语句,就可以得到启发。

可以到这里进行学习:菜鸟教程-MongoDB查询

fields

相比属性value,fields的功能性就比较单一了——控制字段的显示

@Query (value = "{'_id':?0}",fields = "{'username':1,'passwd':0}")
public User findUserById(String id);
//以上的fields表示的是显示username,不显示passwd

这里的不显示不是说直接整个字段不显示,而是将该字段的值设置为null;

{"id":1,"userName":"zhj","passwd":null,"timeStamp":"123"
}

题外话:

这有什么用呢,怎么说呢,我觉得有一个作用——安全和资源

其一:安全

一般而言,后端开发总是前后端分离,那么接口肯定会有可能暴露,

如果不控制字段的显示,显示全部字段内容,那么将会对安全有非常大的危险。

例如恶意删除,恶意调用等等,所以可以对于一些未使用到的敏感字段进行隐藏。

特别是:微信小程序项目开发。

其二:资源:

如果每一个请求都显示大量的无用字段,即业务对于该字段并没有进行利用,那么如果请求返回太多的话,也是对资源的一种浪费。

sort

一般而言sort都是根据时间进行排序,所以非常推荐设计一个字段存储时间戳

当进行查询的时候再根据这个字段进行排序

@Query (value = "{}",fields = "{}",sort = "{timeStamp:-1}")
public Page<User> findUserSortByCreateTimeDESC(Pageable pageable);
//以上表示根据创建时间进行倒序排列
//-1 表示 desc
//1 表示 asc

sort的功能其实也可以像value的一样的,

例如根据某个字段进行排序,如果当某个字段相同时,再根据某个字段排序

以后如果有遇到,再进行记录

总结

以上内容都是对于MongoDB的使用经历,基本可以满足一般的开发需求了。

如果以后还遇到一些另外的需求,再进行补充。

另外,后面会做一篇关于MongoTemplate的。

SpringBoot操作MongoDB之MongoRepository相关推荐

  1. SpringBoot操作MongoDB实现增删改查

    本篇博客主讲如何使用SpringBoot操作MongoDB. SpringBoot操作MongoDB实现增删改查 (1)pom.xml引入依赖 <dependency> <group ...

  2. mongorepository查询条件_Java操作MongoDB采用MongoRepository仓库进行条件查询 | 学步园...

    1.实体类: publicclassPersonimplementsSerializable{ /** * */ private static final long serialVersionUID  ...

  3. SpringBoot 集成 Spring Data Mongodb 操作 MongoDB 详解

    一.MongoDB 简介 MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,且与关系数据库的最为相像的.它支持的数据结构非常松散,是类似 json 的 bso ...

  4. 总结MongoDB采用MongoRepository进行查询

    Java操作MongoDB采用MongoRepository进行条件查询 1)  实体类实现Serializable接口 @Document(collection = "Memo" ...

  5. SpringBoot整合MongoDB 及 基本使用

    目录 1.MongoDB基本介绍 2.MongoDB的特点 3.MongoDB的体系结构 4.MongoDB的数据类型 5.SpringBoot整合MongoDB ** 1.导入依赖 2.启动Mong ...

  6. core 实例化接口_实例讲解Springboot整合MongoDB进行CRUD操作的两种方式

    1 简介 Springboot是最简单的使用Spring的方式,而MongoDB是最流行的NoSQL数据库.两者在分布式.微服务架构中使用率极高,本文将用实例介绍如何在Springboot中整合Mon ...

  7. spring data使用操作mongodb数据库 springboot

    在IDEA里面使用新建一个maven项目, 项目的结构是如图所示:(注意:springboot 项目中所有的组件必须位于application同级或者子包下才会被扫描到,不然就会报上面的错!) 导入相 ...

  8. Springboot中mongodb的使用

    mongodb是最早热门非关系数据库的之一,使用也比较普遍,一般会用做离线数据分析来使用,放到内网的居多.由于很多公司使用了云服务,服务器默认都开放了外网地址,导致前一阵子大批 MongoDB 因配置 ...

  9. MongoDB最简单的入门教程之四:使用Spring Boot操作MongoDB

    Spring Boot 是一个轻量级框架,可以完成基于 Spring 的应用程序的大部分配置工作.Spring Boot的目的是提供一组工具,以便快速构建容易配置的Spring应用程序,省去大量传统S ...

最新文章

  1. 通过进程ID得到进程名
  2. ubuntu12.04下NFS链接开发板并测试交叉编译的第一个应用
  3. MOSS的SPBuiltInFieldId成员的字段类型对照关系表
  4. icmp报文格式_IPV6报文格式和IPV4有什么区别?
  5. Java后台开发Tomcat添加https支持小程序开发过程
  6. 上升沿_输入输出的上升沿和下降沿是怎么来的,一起看看
  7. Oracle Grid Infrastructure: Understanding Split-Brain Node Eviction (文档 ID 1546004.1)
  8. django开发中安装包时遇到的 关于 read timed out的问题的解决
  9. DUTCTF 201x RE20
  10. 5G手机将不用流量可免费看电视,网友:流量免费,内容付费?
  11. Python+OpenCV:对极几何(Epipolar Geometry)
  12. linux删除多余日志,linux 删除日志
  13. 西门子 S7-200和S7-300/400 通过模块连接INTOUCH通讯方法
  14. 创建MSN界面式的Ext JS布局
  15. ImageAssitant插件 — 一件提取网页图片
  16. 红外光电测速传感器电路设计
  17. 我是如何在B站自学Java的?
  18. 第二篇:Haploview做单倍型教程2--分析教程
  19. centos路由查看命令_centos查看ip
  20. 系统分析师-软件工程知识点

热门文章

  1. 张驰咨询:六西格玛常见问题解答
  2. 来,告诉你另一种手机里的文件删了怎么恢复的方法
  3. i7 8550 linux,4核8线程PK标压HQ!8代酷睿i7 8550U测试
  4. 写下2011,展望2012
  5. android 不能试用switch
  6. felayman——Ubuntu下搭建PHP开发环境
  7. RISC-V 指令格式和6种基本整数指令
  8. dos winrar压缩文件
  9. 2022-03-23工作思考
  10. VMware官网下载