springboot mongo 使用
nosql对我来说,就是用它的变动列,如果列是固定的,我为什么不用mysql这种关系型数据库呢?
所以,现在网上搜出来的大部分,用实体类去接的做法,并不适合我的需求。
所以,整理记录一下,我收集到的springboot,自由,使用mongo的信息。
目录
前置
依赖引入
配置
代码引入
使用
插入
单行插入
批量插入
查询
查询全部(无条件)
条件查询
排序
DBObject更加自由的查询
聚合
某些列有值,并且只返回选中的列,并且聚合
其他工具包,像客户端一样写查询
mongodb的java驱动MongoClient
前置
依赖引入
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
版本就根据自己的spring版本来好了,不需要额外加
配置
spring.data.mongodb.uri=mongodb://localhost:27017/myTest
我用的本地版本的mongo,没配用户名+密码,如果配了,就需要加下。
本地mongodb的安装,我使用了菜鸟 MongoDB 安装介绍,并安装了mongoDB compass客户端,用来直连查看mongodb里的数据库数据
代码引入
@Resource private MongoTemplate template;
上述配置完成后,直接依赖注入,就可以使用了
使用
插入
单行插入
template.insert(singleObject, "multi_1242");
上述代码中
singleObject 为 json字符串 {"_id": 3, "1": "1.1", "2": "2.1", "amount": 2.1}
"multi_1242" 为集合名称,我的需求是,不同的集合,里面document的键名,是会完全不同的
批量插入
boolean product = template.collectionExists("multi_1242");if (!product) {template.createCollection("multi_1242");}Gson gson = new Gson();JsonObject jsonObject = new JsonObject();jsonObject.addProperty("_id", 1);jsonObject.addProperty("1", "1.1");jsonObject.addProperty("2", "2.2");jsonObject.addProperty("amount", 10.12);// template.save(gson.toJson(jsonObject), "multi_1242");JsonObject jsonObject1 = new JsonObject();jsonObject1.addProperty("_id", 2);jsonObject1.addProperty("1", "1.2");jsonObject.addProperty("2", "2.2");jsonObject1.addProperty("3", "3.1");jsonObject1.addProperty("amount", 1.13);// template.save(gson.toJson(jsonObject1), "multi_1242");List<String> list = new ArrayList<>();list.add(gson.toJson(jsonObject));list.add(gson.toJson(jsonObject1));template.insert(list, "multi_1242");
这里我使用了google的Json化的工具包,我没有使用ali的fastjson,是因为它的JSON对象转JSON字符串曾经坑过我(它会把一些特殊字符,转换成别的字符)
<dependency><groupId>com.google.code.gson</groupId><artifactId>gson</artifactId><version>2.10.1</version>
</dependency>
import com.google.gson.Gson;
import com.google.gson.JsonObject;
上述动作完成插入后,mongo那边显示的结果为

从上述的实验,可以得出几个结论
1、springboot插入mongo的话,也是用json字符串去插入的,我曾经试过,直接用jsonObject类型去插入,document查出来,会有很多不需要的字段都被插进去了(这并不是我想要的),所以你想插入什么样子,就组装成什么样子后,json字符串后,再传入进去。下图为错误示范。

2、_id这个键,是默认的主键名称,如果你想控制主键多少,可以设置后,再进行插入
查询
查询全部(无条件)
Query query = new Query();
List<String> list = template.find(query, String.class, "multi_1242");//查看测试结果
LoggerUtils.info("size is " + list.size());
for (int i = 0; i < list.size(); i++) {//使用了封装类,打印了一下查出来的结果LoggerUtils.info(i + " is " + list.get(i));
}
不需要传入查询条件,传个空的query进去就行了
下图为输出结果

条件查询
2个and的查询条件
Query query = new Query();
Criteria criteria = new Criteria();
criteria.where("1").is("1.1");
criteria.and("2").is("2.1");
query.addCriteria(criteria);
List<String> list = template.find(query, String.class, "multi_1242");
查询结果

