热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

8.SpringBoot集成MongoDB

目录环境准备引入依赖配置yml使用时注入MongoTemplate集合操作文档操作相关注解创建实体添加文档查询文档更新文档删除文档聚合操作match精准匹配match范围匹配gro

目录



  • 环境准备

    • 引入依赖

    • 配置yml

    • 使用时注入MongoTemplate



  • 集合操作

  • 文档操作

    • 相关注解

    • 创建实体

    • 添加文档

    • 查询文档

    • 更新文档

    • 删除文档



  • 聚合操作

    • match精准匹配

    • match范围匹配

    • group分组统计

    • limit查询N条记录(分页)

    • skip结果中跳过N条记录(分页)

    • count查询结果中总条数(分页)

    • project别名、显示|隐藏字段

    • match模糊查询

    • sort排序

    • lookup跨集合查询(join连表查询)

    • 排序去除数据100M大小限制

    • 应用定义的管道

    • aggregate执行查询



  • 事务


环境准备


引入依赖


org.springframework.boot
spring-boot-starter-data-mongodb


配置yml

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

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


使用时注入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类型。

Employee employee = new Employee(1, "小明", 30,10000.00, new Date());
//添加文档
// sava: _id存在时更新数据
//mongoTemplate.save(employee);
// insert: _id存在抛出异常 支持批量操作
mongoTemplate.insert(employee);
List 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);

查询文档

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

image-20220322184617497



  • 使用Query查询

System.out.println("==========查询所有文档===========");
//查询所有文档
List 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 employees = mongoTemplate.find(
query, Employee.class);
employees.forEach(System.out::println);


  • 使用JSON字符串查询

    //使用json字符串方式查询
    //等值查询
    //String json = "{name:'张三'}";
    //多条件查询
    String json = "{$or:[{age:{$gt:25}},{salary:{$gte:8000}}]}";
    Query query = new BasicQuery(json);
    //查询结果
    List employees = mongoTemplate.find(
    query, Employee.class);
    employees.forEach(System.out::println);



更新文档

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



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

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

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

//query设置查询条件
Query query = new Query(Criteria.where("salary").gte(15000));
System.out.println("==========更新前===========");
List 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);

删除文档

//删除所有文档
//mongoTemplate.remove(new Query(),Employee.class);
//条件删除
Query query = new Query(Criteria.where("salary").gte(10000));
mongoTemplate.remove(query,Employee.class);

聚合操作


match精准匹配

//精准匹配
MatchOperation salary1 = Aggregation.match(Criteria.where("salary").is(8000).and("age").lt(26));//精准匹配 salary=8000 and age<26

match范围匹配

//范围匹配
MatchOperation salary2 = Aggregation.match(Criteria.where("salary").gte(6000).lt(10000));//匹配salary>=6000 and salary <10000的数据

group分组统计

//分组统计
GroupOperation group = Aggregation.group("salary").sum("1").as("count");//根据salary分组,并且获得同样数值出现次数,以“count”字段输出

limit查询N条记录(分页)

//查询N条记录(分页)
LimitOperation limit = Aggregation.limit(1);//查询一条记录(分页:每页多少条数据)

skip结果中跳过N条记录(分页)

//结果中跳过N条记录(分页)
SkipOperation skip = Aggregation.skip(1l);//在结果中跳过第一条,从第二条开始显示(分页:读取多少页的数据=页数*每页条数)

count查询结果中总条数(分页)

//查询结果中总条数(分页)
CountOperation count = Aggregation.count().as("count");//查询结果中总条数(分页:总记录数)

根据上面查出的每页多少条数据、读取多少页的数据、总记录数,可实现分页


project别名、显示|隐藏字段

//别名、显示|隐藏字段
Field field1 = Fields.field("uname", "username");//设置别名,将字段名username映射为uname返回
Field field2 = Fields.field("uage", "age");//设置别名,将字段名age映射为uage返回
Fields fields = Fields.from(field1,field2);
ProjectionOperation projectAS1 = Aggregation.project(fields);//这时就会只查出uname,uage两列,这种方式默认不会查出_id字段
ProjectionOperation projectAS2 = Aggregation.project("username").andExclude("_id");//只查询username字段,并且把默认展示的_id去掉

