MongoDB整合SpringBoot

MongoDB整合SpringBoot

环境准备

1.引入依赖

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

2.配置yml

spring:
  data:
    mongodb:
      uri: mongodb://fox:fox@192.168.65.174:27017/test?authSource=admin
      #uri等同于下面的配置
      #database: test
      #host: 192.168.65.174
      #port: 27017
      #username: fox
      #password: fox
      #authentication-database: admin

连接配置参考文档:https://www.mongodb.com/zh-cn/docs/manual/reference/connection-string/

3.使用时注入mongoTemplate

@Autowired

MongoTemplate mongoTemplate;

集合操作

@Test

public void testCollection(){

    boolean exists = mongoTemplate.collectionExists("emp");

    if (exists) {

        //删除集合

        mongoTemplate.dropCollection("emp");

    }

    //创建集合

    mongoTemplate.createCollection("emp");

}

文档操作

相关注解

  • @Document
    • 修饰范围: 用在类上
    • 作用: 用来映射这个类的一个对象为mongo中一条文档数据。
    • 属性:( value 、collection )用来指定操作的集合名称
  • @Id
    • 修饰范围: 用在成员变量、方法上
    • 作用: 用来将成员变量的值映射为文档的_id的值
  • @Field
    • 修饰范围: 用在成员变量、方法上
    • 作用: 用来将成员变量及其值映射为文档中一个key:value对。
    • 属性:( name , value )用来指定在文档中 key的名称,默认为成员变量名
  • @Transient
    • 修饰范围:用在成员变量、方法上
    • 作用:用来指定此成员变量不参与文档的序列化

创建实体

@Document("emp")  //对应emp集合中的一个文档

@Data

@AllArgsConstructor

@NoArgsConstructor

public class Employee {



    @Id   //映射文档中的_id

    private Integer id;

    @Field("username")

    private String name;

    @Field

    private int age;

    @Field

    private Double salary;

    @Field

    private Date birthday;

}

添加文档

insert方法返回值是新增的Document对象,里面包含了新增后_id的值。如果集合不存在会自动创建集合。通过Spring Data MongoDB还会给集合中多加一个_class的属性,存储新增时Document对应Java中类的全限定路径。这么做为了查询时能把Document转换为Java类型。

@Test

public void testInsert(){

    Employee employee = new Employee(1, "小明", 30,10000.00, new Date());

    

    //添加文档

    // sava:  _id存在时更新数据

    //mongoTemplate.save(employee);

    // insert: _id存在抛出异常   支持批量操作

    mongoTemplate.insert(employee);

    

    List<Employee> list = Arrays.asList(

            new Employee(2, "张三", 21,5000.00, new Date()),

            new Employee(3, "李四", 26,8000.00, new Date()),

            new Employee(4, "王五",22, 8000.00, new Date()),

            new Employee(5, "张龙",28, 6000.00, new Date()),

            new Employee(6, "赵虎",24, 7000.00, new Date()),

            new Employee(7, "赵六",28, 12000.00, new Date()));

    //插入多条数据

    mongoTemplate.insert(list,Employee.class);

} 
  • 插入重复数据时: insert报 DuplicateKeyException提示主键重复; save对已存在的数据进行更新。
  • 批处理操作时: insert可以一次性插入所有数据,效率较高;save需遍历所有数据,一次插入或更新,效率较低。

查询文档

Criteria是标准查询的接口,可以引用静态的Criteria.where的把多个条件组合在一起,就可以轻松地将多个方法标准和查询连接起来,方便我们操作查询语句。

@Test