如果有的document缺少查询条件里的一些键呢,结果是如何呢? 然后我增加了一个查询条件
Query query = new Query();
Criteria criteria = new Criteria();
criteria.where("1").is("1.1");
criteria.and("2").is("2.1");
//增加一条查询条件
criteria.and("3").is("3.1");
query.addCriteria(criteria);
List<String> list = template.find(query, String.class, "multi_1242");
![]()
结果是没有查出来,如果写在where里,明确某个键=某个值的话,那么查出来的document,必然是有该键的。
但是order却不一定,为此,我多插了一行{"_id": 4, "1": "1.1", "2": "2.1","3": "3.1", "amount": 2.1}
排序
Query query = new Query();
Criteria criteria = new Criteria();
criteria.where("1").is("1.1");
criteria.and("2").is("2.1");
query.addCriteria(criteria);
//增加一条排序条件
query.with(Sort.by("3"));
List<String> list = template.find(query, String.class, "multi_1242");
结果

可以看到order依赖的属性不存在,也是可以被查出来的,并且正常排序还排在前面
DBObject更加自由的查询
上述用这个Query类构造还是束手束脚的,不过我又查到了,跟客户端类似的方法

DBObject obj = new BasicDBObject();
obj.put("1", "1.1");
obj.put("2", "2.1");
Query query = new BasicQuery(obj.toString());
List<String> list = template.find(query, String.class, "multi_1242");
仿照着写,查询结果是ok的

如果是复杂的查询,可以自己用DBObject,BasicDBList构造嵌套起来
聚合
某些列有值,并且只返回选中的列,并且聚合
如果是客户端的话,可以先过滤出来后,再进行聚合
例如,我想找到“1”列,“2”列有值,并且根据这两列进行合并的,并且返回的结果只包含这2列作为_id,意味着,如果有(1.1,2.1,3.1)和(1.1,2.1)的组合,将会合并到一起
db.multi_1242.aggregate([
#先过滤一波需要的数据
{$match:
{
"1":{$exists:true},
"2":{$exists:true}
}
},
#然后进行合并,_id使用要合并的字段组成
# mytotal这个键是我随便起的,就是group后面跟的对象,就是将会输出的数据格式
{$group:
{
_id:{"1":"$1","2":"$2"},
mytotal:{$sum:"$amount"}
}
}
])
原始数据如图

查询后的结果如下

可以看到我的_id设置的只有“1”列和“2”列,所以合并也是根据我的要求来合的。
如果我的_id加入了“3”列,那么,有的document行有3这个键值,有的没有,又该如何?
查询如下:

可以发现,有“3” 列的就有,没有“3”列的,就没有。
客户端是这样,那么如何在项目中使用聚合来查询?
Aggregation aggregation =Aggregation.newAggregation(Aggregation.match(new Criteria().where("1").is(obj1).and("2").is(obj1)),Aggregation.group("1", "2").sum("amount").as("mytotal"));
AggregationResults results = template.aggregate(aggregation, "multi_1242", String.class);
List<String> mappedResults = results.getMappedResults();
打印得到的结果

这个group查多组合,需要传 Fields
import org.springframework.data.mongodb.core.aggregation.Fields;DBObject obj1 = new BasicDBObject();
obj1.put("$exists", true);Fields fields = Fields.fields("1");
fields = fields.and("2");
fields = fields.and("3");
Aggregation aggregation =Aggregation.newAggregation(Aggregation.match(new Criteria().where("1").is(obj1).and("2").is(obj1)),Aggregation.group(fields).sum("amount").as("mytotal"));
AggregationResults results = template.aggregate(aggregation, "multi_1242", String.class);
List<String> mappedResults = results.getMappedResults();
查询结果

这个Fields还真是难造,看了下源码,才知道怎么造出来。
然后,如果不想调用各种聚合函数,比如sum,count也是可以的。
比如我把上面的聚合查询,改为这样。
Aggregation aggregation =Aggregation.newAggregation(Aggregation.match(new Criteria().where("1").is(obj1).and("2").is(obj1)),Aggregation.group(fields));
结果如下