match模糊查询

//模糊查询 匹配name字段中包含“小”的
MatchOperation regex = Aggregation.match(Criteria.where("name").regex("小"));

sort排序

SortOperation sort1 = Aggregation.sort(Sort.by(Sort.Order.desc("_id")));

lookup跨集合查询(join连表查询)

//join连表查询
LookupOperation lookup1 = Aggregation.lookup("emp", "userId", "_id", "user");//连表查询:order中有userid和emp中_id关联
LookupOperation lookup2 = Aggregation.lookup("item", "orderNo", "orderNo", "items");//连表查询:item中有orderNo和order中orderNo关联
MatchOperation match = Aggregation.match(Criteria.where("orderNo").is("orderNo"));//连表查询:查询条件只能是order中的字段
//注意:不支持像mysql中 a表关联b表,b表关联c表,c表关联d表,查找的主表必须要和子表有关联关系,我没找到lookup还有没有其他的方式
TypedAggregation typedAggregation =Aggregation.newAggregation(Order.class,sort1,lookup1,lookup2);//将管道封装进Aggregation,连表查询结果

排序去除数据100M大小限制

AggregationOptions aggregatiOnOptions= AggregationOptions.builder().allowDiskUse(true).build();//内存中排序有100M的限制,要执行大型排序,需要启用allowDiskUse选项将数据写入临时文件以进行排序
typedAggregation.withOptions(aggregationOptions);

应用定义的管道

根据业务,调整管道的顺序,放到Aggregation.newAggregation中

TypedAggregation typedAggregation =Aggregation.newAggregation(Order.class,sort1,lookup1,lookup2,。。。。。);

aggregate执行查询

//执行查询,类型可定义成对象
AggregationResults aggregate = mongoTemplate.aggregate(typedAggregation, Map.class);
List mappedResults = aggregate.getMappedResults();
mappedResults.forEach(System.out::println);

常用的差不多就这些,其他的命令同理,无非就是先通过Aggregation创建一个管道,然后根据业务,调整管道的顺序,放到Aggregation.newAggregation中


事务

用SpringBoot的MongoTemplate,有两种方式



  1. 注解

@Transactional


  1. 添加配置

@Configuration
public class TransactionConfig {
@Bean
MongoTransactionManager transactionManager(MongoDbFactory factory){
return new MongoTransactionManager(factory);
}
}

官方事务文档

1.所写技术都是我工作中用到的

2.所写技术都是自己从项目中提取的

3.所有配置搭建流程都经过2到3遍的测试

4.因都是工作中使用的技术,所以不确定是否有转载的,如果有,请及时通知