public void testFind(){



    System.out.println("==========查询所有文档===========");

    //查询所有文档

    List<Employee> list = mongoTemplate.findAll(Employee.class);

    list.forEach(System.out::println);



    System.out.println("==========根据_id查询===========");

    //根据_id查询

    Employee e = mongoTemplate.findById(1, Employee.class);

    System.out.println(e);



    System.out.println("==========findOne返回第一个文档===========");

    //如果查询结果是多个,返回其中第一个文档对象

    Employee one = mongoTemplate.findOne(new Query(), Employee.class);

    System.out.println(one);



    System.out.println("==========条件查询===========");

    //new Query() 表示没有条件

    //查询薪资大于等于8000的员工

    //Query query = new Query(Criteria.where("salary").gte(8000));

    //查询薪资大于4000小于10000的员工

    //Query query = new Query(Criteria.where("salary").gt(4000).lt(10000));

    //正则查询(模糊查询)  java中正则不需要有//

    //Query query = new Query(Criteria.where("name").regex("张"));



    //and  or  多条件查询

    Criteria criteria = new Criteria();

    //and  查询年龄大于25&薪资大于8000的员工

    //criteria.andOperator(Criteria.where("age").gt(25),Criteria.where("salary").gt(8000));

    //or 查询姓名是张三或者薪资大于8000的员工

    criteria.orOperator(Criteria.where("name").is("张三"),Criteria.where("salary").gt(5000));

    Query query = new Query(criteria);



    //sort排序

    //query.with(Sort.by(Sort.Order.desc("salary")));





    //skip limit 分页  skip用于指定跳过记录数,limit则用于限定返回结果数量。

    query.with(Sort.by(Sort.Order.desc("salary")))

            .skip(0)  //指定跳过记录数

            .limit(4);  //每页显示记录数





    //查询结果

    List<Employee> employees = mongoTemplate.find(

            query, Employee.class);

    employees.forEach(System.out::println);

}
@Test

public void testFindByJson() {



    //使用json字符串方式查询

    //等值查询

    //String json = "{name:'张三'}";

    //多条件查询

    String json = "{$or:[{age:{$gt:25}},{salary:{$gte:8000}}]}";

    Query query = new BasicQuery(json);



    //查询结果

    List<Employee> employees = mongoTemplate.find(

            query, Employee.class);

    employees.forEach(System.out::println);

}

更新文档

在Mongodb中无论是使用客户端API还是使用Spring Data,更新返回结果一定是受行数影响。如果更新后的结果和更新前的结果是相同,返回0。

  • updateFirst() 只更新满足条件的第一条记录
  • updateMulti() 更新所有满足条件的记录
  • upsert() 没有符合条件的记录则插入数据
@Test

public void testUpdate(){

    //query设置查询条件

    Query query = new Query(Criteria.where("salary").gte(15000));

    System.out.println("==========更新前===========");

    List<Employee> employees = mongoTemplate.find(query, Employee.class);

    employees.forEach(System.out::println);



    Update update = new Update();

    //设置更新属性

    update.set("salary",13000);



    //updateFirst() 只更新满足条件的第一条记录

    //UpdateResult updateResult = mongoTemplate.updateFirst(query, update, Employee.class);

    //updateMulti() 更新所有满足条件的记录

    //UpdateResult updateResult = mongoTemplate.updateMulti(query, update, Employee.class);



    //upsert() 没有符合条件的记录则插入数据

    //update.setOnInsert("id",11);  //指定_id

    UpdateResult updateResult = mongoTemplate.upsert(query, update, Employee.class);



    //返回修改的记录数

    System.out.println(updateResult.getModifiedCount());





    System.out.println("==========更新后===========");

    employees = mongoTemplate.find(query, Employee.class);

    employees.forEach(System.out::println);

}

删除文档

@Test

public void testDelete(){

    //删除所有文档

    //mongoTemplate.remove(new Query(),Employee.class);

    //条件删除

    Query query = new Query(Criteria.where("salary").gte(10000));

    mongoTemplate.remove(query,Employee.class);

}

聚合操作

MongoTemplate提供了aggregate方法来实现对数据的聚合操作。

基于聚合管道mongodb提供的可操作的内容:

基于聚合操作Aggregation.group,mongodb提供可选的表达式

示例:以聚合管道示例2为例

返回人口超过1000万的州

db.zips.aggregate( [

   { $group: { _id: "$state", totalPop: { $sum: "$pop" } } },

   { $match: { totalPop: { $gt: 10*1000*1000 } } }

] )

java实现

@Test

public void test(){

    //$group

    GroupOperation groupOperation = Aggregation.group("state").sum("pop").as("totalPop");



    //$match

    MatchOperation matchOperation = Aggregation.match(

            Criteria.where("totalPop").gte(10*1000*1000));



    // 按顺序组合每一个聚合步骤

    TypedAggregation<Zips> typedAggregation = Aggregation.newAggregation(Zips.class,

             groupOperation, matchOperation);



    //执行聚合操作,如果不使用 Map,也可以使用自定义的实体类来接收数据

    AggregationResults<Map> aggregationResults = mongoTemplate.aggregate(typedAggregation, Map.class);

    // 取出最终结果

    List<Map> mappedResults = aggregationResults.getMappedResults();

    for(Map map:mappedResults){

        System.out.println(map);

    }



}