只会查出聚合的键,这也是我需要的内容
其他工具包,像客户端一样写查询
mongodb的java驱动MongoClient
mongoClient的参考文章
其中的这种写法,我是比较赞赏的,因为都是字符串拼接,很自由,引用一下。
Document match = Document.parse("{$match:{$or:[{\"组织机构代码\":\"" + id + "\"}, {\"单位名称\":\"" + id + "\"}]}}");
Document unwind = Document.parse("{$unwind:\"$公司人员\"}");
Document group = Document.parse("{$group : {_id : \"$公司人员." + arrayFiled + "\", count : {$sum : 1}}}");List<Document> conditions = new ArrayList<>();
conditions.add(match);
conditions.add(unwind);
conditions.add(group);List<Document> result = new ArrayList<>();
AggregateIterable<Document> resultSet = this.collection.aggregate(conditions);
try (MongoCursor<Document> cursor = resultSet.iterator()) {while (cursor.hasNext()) {Document item_doc = cursor.next();result.add(item_doc);}
}
Bson的话,两种工具包好像都可以进行使用,我这边就不赘述了。
相关文章:
springboot mongo 使用
nosql对我来说,就是用它的变动列,如果列是固定的,我为什么不用mysql这种关系型数据库呢? 所以,现在网上搜出来的大部分,用实体类去接的做法,并不适合我的需求。 所以,整理记录一下…...
如何使用appuploader制作apple证书
转载:如何使用appuploader制作apple证书 如何使用appuploader制作apple证书 一.证书管理 点击首页的证书管理 二.新建证书 点击“添加”,新建一个证书文件 免费账号制作证书只有7天有效期,没有推送消息功能,推送证书…...
Promise详细版
promise基础原理到难点分析 常见的Promise的方法解读 扩展async和await深入分析 逐步分析Promise底层逻辑代码 一、Promise基础 1.什么是promise 为了解决回调地狱: //2.设置点击事件btn.onclick function() {//3.创建ajax实例化对象let xhr new XMLHttpRe…...
v-for循环生成的盒子只改变当前选中的盒子的样式
1.给盒子添加动态属性:class"[index isActive?active-box:choose-box]" <div v-for"(item,index) in zyList" :key"item.sid" :class"[index isActive?active-box:choose-box]" click"getKmList(item,index)"…...
Spring Data JPA源码
导读: 什么是Spring Data JPA? 要解释这个问题,我们先将Spring Data JPA拆成两个部分,即Sping Data和JPA。 从这两个部分来解释。 Spring Data是什么? 摘自: https://spring.io/projects/spring-data Spring Data’s mission is to provide a familiar and cons…...
如何防止CSRF攻击
背景 随着互联网的高速发展,信息安全问题已经成为企业最为关注的焦点之一,而前端又是引发企业安全问题的高危据点。在移动互联网时代,前端人员除了传统的 XSS、CSRF 等安全问题之外,又时常遭遇网络劫持、非法调用 Hybrid API 等新…...
linuxARM裸机学习笔记(7)----RTC实时时钟实验
基础概念: I.MX6U 内部也有个RTC 模块,但是不叫作“ RTC ”,而是叫做“ SNVS ”。 SNVS 直译过来就是安全的非易性存储, SNVS 里面主要是一些低功耗的外设,包括一个 安全的实时计数器 (RTC) 、一个单调计数器 (mo…...
NSS [UUCTF 2022 新生赛]ez_upload
NSS [UUCTF 2022 新生赛]ez_upload 考点:Apache解析漏洞 开题就是标准的上传框 起手式就是传入一个php文件,非常正常的有过滤。 .txt、.user.ini、.txxx都被过滤了,应该是白名单或者黑名单加MIME过滤,只允许.jpg、.png。 猜测二…...
【操作系统】操作系统知识点总结(秋招篇)
文章目录 前言操作系统主要做了哪些工作?进程 线程 协程之间的区别进程的组成部分介绍一下进程的PCB讲一下进程的五态 以及它们的状态转移用户态和内核态是什么?进程在用户态和内核态之间是如何切换的讲一下进程之间的通信方式讲一下进程调度的三个层次介…...
篇十九:迭代器模式:遍历集合
篇十九:"迭代器模式:遍历集合" 开始本篇文章之前先推荐一个好用的学习工具,AIRIght,借助于AI助手工具,学习事半功倍。欢迎访问:http://airight.fun/。 另外有2本不错的关于设计模式的资料&…...
浅谈JVM中的即时编译器(Just-In-Time compiler, JIT)
Java虚拟机(JVM)中的即时编译器(Just-In-Time compiler, JIT)是一个非常重要的组件,它负责将字节码转换为本地机器代码。在不使用JIT的情况下,JVM通过解释字节码来执行程序,这意味着它会为每个字…...
Android 13 Launcher——长按图标弹窗内容修改以及小组件等隐藏起来
目录 一.背景 二.实现思路 三.布局文件修改 四.隐藏代码中原先的view 一.背景 由于定制化开发需要将原先的长按图标原生弹窗界面隐藏,然后显示自定义的弹窗界面,如下就是我们来实现自定义的弹窗界面...
又一个不可错过的编程大模型来了让你惊呼“码农人生”不虚此行
继Stable Diffusion爆火之后,StabilityAI近期又放大招,推出了号称是革命性的编程大模型StableCode。StableCode是其首款用于编码的LLM生成式AI产品,该产品旨在帮助程序员完成日常工作。目前已发布的版本为StableCode-Completion-Alpha-3B&…...
【Express.js】集成SocketIO
集成SocketIO 本节我们介绍在如何在 express 中集成 Socket.IO Socket.IO 算是 WebSocket 的一个超集,进行了一些封装和拓展。 准备工作 创建一个 express.js 项目(本文基于evp-express-cli)安装socket.io.js: npm i socket.io创建代理 …...
为树莓派Pico配置交叉编译环境和工具链arm-none-eabi-gcc时可能会遇到的错误以及解决方案
本文是一个类似手册的文章,用来记录可能遇到的错误。你可以通过侧栏选择遇到的错误来查看详细信息。 No install step for ‘ELF2UF2Build’ 遇到这种错误有两种原因: 安装了版本不对或者不完整的arm-none-eabi-gcc;没有使用正确的 C/C 的…...
Yum 部署K8S集群
目录 1、准备环境 (温馨提示:尽量一次完成集群) 2.安装master节点 3、安装k8s-master上的node 4、安装配置k8s-node1节点 5、安装k8s-node2节点 6、为所有node节点配置flannel网络 7、配置docker开启加载防火墙规则允许转发数据 一. 环…...
初阶C语言-操作符详解(下)
🌞 “等春风得意,等时间嘉许!” 接下来,我们把操作符没学完的继续学完! 操作符详解 6.2sizeof和数组 7.关系操作符8.逻辑操作符9.条件操作符10.逗号表达式11.下标引用、函数调用和结构成员12.表达式求值12.1隐式类型转…...
reposync命令——下载yum仓库中全部的包到本地
reposync命令可以将远端yum仓库里面的包全部都下载到本地。这样构建自己的yum仓库,就不会遇到网络经常更新包而头疼的事情了。 reposync命令在软件包 yum-utils 里面,需要保证yum-utils已安装。 yum install yum-utils -y 常用参数 -r :指定…...
LC-杨辉三角
LC-杨辉三角 链接:https://leetcode.cn/problems/pascals-triangle/submissions/ 上图就是一个杨辉三角,每个数等于他左上角的数与右上角的数之和。 第一行就是一个1;第二行是两个1;第三行的2就是它肩膀上两个1之和,其余的类似。…...
Golang空结构体struct{}的作用是什么?
文章目录 占位符:通道标识:键集合:内存占用优化:总结: 在Go语言中,空结构体 struct{}是一种特殊的数据类型,它不占用任何内存空间。空结构体没有任何字段,也没有任何方法。尽管它看起…...
JAVA - EasyExcel动态填充Excel模板与样式优化实战
1. 为什么选择EasyExcel处理Excel模板 第一次接触Excel导出需求时,我尝试过Apache POI。当时处理一个20MB的Excel文件,直接让服务器内存飙到2GB,差点引发生产事故。后来发现阿里开源的EasyExcel,同样的文件内存占用不到100MB&…...
第二十七章 灾备与演练:生产级数据库的增量备份、异地容灾与快速恢复预案
第二十七章 灾备与演练:生产级数据库的增量备份、异地容灾与快速恢复预案 在煤化工这样的大型连续性生产企业中,数据库不仅仅是存储代码和日志的地方,它是整个工厂的数字心脏。一次看似短暂的数据库宕机,在极客眼中可能只是 systemctl restart 的几秒钟,但在厂长眼中,那…...
告别手动标注!用μSAM和napari插件5分钟搞定显微图像分割(附保姆级配置流程)
告别手动标注!用μSAM和napari插件5分钟搞定显微图像分割(附保姆级配置流程) 在生物医学研究领域,显微图像分析一直是数据处理的瓶颈环节。传统的手动标注方式不仅耗时费力,还容易引入人为误差——研究人员常常需要花费…...
等高线转面(断边界处理+将线的高程属性赋予面)
1 引言想把获得的等高线转化为面,便于统计不同高程下的其他面shp数据,操作中发现两个问题:(1)等高线若不闭合,则无法生成面;(2)闭合的等高线生成面后,没有等高…...
局域网聊天工具选型:为什么企业办公场景更青睐 BeeWorks? - BeeWorks
在制造、政务、军工、大型集团等行业中,内网隔离、无外网办公已成为常态,一款专业的局域网聊天工具成为刚性需求。不同于依赖公有云服务器的通用即时通讯软件,局域网聊天工具将数据传输与存储完全限定在企业内部网络,从物理层面杜…...
告别‘打架’的目标:用CMPSO算法轻松搞定多目标优化(Python代码实战)
告别‘打架’的目标:用CMPSO算法轻松搞定多目标优化(Python代码实战) 想象一下,你正在设计一款新型电动汽车,需要同时优化续航里程、制造成本和充电速度。这三个目标就像三个固执的谈判代表,各自坚持己见—…...
Claude仅用10分钟发现Apache ActiveMQ潜伏13年的RCE漏洞
Apache ActiveMQ Classic 近日披露了一个存在十多年未被发现的严重远程代码执行(RCE)漏洞。值得注意的是,这个漏洞并非由人工代码审计发现,而是 Anthropic 公司的 Claude AI 模型在不到 10 分钟内识别出来的。该漏洞编号为 CVE-20…...
如何解决APT仓库体系结构不匹配问题:以amd64和i386为例
1. 当APT仓库遇到体系结构不匹配时会发生什么 第一次在树莓派上执行sudo apt-get update时看到"不支持amd64体系结构"的红色警告,我差点以为系统崩溃了。实际上这是Linux系统在提醒你:当前仓库和你的设备"语言不通"。就像带着英文菜…...
被“圈养”的Java开发者:当AI浪潮来袭,你还在用手写HttpClient调大模型吗?
写在前面 2026年,AI早已不是算法工程师的专属领域。每个后端开发者都被卷入了这场浪潮——无论你愿不愿意。 “两年前,大部分Java团队面对大模型浪潮的反应是:‘我们用HTTP调OpenAI的API不就行了?’” 但到了2026年,如…...
培训行业残酷真相,项目失败,90%都不是你的错
——致那些在深夜里,反复怀疑自己的你 今天我们助教又被学员点名夸奖了。顺便一顿拉扯,我们聊了很多。 这位学员告诉我,他很信命,曾找人看过他的命盘,总的来说就是一个非常普通的盘,这辈子注定赚不了什么大…...
