热门标签 | 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.因都是工作中使用的技术,所以不确定是否有转载的,如果有,请及时通知



推荐阅读
  • 使用 Docker 部署 MongoDB 并通过 IntelliJ IDEA 远程访问
    本文详细介绍了如何使用 Docker 部署 MongoDB,并通过 IntelliJ IDEA 实现远程连接的方法。包括 MongoDB 的基本配置、用户管理以及如何在 IDE 中配置连接。 ... [详细]
  • 利用GitHub热门资源,成功斩获阿里、京东、腾讯三巨头Offer
    Spring框架作为Java生态系统中的重要组成部分,因其强大的功能和灵活的扩展性,被广泛应用于各种规模的企业级应用开发中。本文将通过一份在GitHub上获得极高评价的Spring全家桶文档,探讨如何掌握Spring框架及其相关技术,助力职业发展。 ... [详细]
  • 在 Android 开发中,通过 Intent 启动 Activity 或 Service 时,可以使用 putExtra 方法传递数据。接收方可以通过 getIntent().getExtras() 获取这些数据。本文将介绍如何使用 RoboGuice 框架简化这一过程,特别是 @InjectExtra 注解的使用。 ... [详细]
  • 配置PHPStudy环境并使用DVWA进行Web安全测试
    本文详细介绍了如何在PHPStudy环境下配置DVWA( Damn Vulnerable Web Application ),并利用该平台进行SQL注入和XSS攻击的练习。通过此过程,读者可以熟悉常见的Web漏洞及其利用方法。 ... [详细]
  • 深入解析Spring Boot自动配置机制
    本文旨在深入探讨Spring Boot的自动配置机制,特别是如何利用配置文件进行有效的设置。通过实例分析,如Http编码自动配置,我们将揭示配置项的具体作用及其背后的实现逻辑。 ... [详细]
  • EasyMock实战指南
    本文介绍了如何使用EasyMock进行单元测试,特别是当测试对象的合作者依赖于外部资源或尚未实现时。通过具体的示例,展示了EasyMock在模拟对象行为方面的强大功能。 ... [详细]
  • 字节跳动夏季招聘面试经验分享
    本文详细记录了字节跳动夏季招聘的面试经历,涵盖了一、二、三轮面试的技术问题及项目讨论,旨在为准备类似面试的求职者提供参考。 ... [详细]
  • 掌握Spring MVC中自定义类型转换与格式化的技巧
    近期,在开发一款小程序的过程中遇到了几个Spring MVC接口需要传递时间参数的问题。本文将详细介绍如何利用Java 8 Time API在Spring MVC中实现时间参数的自定义类型转换和格式化。 ... [详细]
  • Spring Cloud因其强大的功能和灵活性,被誉为开发分布式系统的‘一站式’解决方案。它不仅简化了分布式系统中的常见模式实现,还被广泛应用于企业级生产环境中。本书内容详实,覆盖了从微服务基础到Spring Cloud的高级应用,适合各层次的开发者。 ... [详细]
  • 尽管PHP是一种强大且灵活的Web开发语言,但开发者在使用过程中常会陷入一些典型的陷阱。本文旨在列出PHP开发中最为常见的10种错误,并提供相应的预防建议。 ... [详细]
  • 利用 Jest 和 Supertest 实现接口测试的全面指南
    本文深入探讨了如何使用 Jest 和 Supertest 进行接口测试,通过实际案例详细解析了测试环境的搭建、测试用例的编写以及异步测试的处理方法。 ... [详细]
  • 本文探讨了在 Spring Boot 应用程序中使用 MongoDB 进行复杂文档查询的方法,特别是如何通过实体类映射来处理包含嵌套对象和列表的数据结构。 ... [详细]
  • 近期参与了一个旨在提高在线平台大规模查询响应速度的项目,预计处理的数据量为2-3亿条,数据库并发量约为每秒1500次,未来可能增至3000次。通过对比Redis和MongoDB,最终选择了MongoDB,因其具备优秀的横向扩展性和GridFS支持下的Map/Reduce功能。 ... [详细]
  • 本文详细介绍了如何构建MongoDB的ReplSet复制集群,包括环境准备、配置文件设置以及初始化复制集群的具体步骤。 ... [详细]
  • 开发笔记:Mongodb副本集集群搭建 ... [详细]
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社区 版权所有