返回各州平均城市人口

db.zips.aggregate( [

   { $group: { _id: { state: "$state", city: "$city" }, cityPop: { $sum: "$pop" } } },

   { $group: { _id: "$_id.state", avgCityPop: { $avg: "$cityPop" } } },

   { $sort:{avgCityPop:-1}}

] )

java实现

@Test

public void test2(){

    //$group

    GroupOperation groupOperation = Aggregation.group("state","city").sum("pop").as("cityPop");

    //$group

    GroupOperation groupOperation2 = Aggregation.group("_id.state").avg("cityPop").as("avgCityPop");

    //$sort

    SortOperation sortOperation = Aggregation.sort(Sort.Direction.DESC,"avgCityPop");

    

    // 按顺序组合每一个聚合步骤

    TypedAggregation<Zips> typedAggregation = Aggregation.newAggregation(Zips.class,

            groupOperation, groupOperation2,sortOperation);



    //执行聚合操作,如果不使用 Map,也可以使用自定义的实体类来接收数据

    AggregationResults<Map> aggregationResults = mongoTemplate.aggregate(typedAggregation, Map.class);

    // 取出最终结果

    List<Map> mappedResults = aggregationResults.getMappedResults();

    for(Map map:mappedResults){

        System.out.println(map);

    }

}

按州返回最大和最小的城市

db.zips.aggregate( [

   { $group:

      {

        _id: { state: "$state", city: "$city" },

        pop: { $sum: "$pop" }

      }

   },

   { $sort: { pop: 1 } },

   { $group:

      {

        _id : "$_id.state",

        biggestCity:  { $last: "$_id.city" },

        biggestPop:   { $last: "$pop" },

        smallestCity: { $first: "$_id.city" },

        smallestPop:  { $first: "$pop" }

      }

   },

  { $project:

    { _id: 0,

      state: "$_id",

      biggestCity:  { name: "$biggestCity",  pop: "$biggestPop" },

      smallestCity: { name: "$smallestCity", pop: "$smallestPop" }

    }

  },

   { $sort: { state: 1 } }

] )

java实现

@Test

public void test3(){

    //$group

    GroupOperation groupOperation = Aggregation

            .group("state","city").sum("pop").as("pop");



    //$sort

    SortOperation sortOperation = Aggregation

            .sort(Sort.Direction.ASC,"pop");



    //$group

    GroupOperation groupOperation2 = Aggregation

            .group("_id.state")

            .last("_id.city").as("biggestCity")

            .last("pop").as("biggestPop")

            .first("_id.city").as("smallestCity")

            .first("pop").as("smallestPop");



    //$project

    ProjectionOperation projectionOperation = Aggregation

            .project("state","biggestCity","smallestCity")

            .and("_id").as("state")

            .andExpression(

                    "{ name: \"$biggestCity\",  pop: \"$biggestPop\" }")

            .as("biggestCity")

            .andExpression(

                    "{ name: \"$smallestCity\", pop: \"$smallestPop\" }"

            ).as("smallestCity")

            .andExclude("_id");



    //$sort

    SortOperation sortOperation2 = Aggregation

            .sort(Sort.Direction.ASC,"state");





    // 按顺序组合每一个聚合步骤

    TypedAggregation<Zips> typedAggregation = Aggregation.newAggregation(

            Zips.class, groupOperation, sortOperation, groupOperation2,

            projectionOperation,sortOperation2);



    //执行聚合操作,如果不使用 Map,也可以使用自定义的实体类来接收数据

    AggregationResults<Map> aggregationResults = mongoTemplate

            .aggregate(typedAggregation, Map.class);

    // 取出最终结果

    List<Map> mappedResults = aggregationResults.getMappedResults();

    for(Map map:mappedResults){

        System.out.println(map);

    }



}

小技巧:如何去掉_class属性

@Configuration

public class TulingMongoConfig {

    /**

     * 定制TypeMapper去掉_class属性

     * @param mongoDatabaseFactory

     * @param context

     * @param conversions

     * @return

     */

    @Bean