推荐阅读
  • 深入理解Java中的多态性概念及其应用
    多态是面向对象编程中的三大核心特性之一,与封装和继承共同构成了面向对象的基础。多态使得代码更加灵活和可扩展,封装和继承则为其提供了必要的支持。本文将深入探讨多态的概念及其在Java中的具体应用,帮助读者全面理解和掌握这一关键知识点。 ... [详细]
  • 本文介绍了如何将Spring属性占位符与Jersey的@Path和@ApplicationPath注解结合使用,以便在资源路径中动态解析属性值。 ... [详细]
  • 本文探讨了如何通过优化 DOM 操作来提升 JavaScript 的性能,包括使用 `createElement` 函数、动画元素、理解重绘事件及处理鼠标滚动事件等关键主题。 ... [详细]
  • 一、Advice执行顺序二、Advice在同一个Aspect中三、Advice在不同的Aspect中一、Advice执行顺序如果多个Advice和同一个JointPoint连接& ... [详细]
  • 从理想主义者的内心深处萌发的技术信仰,推动了云原生技术在全球范围内的快速发展。本文将带你深入了解阿里巴巴在开源领域的贡献与成就。 ... [详细]
  • MongoDB核心概念详解
    本文介绍了NoSQL数据库的概念及其应用场景,重点解析了MongoDB的基本特性、数据结构以及常用操作。MongoDB是一个高性能、高可用且易于扩展的文档数据库系统。 ... [详细]
  • 在CentOS 7环境中安装配置Redis及使用Redis Desktop Manager连接时的注意事项与技巧
    在 CentOS 7 环境中安装和配置 Redis 时,需要注意一些关键步骤和最佳实践。本文详细介绍了从安装 Redis 到配置其基本参数的全过程,并提供了使用 Redis Desktop Manager 连接 Redis 服务器的技巧和注意事项。此外,还探讨了如何优化性能和确保数据安全,帮助用户在生产环境中高效地管理和使用 Redis。 ... [详细]
  • ### 优化后的摘要本学习指南旨在帮助读者全面掌握 Bootstrap 前端框架的核心知识点与实战技巧。内容涵盖基础入门、核心功能和高级应用。第一章通过一个简单的“Hello World”示例,介绍 Bootstrap 的基本用法和快速上手方法。第二章深入探讨 Bootstrap 与 JSP 集成的细节,揭示两者结合的优势和应用场景。第三章则进一步讲解 Bootstrap 的高级特性,如响应式设计和组件定制,为开发者提供全方位的技术支持。 ... [详细]
  • V8不仅是一款著名的八缸发动机,广泛应用于道奇Charger、宾利Continental GT和BossHoss摩托车中。自2008年以来,作为Chromium项目的一部分,V8 JavaScript引擎在性能优化和技术创新方面取得了显著进展。该引擎通过先进的编译技术和高效的垃圾回收机制,显著提升了JavaScript的执行效率,为现代Web应用提供了强大的支持。持续的优化和创新使得V8在处理复杂计算和大规模数据时表现更加出色,成为众多开发者和企业的首选。 ... [详细]
  • Web开发框架概览:Java与JavaScript技术及框架综述
    Web开发涉及服务器端和客户端的协同工作。在服务器端,Java是一种优秀的编程语言,适用于构建各种功能模块,如通过Servlet实现特定服务。客户端则主要依赖HTML进行内容展示,同时借助JavaScript增强交互性和动态效果。此外,现代Web开发还广泛使用各种框架和库,如Spring Boot、React和Vue.js,以提高开发效率和应用性能。 ... [详细]
  • 如何撰写适应变化的高效代码:策略与实践
    编写高质量且适应变化的代码是每位程序员的追求。优质代码的关键在于其可维护性和可扩展性。本文将从面向对象编程的角度出发,探讨实现这一目标的具体策略与实践方法,帮助开发者提升代码效率和灵活性。 ... [详细]
  • 在Java Web服务开发中,Apache CXF 和 Axis2 是两个广泛使用的框架。CXF 由于其与 Spring 框架的无缝集成能力,以及更简便的部署方式,成为了许多开发者的首选。本文将详细介绍如何使用 CXF 框架进行 Web 服务的开发,包括环境搭建、服务发布和客户端调用等关键步骤,为开发者提供一个全面的实践指南。 ... [详细]
  • 小王详解:内部网络中最易理解的NAT原理剖析,挑战你的认知极限
    小王详解:内部网络中最易理解的NAT原理剖析,挑战你的认知极限 ... [详细]
  • 《Spring in Action 第4版:全面解析与实战指南》
    《Spring in Action 第4版:全面解析与实战指南》不仅详细介绍了Spring框架的核心优势,如简洁易测试、低耦合特性,还深入探讨了其轻量级和最小侵入性的设计原则。书中强调了声明式编程的优势,并通过基于约定的方法简化开发流程。此外,Spring的模板机制有效减少了重复代码,而依赖注入功能则由容器自动管理,确保了应用的灵活性和可维护性。 ... [详细]
  • 在使用SSH框架进行项目开发时,经常会遇到一些常见的问题。例如,在Spring配置文件中配置AOP事务声明后,进行单元测试时可能会出现“No Hibernate Session bound to thread”的错误。本文将详细探讨这一问题的原因,并提供有效的解决方案,帮助开发者顺利解决此类问题。 ... [详细]
author-avatar
张程Louis
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有