    MappingMongoConverter mappingMongoConverter(

            MongoDatabaseFactory mongoDatabaseFactory,

            MongoMappingContext context, MongoCustomConversions conversions){



        DbRefResolver dbRefResolver = new DefaultDbRefResolver(mongoDatabaseFactory);

        MappingMongoConverter mappingMongoConverter =

                new MappingMongoConverter(dbRefResolver,context);

        mappingMongoConverter.setCustomConversions(conversions);



        //构造DefaultMongoTypeMapper,将typeKey设置为空值

        mappingMongoConverter.setTypeMapper(new DefaultMongoTypeMapper(null));



        return mappingMongoConverter;

    }

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/930243.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

记录过程校准器:精准测量的未来驱动力与市场蓝海

在科技日新月异的今天&#xff0c;精确测量已成为工业制造、科学研究、环境监测等众多领域的核心要素。记录过程校准器&#xff0c;作为确保测量设备准确性和可靠性的关键工具&#xff0c;正扮演着越来越重要的角色。随着智能制造、物联网技术的快速发展&#xff0c;以及全球对…

【NLP 9、实践 ① 五维随机向量交叉熵多分类】

目录 五维向量交叉熵多分类 规律&#xff1a; 实现&#xff1a; 1.设计模型 2.生成数据集 3.模型测试 4.模型训练 5.对训练的模型进行验证 调用模型 你的平静&#xff0c;是你最强的力量 —— 24.12.6 五维向量交叉熵多分类 规律&#xff1a; x是一个五维(索引)向量&#xff…

STM32使用RCC(Reset Clock Contorl,复位时钟控制器)配置时钟以及时钟树

RCC主要作用 设置系统时钟SYSCLK&#xff08;System Clock&#xff09;频率&#xff1b;设置AHB、APB2、APB1以及各个外设分频因子&#xff0c;从而设置HCLK、PCLK2、PCLK1以及各个外设的时钟频率&#xff1b;控制AHB、APB2、APB1这三条总线时钟以及每个外设的时钟开启&#xf…

使用mtools搭建MongoDB复制集和分片集群

mtools介绍 mtools是一套基于Python实现的MongoDB工具集&#xff0c;其包括MongoDB日志分析、报表生成及简易的数据库安装等功能。它由MongoDB原生的工程师单独发起并做开源维护&#xff0c;目前已经有大量的使用者。 mtools所包含的一些常用组件如下&#xff1a; mlaunch支…

随记:win11 win+g 捕获 不能录视频 不用下载注册表修复工具

问题&#xff1a; 我解决的方法&#xff1a; win R 打开 再去 计算机\HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\GameDVR 这是我的问题&#xff0c;要是没有这个&#xff0c;可能是其他原因了 还有就是我还看到一个 上面那个不能解决的可以试试这个

算法刷题Day11: BM33 二叉树的镜像

点击题目链接 思路 转换为子问题&#xff1a;左右子树相反转。遍历手法&#xff1a;后序遍历 代码 class Solution:def Transverse(self,root: TreeNode):if root None:return rootnewleft self.Transverse(root.left)newright self.Transverse(root.right)# 对root节点…

【赵渝强老师】PostgreSQL的服务器日志文件

PostgreSQL数据库的物理存储结构主要是指硬盘上存储的文件&#xff0c;包括&#xff1a;数据文件、日志文件、参数文件、控制文件、WAL预写日志文件等等。下面重点讨论一下PostgreSQL的服务器日志文件。 视频讲解如下 【赵渝强老师】PostgreSQL的服务器日志文件 通过使用pg_ct…

【人工智能】深度解剖利用人工智能MSA模型

目录 情感分析的应用一、概述二、研究背景三、主要贡献四、模型结构和代码五、数据集介绍六、性能展示七、复现过程 情感分析的应用 近年来社交媒体的空前发展以及配备高质量摄像头的智能手机的出现&#xff0c;我们见证了多模态数据的爆炸性增长&#xff0c;如电影、短视频等…

行业标杆!鸿翼入选WAIC 2024《2024大模型典型示范应用案例集》

​7月5日&#xff0c;在2024世界人工智能大会“迈向 AGI&#xff1a;大模型焕新与产业赋能”论坛上&#xff0c;《2024大模型典型示范应用案例集》&#xff08;以下简称《案例集》&#xff09;重磅发布&#xff01;鸿翼AI项目成功入选&#xff0c;彰显了鸿翼在大模型应用领域的…

nodejs循环导出多个word表格文档

文章目录 nodejs循环导出多个word表格文档一、文档模板编辑二、安装依赖三、创建导出工具类exportWord.js四、调用五、效果图nodejs循环导出多个word表格文档 结果案例: 一、文档模板编辑 二、安装依赖 // 实现word下载的主要依赖 npm install docxtemplater pizzip --save/…

ABAP DIALOG屏幕编程1

一、DIALOG屏幕编程 DIALOG屏幕编程是SAP ABAP中用于创建用户交互界面的一种技术&#xff0c;主要用于开发事务性应用程序。它允许用户通过屏幕输入或操作数据&#xff0c;程序根据用户的操作执行逻辑处理。 1、DIALOG编程的主要组件 a、屏幕 (Screen) DIALOG程序的核心部分…

Shell免交互

Shell免交互 一. 变量配置1.1 在E0F外面的变量可以直接传入使用1.2 EOF的输入内容可以直接赋值给变量 二. expect语句2.1 转义符2.2 expect的语法2.3 格式2.4 脚本外传参2.5 嵌套 三. 访问其它主机 交互&#xff1a;当我们使用程序时&#xff0c;需要进入程序发出对应的指令&am…

清风数学建模学习笔记——Topsis法

数模评价类&#xff08;2&#xff09;——Topsis法 概述 Topsis:Technique for Order Preference by Similarity to Ideal Solution 也称优劣解距离法&#xff0c;该方法的基本思想是&#xff0c;通过计算每个备选方案与理想解和负理想解之间的距离&#xff0c;从而评估每个…

【认证法规】安全隔离变压器

文章目录 定义反激电源变压器 定义 安全隔离变压器&#xff08;safety isolating transformer&#xff09;&#xff0c;通过至少相当于双重绝缘或加强绝缘的绝缘使输入绕组与输出绕组在电气上分开的变压器。这种变压器是为以安全特低电压向配电电路、电器或其它设备供电而设计…

喆塔科技携手国家级创新中心,共建高性能集成电路数智化未来

集创新之力成数智之塔 近日&#xff0c;喆塔科技与国家集成电路创新中心携手共建“高性能集成电路数智化联合工程中心”并举行签约揭牌仪式。出席此次活动的领导嘉宾包含&#xff1a;上海市经济和信息化委员会、上海市集成电路行业协会、复旦大学微电子学院、国家集成电路创新中…

OpenCV-图像阈值

简单阈值法 此方法是直截了当的。如果像素值大于阈值&#xff0c;则会被赋为一个值&#xff08;可能为白色&#xff09;&#xff0c;否则会赋为另一个值&#xff08;可能为黑色&#xff09;。使用的函数是 cv.threshold。第一个参数是源图像&#xff0c;它应该是灰度图像。第二…

手游和应用出海资讯:怪物猎人AR手游累计总收入已超过2.5亿美元、SuperPlay获得迪士尼纸牌游戏发行许可

NetMarvel帮助游戏和应用广告主洞察全球市场、获取行业信息&#xff0c;以下为12月第一周资讯&#xff1a; ● 怪物猎人AR手游累计总收入已超过 2.5 亿美元 ● SuperPlay获得迪士尼纸牌游戏发行许可 ● 腾讯混元大模型上线文生视频能力 ● 网易天下事业部一拆三&#xff0c;蛋仔…

ARINC 标准全解析:航空电子领域多系列标准的核心内容、应用与重要意义

ARINC标准概述 ARINC标准是航空电子领域一系列重要的标准规范&#xff0c;由航空电子工程委员会&#xff08;AEEC&#xff09;编制&#xff0c;众多航空公司等参与支持。这些标准涵盖了从飞机设备安装、数据传输到航空电子设备功能等众多方面&#xff0c;确保航空电子系统的兼…

代码随想录Day35 本周小结动态规划,动态规划:01背包理论基础,动态规划:01背包理论基础(滚动数组),416. 分割等和子集。

1.本周小结动态规划 周一 动态规划&#xff1a;不同路径 (opens new window)中求从出发点到终点有几种路径&#xff0c;只能向下或者向右移动一步。 我们提供了三种方法&#xff0c;但重点讲解的还是动规&#xff0c;也是需要重点掌握的。 dp[i][j]定义 &#xff1a;表示从…

tomcat+jdbc报错怎么办?

1. 虽然mysql8.0以上的不用手动添加driver类&#xff0c;但是一旦加上driver类&#xff0c;就要手动添加了 不然会报找不到driver类的错误 2. java.lang.RuntimeException: java.sql.SQLException: No suitable driver found for jdbc:mysql://localhost:xXX?serverTimezoneU…